diff --git a/.clang-tidy b/.clang-tidy index 44d9133..982be9b2 100644 --- a/.clang-tidy +++ b/.clang-tidy
@@ -11,6 +11,7 @@ google-explicit-constructor, google-readability-casting, modernize-avoid-bind, + modernize-concat-nested-namespaces, modernize-loop-convert, modernize-make-shared, modernize-make-unique,
diff --git a/.gn b/.gn index fdde7824..ac2a30b5 100644 --- a/.gn +++ b/.gn
@@ -70,8 +70,6 @@ # their includes checked for proper dependencies when you run either # "gn check" or "gn gen --check". no_check_targets = [ - "//extensions:chrome_extensions_browsertests", # 26 errors - "//headless:headless_browsertests", # 47 errors "//headless:headless_browsertests__exec", "//headless:headless_example", # 3 errors
diff --git a/BUILD.gn b/BUILD.gn index 57432ddd..023d3da 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1201,7 +1201,7 @@ } else { _common_web_test_args += [ "--release" ] if (dcheck_always_on) { - _common_web_test_args += [ "--time-out-ms=12000" ] + _common_web_test_args += [ "--timeout-ms=12000" ] } } @@ -1403,7 +1403,7 @@ root_build_dir) + ")" ] + _common_web_test_args - [ _common_web_test_args[0] ] if (is_asan) { - args += [ "--time-out-ms=30000" ] + args += [ "--timeout-ms=30000" ] } args += [ "--webgpu-cts-expectations",
diff --git a/DEPS b/DEPS index 73f2324..85ac3b51 100644 --- a/DEPS +++ b/DEPS
@@ -213,7 +213,7 @@ # luci-go CIPD package version. # Make sure the revision is uploaded by infra-packagers builder. # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console - 'luci_go': 'git_revision:89429843eb2dedb599a6c7c7754343b97d95943d', + 'luci_go': 'git_revision:d1e877e2b3e5a05a5cd34c4a340fedba14a16c2b', # This can be overridden, e.g. with custom_vars, to build clang from HEAD # instead of downloading the prebuilt pinned revision. @@ -245,23 +245,23 @@ # 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': 'd7771857e9e24b3b8e67e25215d62ec78ff344c3', + 'skia_revision': '72412a86725a391f0d41d7a49ef5669b3ea81c28', # 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': '1e8198a9daae6bf35ec416970b1e6cae3d335064', + 'v8_revision': '09e91f429ec411bb79d9748e90baeb979b2ead37', # 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': 'b6399ac94f468ed94433fdb733d43d1fa5a08608', + 'angle_revision': 'caf6433addcbae9632ed994a793d75fcdf522eca', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'c73969d73ff90a54487df765f0fdb12d3583b344', + 'swiftshader_revision': 'b57a3aaee927a7412dffffac064d833e1d87dc7d', # 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': '9606a2fc6ff09357cf7e82b078c2efba6a483cca', + 'pdfium_revision': '07819c470bb1e243e894297516c22147515cda8c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -288,11 +288,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'a90562b0e045950f6884105bfa6e560dbce9d319', + 'nacl_revision': '881b4022a59751db8ccce6ea69cee4198b18454f', # 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': '2b672e7210a6e989aca4787fb81f4b2542bad9c1', + 'freetype_revision': 'afb4ca0151959a8bedfb39a9a9140504168be7ea', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -312,7 +312,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '5d00ad2e9ae4b758e418384961560cb6e767cec3', + 'catapult_revision': 'aa0e8d05643953c9f7f84bdd7ee3ca4ee3772d41', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -320,7 +320,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': '378ed186f5e4bbafbaacf74f6b7564c9ff8f82cf', + 'devtools_frontend_revision': 'ff9f0daa37f718e0e11c2ba9ef7bea6e0347c5b3', # 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. @@ -360,11 +360,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'b4a4d3fd59a0006330c9b86b81644e0ee7e4d5f7', + 'dawn_revision': 'c40f04b85bb5ecfe6dbea51a61037802d88af6af', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'ed970f7c38381309e9306982efa8dcfac1201269', + 'quiche_revision': 'cb6ab3eb3fdf36c5db3a4a845f4af1c7c5d68b7e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -408,7 +408,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libunwind_revision': '6a10e3e97c45505615d35dea94f588b5f86045dc', + 'libunwind_revision': '4bf418ebaf3ea28ffa0bbdc3361e667ac0bff9a7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -427,7 +427,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:281ba2c91861b10fec7407c4b6172ec3d4661243', + 'gn_version': 'git_revision:387b368dfe63fec317f8e609d90c634807f2764e', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -617,7 +617,7 @@ Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248', 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '08d439231d43f9b1dfc72e701c17c4840652e356', + 'url': Var('chromium_git') + '/website.git' + '@' + '052453fa5e07abc471ba2abe48cae3bffcf47eaa', }, 'src/ios/third_party/earl_grey2/src': { @@ -722,7 +722,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'HZFIzEg73fyXn3PT8ANFZiCjpNXG3wNza3GZNAv_K0YC', + 'version': 'xX3VPCe9E9oTxNq-0hh3eMKuQGDqiZIaRsEZNUqteUYC', }, ], 'dep_type': 'cipd', @@ -733,7 +733,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'nj9qYCdjBO4VQ2EgkpYLAKSW07xpPXqvINZUVsDPHaIC', + 'version': 'vSnyGD-lDffy5fyC4ygQkpau2epL-9TGMnjIunp0W7UC', }, ], 'dep_type': 'cipd', @@ -744,7 +744,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'JzjZI3xnSTQWDAjJXDRxfg0V7wED1RRwquKmzyU_FQgC', + 'version': 'Dlcmpgi1yMknK9l9x-2j-f82qa-zbeiUD0K-ZKf7qKIC', }, ], 'dep_type': 'cipd', @@ -805,7 +805,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'rHl7WLfujPiSrBBRroGr68FcsXWIPHzpsXUuSYZ6r-kC', + 'version': 'SBd1_afac7GmjsqtDzNI7TUwKr4KVbHuX3oqnduAW9EC', }, ], 'condition': 'checkout_android', @@ -970,7 +970,7 @@ }, 'src/third_party/breakpad/breakpad': - Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '3846f6d297339c17663d7a797ba481b3411f13ad', + Var('chromium_git') + '/breakpad/breakpad.git' + '@' + 'bbf740148d4fbd77b6ac103c22d83703f9488da0', 'src/third_party/byte_buddy': { 'packages': [ @@ -1024,7 +1024,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' + '@' + 'f53daf6c421687e65f0535154806cd74e55678a6', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '81093092ece1b06a493257f50a23ec429c01529a', 'condition': 'checkout_chromeos', }, @@ -1039,12 +1039,12 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '725259a4bd767e8535374fc391849f2bc4a79e32', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'bf9d8619a4a132b59de7d9043ffe415d6df8917f', 'condition': 'checkout_linux', }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'aae6725ff0466e1f12555bf21a87b070b068ed27', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '44dda9648cce2a12c67aa96a498adfb3245d38e7', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1524,7 +1524,7 @@ }, 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'd826d9fcb68c62996c1b7c0a45d604e22d814952', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'cb5bbb250e07e7621a5cfe3818f8141e33967f0e', 'src/third_party/r8': { 'packages': [ @@ -1588,7 +1588,7 @@ }, 'src/third_party/tflite/src': - Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'dd57f5328f37a81197b0dadd052e05c9d9461b16', + Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'a4289fcb7a4fc982886aa2d11c7b0d87e9815ed7', 'src/third_party/turbine': { 'packages': [ @@ -1609,7 +1609,7 @@ 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '62d7d0c928c9a040dce96aa2f16c00e7e67d59cb', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@760dcbc9cc523a8d3028758282a3b1b6483ba41d', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@a44aaa9661c061d021dbf498423ccf6b746e02ce', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '5e49f57a6e71a026a54eb42e366de09a4142d24e', @@ -1648,7 +1648,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'fca7b339442bd70c5dc49bb33ee7f9466b560a97', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '9abd74dc1e453a2b0bfd5521b25704db4423ff1e', + Var('webrtc_git') + '/src.git' + '@' + 'd908d74fac46c58b80c1120b982d3f1b407292f3', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1675,7 +1675,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': '2z57AgaznK-BN6rC-A4ZVj85ldJOjFFCMFQ_LYWeUv4C', + 'version': 'YNf7R76UZBvuCmgAKDzb1F43jfA8FkFy9DCW6B98MHEC', }, ], 'dep_type': 'cipd', @@ -1685,7 +1685,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'SSrgf0lBIrCHRZ2acvLwXzzm4KTPzRg17PGIiqsMxBQC', + 'version': '0Z6Y_DY-axS2RajDae9CHJrDn1a4CTif2VkT4CR5jOMC', }, ], 'dep_type': 'cipd', @@ -1708,7 +1708,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': 'zLP4FDegN-yg3uvzWUdf4zNRVHDwHd0VLm86FkZCP_MC', + 'version': 'x0lVRcTpz47HUZXm2WnVv16tuAKSZ-QUF9A1T1j2RykC', }, ], 'dep_type': 'cipd', @@ -1719,7 +1719,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-arm64', - 'version': 'FOo-HR3_OFTL0pn9TIm0H93TmtXgEfjSazYb3xAtx68C', + 'version': 'Cbv4TR0stWg2pA84PBfgi-N9jV07KWhEcAsg8ZX8ZkYC', }, ], 'dep_type': 'cipd', @@ -1730,7 +1730,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@933ce812bd6c9e391d32095bad0cc6cc019c8bcb', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0c5fa389c6ce3962fdfb5a8ffad28ce83542ab9a', 'condition': 'checkout_src_internal', }, @@ -1760,7 +1760,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'u_Fv6v2Geu2wAIpdFw_5DMsaNf0h8KMx9H3CLGVt3ZcC', + 'version': 'ALKqv_hdzRbzx6zAqVrRyRoC7_l0PzxpaXcMy8FY12gC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1771,7 +1771,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'sXs5SWPhJ7kAbHETKs4m-ZHITYSXiJjF4lMiFbU1q4IC', + 'version': 'AbBYfsC4757NystoBycRj-9JENE23kFNcGpJfUoBw5IC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1782,7 +1782,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'qki7FFASojKNGXO3gBN1xtUp8ev25Jo80vs1jWzwSm4C', + 'version': 'mb7CztOm9eOO_zhv70UJPRSZC3CDEPA7d7CUnS6ifGkC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 623876d..3eb2598 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -663,6 +663,8 @@ '^chromecast/cast_core/runtime/browser', # Fuchsia provides C++ libraries that use std::shared_ptr<>. '.*fuchsia.*test\.(cc|h)', + # Needed for clang plugin tests + '^tools/clang/plugins/tests/', _THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), ( @@ -5418,7 +5420,7 @@ 'RenderViewDeleted', 'RenderViewHostChanged', 'DocumentAvailableInMainFrame', - 'DocumentOnLoadCompletedInMainFrame', + 'DocumentOnLoadCompletedInPrimaryMainFrame', 'DOMContentLoaded', 'DidFinishLoad', ]
diff --git a/WATCHLISTS b/WATCHLISTS index b87edd37..e0abbff8 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1128,6 +1128,7 @@ 'ash/system/holding_space|'\ 'chrome/browser/lacros/.*holding_space.*|'\ 'chrome/browser/ui/ash/holding_space|'\ + 'chrome/browser/ui/ash/thumbnail_loader.*|'\ 'chromeos/crosapi/mojom/.*holding_space.*|'\ 'tools/metrics/histograms/metadata/holding_space' },
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 224a038f7..77213b1 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -869,6 +869,7 @@ void AwContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { WebContents* web_contents = content::WebContents::FromRenderFrameHost( content::RenderFrameHost::FromID(render_process_id, render_frame_id));
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index dbbaf193..207f90e 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -193,6 +193,7 @@ void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) override; bool ShouldAllowNoLongerUsedProcessToExit() override; bool ShouldIsolateErrorPage(bool in_main_frame) override;
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index d824169..3be25ede 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -852,12 +852,12 @@ env, obj, ConvertUTF8ToJavaString(env, url), precomposed); } -void AwContents::PostInvalidate() { +void AwContents::PostInvalidate(bool inside_vsync) { DCHECK_CURRENTLY_ON(BrowserThread::UI); JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj) - Java_AwContents_postInvalidateOnAnimation(env, obj); + Java_AwContents_postInvalidate(env, obj, inside_vsync); } void AwContents::OnNewPicture() { @@ -1197,7 +1197,8 @@ } void AwContents::DidOverscroll(const gfx::Vector2d& overscroll_delta, - const gfx::Vector2dF& overscroll_velocity) { + const gfx::Vector2dF& overscroll_velocity, + bool inside_vsync) { DCHECK_CURRENTLY_ON(BrowserThread::UI); JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); @@ -1205,7 +1206,7 @@ return; Java_AwContents_didOverscroll(env, obj, overscroll_delta.x(), overscroll_delta.y(), overscroll_velocity.x(), - overscroll_velocity.y()); + overscroll_velocity.y(), inside_vsync); } ui::TouchHandleDrawable* AwContents::CreateDrawable() {
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h index 7e19b9e..d10b619e 100644 --- a/android_webview/browser/aw_contents.h +++ b/android_webview/browser/aw_contents.h
@@ -312,7 +312,7 @@ void OnWebLayoutContentsSizeChanged(const gfx::Size& contents_size) override; // BrowserViewRendererClient implementation. - void PostInvalidate() override; + void PostInvalidate(bool inside_vsync) override; void OnNewPicture() override; gfx::Point GetLocationOnScreen() override; void OnViewTreeForceDarkStateChanged( @@ -327,7 +327,8 @@ float min_page_scale_factor, float max_page_scale_factor) override; void DidOverscroll(const gfx::Vector2d& overscroll_delta, - const gfx::Vector2dF& overscroll_velocity) override; + const gfx::Vector2dF& overscroll_velocity, + bool inside_vsync) override; ui::TouchHandleDrawable* CreateDrawable() override; void ClearCache(JNIEnv* env,
diff --git a/android_webview/browser/gfx/begin_frame_source_webview.h b/android_webview/browser/gfx/begin_frame_source_webview.h index dd77699..9abd8f7 100644 --- a/android_webview/browser/gfx/begin_frame_source_webview.h +++ b/android_webview/browser/gfx/begin_frame_source_webview.h
@@ -31,6 +31,7 @@ // Sets parent of this BeginFrameSource void SetParentSource(BeginFrameSourceWebView* parent); + bool inside_begin_frame() { return inside_begin_frame_; } // Schedules BeginFrame completion callback on root begin frame source. virtual void AddBeginFrameCompletionCallback(base::OnceClosure callback); @@ -39,7 +40,6 @@ void ObserveBeginFrameSource(viz::BeginFrameSource* begin_frame_source); virtual void AfterBeginFrame() {} - bool inside_begin_frame() { return inside_begin_frame_; } private: class BeginFrameObserver;
diff --git a/android_webview/browser/gfx/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc index 5b58e972..5302d1c 100644 --- a/android_webview/browser/gfx/browser_view_renderer.cc +++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -856,7 +856,8 @@ gfx::Vector2dF fling_velocity_pixels = gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale); - client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels); + client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels, + begin_frame_source_->inside_begin_frame()); } ui::TouchHandleDrawable* BrowserViewRenderer::CreateDrawable() { @@ -904,7 +905,8 @@ return; did_invalidate_since_last_draw_ = true; - client_->PostInvalidate(); + client_->PostInvalidate( + RootBeginFrameSourceWebView::GetInstance()->inside_begin_frame()); } bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas, bool software_canvas) {
diff --git a/android_webview/browser/gfx/browser_view_renderer_client.h b/android_webview/browser/gfx/browser_view_renderer_client.h index 0e5a564..d72eb477 100644 --- a/android_webview/browser/gfx/browser_view_renderer_client.h +++ b/android_webview/browser/gfx/browser_view_renderer_client.h
@@ -26,7 +26,7 @@ // Called to trigger view invalidations. // This calls postInvalidateOnAnimation if outside of a vsync, otherwise it // calls invalidate. - virtual void PostInvalidate() = 0; + virtual void PostInvalidate(bool inside_vsync) = 0; // Called to get view's absolute location on the screen. virtual gfx::Point GetLocationOnScreen() = 0; @@ -47,7 +47,8 @@ // Handle overscroll. virtual void DidOverscroll(const gfx::Vector2d& overscroll_delta, - const gfx::Vector2dF& overscroll_velocity) = 0; + const gfx::Vector2dF& overscroll_velocity, + bool inside_vsync) = 0; // Create a text selection handle on demand. virtual ui::TouchHandleDrawable* CreateDrawable() = 0;
diff --git a/android_webview/browser/gfx/browser_view_renderer_unittest.cc b/android_webview/browser/gfx/browser_view_renderer_unittest.cc index b046c857..6598dd4d 100644 --- a/android_webview/browser/gfx/browser_view_renderer_unittest.cc +++ b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
@@ -194,9 +194,10 @@ bool WillDrawOnRT(HardwareRendererDrawParams* params) override { if (draw_gl_count_on_rt_ == 1) { draw_gl_count_on_rt_++; - ui_task_runner_->PostTask(FROM_HERE, - base::BindOnce(&RenderingTest::PostInvalidate, - base::Unretained(this))); + ui_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RenderingTest::PostInvalidate, base::Unretained(this), + /*inside_vsync=*/false)); return false; }
diff --git a/android_webview/browser/gfx/test/rendering_test.cc b/android_webview/browser/gfx/test/rendering_test.cc index fd4e581..140312d 100644 --- a/android_webview/browser/gfx/test/rendering_test.cc +++ b/android_webview/browser/gfx/test/rendering_test.cc
@@ -156,7 +156,7 @@ void RenderingTest::OnNewPicture() {} -void RenderingTest::PostInvalidate() { +void RenderingTest::PostInvalidate(bool inside_vsync) { if (window_) window_->PostInvalidate(); }
diff --git a/android_webview/browser/gfx/test/rendering_test.h b/android_webview/browser/gfx/test/rendering_test.h index 916ee0a..90158873 100644 --- a/android_webview/browser/gfx/test/rendering_test.h +++ b/android_webview/browser/gfx/test/rendering_test.h
@@ -49,7 +49,7 @@ // BrowserViewRendererClient overrides. void OnNewPicture() override; - void PostInvalidate() override; + void PostInvalidate(bool inside_vsync) override; gfx::Point GetLocationOnScreen() override; void ScrollContainerViewTo(const gfx::Point& new_value) override {} void UpdateScrollState(const gfx::Point& max_scroll_offset, @@ -58,7 +58,8 @@ float min_page_scale_factor, float max_page_scale_factor) override {} void DidOverscroll(const gfx::Vector2d& overscroll_delta, - const gfx::Vector2dF& overscroll_velocity) override {} + const gfx::Vector2dF& overscroll_velocity, + bool inside_vsync) override {} ui::TouchHandleDrawable* CreateDrawable() override; // WindowHooks overrides.
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc index c9d5225..ffaafc8 100644 --- a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc +++ b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
@@ -82,6 +82,10 @@ safe_browsing::TriggerType::SECURITY_INTERSTITIAL, web_contents, unsafe_resources[0], url_loader_factory, /*history_service*/ nullptr, + // TODO(crbug.com/1284979) If features get added that can alter + // user population values in android_webview, we should consider + // threading the user population through for client reports + /*get_user_population_callback*/ base::NullCallback(), /*referrer_chain_provider*/ nullptr, sb_error_ui()->get_error_display_options()); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 413f9f9..f71fe6eb 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -110,7 +110,6 @@ import org.chromium.device.gamepad.GamepadList; import org.chromium.net.NetworkChangeNotifier; import org.chromium.network.mojom.ReferrerPolicy; -import org.chromium.ui.VSyncMonitor; import org.chromium.ui.base.ActivityWindowAndroid; import org.chromium.ui.base.Clipboard; import org.chromium.ui.base.IntentRequestTracker; @@ -770,7 +769,7 @@ @Override public void invalidate() { - postInvalidateOnAnimation(); + mContainerView.postInvalidateOnAnimation(); } @Override @@ -1554,7 +1553,7 @@ if (!wasPaused) onResume(); if (wasAttached) { onAttachedToWindow(); - postInvalidateOnAnimation(); + mContainerView.postInvalidateOnAnimation(); } onSizeChanged(mContainerView.getWidth(), mContainerView.getHeight(), 0, 0); if (wasWindowVisible) setWindowVisibilityInternal(true); @@ -3634,11 +3633,11 @@ } @CalledByNative - private void postInvalidateOnAnimation() { - if (!VSyncMonitor.isInsideVSync()) { - mContainerView.postInvalidateOnAnimation(); - } else { + private void postInvalidate(boolean insideVSync) { + if (insideVSync) { mContainerView.invalidate(); + } else { + mContainerView.postInvalidateOnAnimation(); } } @@ -3685,7 +3684,8 @@ } @CalledByNative - private void didOverscroll(int deltaX, int deltaY, float velocityX, float velocityY) { + private void didOverscroll( + int deltaX, int deltaY, float velocityX, float velocityY, boolean insideVSync) { mScrollOffsetManager.overScrollBy(deltaX, deltaY); if (mOverScrollGlow == null) return; @@ -3702,7 +3702,7 @@ (float) Math.hypot(velocityX, velocityY)); if (mOverScrollGlow.isAnimating()) { - postInvalidateOnAnimation(); + postInvalidate(insideVSync); } } @@ -3986,7 +3986,7 @@ if (mOverScrollGlow != null && mOverScrollGlow.drawEdgeGlows(canvas, mScrollOffsetManager.computeMaximumHorizontalScrollOffset(), mScrollOffsetManager.computeMaximumVerticalScrollOffset())) { - postInvalidateOnAnimation(); + mContainerView.postInvalidateOnAnimation(); } if (mInvalidateRootViewOnNextDraw) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java index e9902b5..8f2f196b 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -51,7 +51,6 @@ import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; -import org.chromium.components.viz.common.VizFeatures; import org.chromium.content_public.browser.test.util.RenderProcessHostUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TouchCommon; @@ -1031,16 +1030,6 @@ @Test @Feature({"AndroidWebView"}) @MediumTest - @CommandLineFlags. - Add({"enable-features=" + VizFeatures.USE_SKIA_RENDERER, "disable-oop-rasterization"}) - public void testHardwareRenderingSmokeTestSkiaRenderer() throws Throwable { - mActivityTestRule.startBrowserProcess(); - doHardwareRenderingSmokeTest(); - } - - @Test - @Feature({"AndroidWebView"}) - @MediumTest @MinAndroidSdkLevel(Build.VERSION_CODES.P) public void testHardwareRenderingSmokeTestVulkanWhereSupported() throws Throwable { // Manually curated list.
diff --git a/android_webview/nonembedded/component_updater/registration.cc b/android_webview/nonembedded/component_updater/registration.cc index 8ed879c..ecfbc0b 100644 --- a/android_webview/nonembedded/component_updater/registration.cc +++ b/android_webview/nonembedded/component_updater/registration.cc
@@ -13,25 +13,29 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/command_line.h" +#include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" +#include "components/component_updater/component_installer.h" #include "components/component_updater/component_updater_service.h" +#include "components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h" #include "components/component_updater/installer_policies/origin_trials_component_installer.h" #include "components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h" +#include "components/update_client/update_client.h" namespace android_webview { namespace { // Update when changing the components WebView registers. -constexpr int kNumWebViewComponents = 3; +constexpr int kNumWebViewComponents = 4; void RegisterComponentInstallerPolicyShim( - std::unique_ptr<component_updater::ComponentInstallerPolicy> policy_, + std::unique_ptr<component_updater::ComponentInstallerPolicy> policy, base::OnceCallback<bool(const component_updater::ComponentRegistration&)> register_callback, base::OnceClosure registration_finished) { base::MakeRefCounted<component_updater::ComponentInstaller>( - std::make_unique<AwComponentInstallerPolicyShim>(std::move(policy_))) + std::make_unique<AwComponentInstallerPolicyShim>(std::move(policy))) ->Register(std::move(register_callback), std::move(registration_finished)); } @@ -46,8 +50,9 @@ bool package_names_allowlist_enabled = !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kWebViewDisableAppsPackageNamesAllowlistComponent); - int num_webview_components = - package_names_allowlist_enabled ? kNumWebViewComponents : 2; + int num_webview_components = package_names_allowlist_enabled + ? kNumWebViewComponents + : kNumWebViewComponents - 1; base::RepeatingClosure barrier_closure = base::BarrierClosure( num_webview_components, base::BindOnce(std::move(on_finished))); @@ -64,6 +69,23 @@ [](const std::string& raw_commitments) { NOTREACHED(); })), register_callback, barrier_closure); + RegisterComponentInstallerPolicyShim( + std::make_unique< + component_updater::ClientSidePhishingComponentInstallerPolicy>( + // Files shouldn't be parsed or loaded in this process, thus + // ClientSidePhishingComponentInstallerPolicy::ComponentReady will + // never be called in this process and the `ReadFilesCallback` + // shouldn't be called either. + base::BindRepeating( + [](const base::FilePath& /* install_path */) { NOTREACHED(); }), + base::BindRepeating([]() { + // Always download the "default" binary, because variations aren't + // initialized in this process and values can't be dynamically + // changed using finch. See https://crbug.com/1115700#c36. + return update_client::InstallerAttributes{{"tag", "default"}}; + })), + register_callback, barrier_closure); + if (package_names_allowlist_enabled) { RegisterWebViewAppsPackageNamesAllowlistComponent(register_callback, barrier_closure);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index cdd3ff9..e7dbe7a 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2193,6 +2193,7 @@ "//ash/assistant/ui", "//ash/quick_pair/feature_status_tracker", "//ash/quick_pair/pairing", + "//ash/quick_pair/repository", "//ash/quick_pair/ui", ]
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index 9e7b726..537dca9 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -134,7 +134,6 @@ // Toast id and duration for Assistant shortcuts. constexpr char kAssistantErrorToastId[] = "assistant_error"; -constexpr int kToastDurationMs = 2500; constexpr char kVirtualDesksToastId[] = "virtual_desks_toast"; @@ -219,7 +218,7 @@ } void ShowToast(std::string id, const std::u16string& text) { - ToastData toast(id, text, kToastDurationMs, absl::nullopt, + ToastData toast(id, text, ToastData::kDefaultToastDurationMs, /*visible_on_lock_screen=*/true); Shell::Get()->toast_manager()->Show(toast); }
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc index 91a80a4c..498c614 100644 --- a/ash/accelerators/debug_commands.cc +++ b/ash/accelerators/debug_commands.cc
@@ -178,8 +178,9 @@ HandlePrintWindowHierarchy(); break; case DEBUG_SHOW_TOAST: - Shell::Get()->toast_manager()->Show( - ToastData("id", u"Toast", 5000 /* duration_ms */, u"Dismiss")); + Shell::Get()->toast_manager()->Show(ToastData( + /*id=*/"id", /*text=*/u"Toast", ToastData::kDefaultToastDurationMs, + /*visible_on_lock_screen=*/false, /*dismiss_text=*/u"Dismiss")); break; case DEBUG_TOGGLE_TOUCH_PAD: HandleToggleTouchpad();
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index ccacd4b..643e918 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -691,26 +691,6 @@ kMaxValue = kNone, }; -void MigrateSwitchAccessKeyCodePref(PrefService* prefs, - const std::string& old_pref, - const std::string& new_pref) { - if (!prefs->HasPrefPath(old_pref)) - return; - - base::ListValue devices; - devices.Append(ash::kSwitchAccessInternalDevice); - devices.Append(ash::kSwitchAccessUsbDevice); - devices.Append(ash::kSwitchAccessBluetoothDevice); - - const auto old_keys = prefs->Get(old_pref)->GetList(); - base::DictionaryValue new_keys; - for (const auto& key : old_keys) - new_keys.SetPath(base::NumberToString(key.GetInt()), devices.Clone()); - - prefs->Set(new_pref, std::move(new_keys)); - prefs->ClearPref(old_pref); -} - } // namespace AccessibilityControllerImpl::Feature::Feature( @@ -1697,26 +1677,6 @@ void AccessibilityControllerImpl::ObservePrefs(PrefService* prefs) { DCHECK(prefs); - // TODO(accessibility): Remove in m92 or later after deprecation; see - // https://bugs.chromium.org/p/chromium/issues/detail?id=1161305 - static const char kAccessibilitySwitchAccessSelectKeyCodes[] = - "settings.a11y.switch_access.select.key_codes"; - static const char kAccessibilitySwitchAccessNextKeyCodes[] = - "settings.a11y.switch_access.next.key_codes"; - static const char kAccessibilitySwitchAccessPreviousKeyCodes[] = - "settings.a11y.switch_access.previous.key_codes"; - - // Migrate old keys to the new format. - MigrateSwitchAccessKeyCodePref( - prefs, kAccessibilitySwitchAccessSelectKeyCodes, - prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes); - MigrateSwitchAccessKeyCodePref( - prefs, kAccessibilitySwitchAccessNextKeyCodes, - prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes); - MigrateSwitchAccessKeyCodePref( - prefs, kAccessibilitySwitchAccessPreviousKeyCodes, - prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes); - active_user_prefs_ = prefs; // Watch for pref updates from webui settings and policy.
diff --git a/ash/accessibility/chromevox/touch_exploration_controller.cc b/ash/accessibility/chromevox/touch_exploration_controller.cc index 511a37e..9bf73350 100644 --- a/ash/accessibility/chromevox/touch_exploration_controller.cc +++ b/ash/accessibility/chromevox/touch_exploration_controller.cc
@@ -791,7 +791,7 @@ return; } case SINGLE_TAP_PRESSED: - FALLTHROUGH; + [[fallthrough]]; case GESTURE_IN_PROGRESS: // If only one finger is down, go into touch exploration. if (current_touch_ids_.size() == 1) {
diff --git a/ash/ambient/ambient_constants.h b/ash/ambient/ambient_constants.h index e8f8d8ed..50e7671 100644 --- a/ash/ambient/ambient_constants.h +++ b/ash/ambient/ambient_constants.h
@@ -64,7 +64,7 @@ // // The motion designers who build the Lottie animations and eng have agreed upon // this prefix. Do not change unless coordinated with motion designers. -constexpr char kLottieDynamicAssetIdPrefix[] = "USER_PHOTO_"; +constexpr char kLottieDynamicAssetIdPrefix[] = "dynamic_img"; } // namespace ash
diff --git a/ash/ambient/util/ambient_util_unittest.cc b/ash/ambient/util/ambient_util_unittest.cc index 346de4cc..38c2e80 100644 --- a/ash/ambient/util/ambient_util_unittest.cc +++ b/ash/ambient/util/ambient_util_unittest.cc
@@ -12,8 +12,8 @@ namespace util { TEST(AmbientUtilTest, IsDynamicLottieAsset) { - EXPECT_TRUE(IsDynamicLottieAsset("USER_PHOTO_1")); - EXPECT_TRUE(IsDynamicLottieAsset("USER_PHOTO_2")); + EXPECT_TRUE(IsDynamicLottieAsset("dynamic_img1")); + EXPECT_TRUE(IsDynamicLottieAsset("dynamic_img2")); EXPECT_FALSE(IsDynamicLottieAsset("some_random_string")); EXPECT_FALSE(IsDynamicLottieAsset("random_string_with_user_photo_in_it")); }
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index fc047c8..42ada8a 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -192,6 +192,17 @@ EXPECT_LT(dialog_bounds.y(), search_box_bounds.bottom()); } +// Returns the search box view from either the clamshell bubble or the tablet +// mode fullscreen launcher. +SearchBoxView* GetSearchBoxViewFromHelper(AppListTestHelper* helper) { + if (features::IsProductivityLauncherEnabled() && + !Shell::Get()->IsInTabletMode()) { + DCHECK(Shell::Get()->app_list_controller()->IsVisible()); + return helper->GetBubbleSearchBoxView(); + } + return helper->GetSearchBoxView(); +} + } // namespace // This suite used to be called AppListPresenterDelegateTest. It's not called @@ -235,12 +246,7 @@ bool TestFullscreenParam() const { return GetParam(); } SearchBoxView* GetSearchBoxView() { - if (features::IsProductivityLauncherEnabled() && - !Shell::Get()->IsInTabletMode()) { - DCHECK(Shell::Get()->app_list_controller()->IsVisible()); - return GetAppListTestHelper()->GetBubbleSearchBoxView(); - } - return GetAppListTestHelper()->GetSearchBoxView(); + return GetSearchBoxViewFromHelper(GetAppListTestHelper()); } gfx::Point GetPointOutsideSearchbox() { @@ -4590,10 +4596,23 @@ } // Test a variety of behaviors for home launcher (app list in tablet mode). -class AppListPresenterHomeLauncherTest : public AshTestBase { +// Parameterized by ProductivityLauncher. +class AppListPresenterHomeLauncherTest + : public AshTestBase, + public testing::WithParamInterface<bool> { public: AppListPresenterHomeLauncherTest() { - scoped_feature_list_.InitAndEnableFeature(features::kEnableBackgroundBlur); + const bool enable_productivity_launcher = GetParam(); + if (enable_productivity_launcher) { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEnableBackgroundBlur, + features::kProductivityLauncher}, + /*disabled_features=*/{}); + } else { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEnableBackgroundBlur}, + /*disabled_features=*/{features::kProductivityLauncher}); + } } AppListPresenterHomeLauncherTest(const AppListPresenterHomeLauncherTest&) = delete; @@ -4653,8 +4672,7 @@ // (2) The point is outside of the search box. // (3) The touch event on the point should not be consumed by the handler // for back gesture. - return GetAppListView() - ->search_box_view() + return GetSearchBoxViewFromHelper(GetAppListTestHelper()) ->GetBoundsInScreen() .bottom_right(); } @@ -4674,8 +4692,16 @@ std::unique_ptr<WallpaperControllerTestApi> wallpaper_test_api_; }; +INSTANTIATE_TEST_SUITE_P(ProductivityLauncher, + AppListPresenterHomeLauncherTest, + testing::Bool()); + // Verifies that mouse dragging AppListView is enabled. -TEST_F(AppListPresenterHomeLauncherTest, MouseDragAppList) { +TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppList) { + // ProductivityLauncher doesn't use peeking state or app list dragging. + if (features::IsProductivityLauncherEnabled()) + return; + std::unique_ptr<AppListItem> item(new AppListItem("fake id")); GetAppListModel()->AddItem(std::move(item)); @@ -4705,7 +4731,11 @@ // Verifies that mouse dragging AppListView creates layers, causes to change the // opacity, and destroys the layers when done. -TEST_F(AppListPresenterHomeLauncherTest, MouseDragAppListItemOpacity) { +TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppListItemOpacity) { + // ProductivityLauncher doesn't use peeking state or app list dragging. + if (features::IsProductivityLauncherEnabled()) + return; + const int items_in_page = SharedAppListConfig::instance().GetMaxNumOfItemsPerPage(); for (int i = 0; i < items_in_page; ++i) { @@ -4767,7 +4797,11 @@ // Tests that ending of the mouse dragging of app-list destroys the layers for // the items which are in the second page. See https://crbug.com/990529. -TEST_F(AppListPresenterHomeLauncherTest, LayerOnSecondPage) { +TEST_P(AppListPresenterHomeLauncherTest, LayerOnSecondPage) { + // ProductivityLauncher doesn't use peeking state or app list dragging. + if (features::IsProductivityLauncherEnabled()) + return; + const int items_in_page = SharedAppListConfig::instance().GetMaxNumOfItemsPerPage(); AppListModel* model = GetAppListModel(); @@ -4843,7 +4877,7 @@ // Tests that the app list is shown automatically when the tablet mode is on. // The app list is dismissed when the tablet mode is off. -TEST_F(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) { +TEST_P(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) { GetAppListTestHelper()->CheckVisibility(false); // Turns on tablet mode. @@ -4857,11 +4891,11 @@ // Tests that the app list window's parent is changed after entering tablet // mode. -TEST_F(AppListPresenterHomeLauncherTest, ParentWindowContainer) { +TEST_P(AppListPresenterHomeLauncherTest, ParentWindowContainer) { // Show app list in non-tablet mode. The window container should be // kShellWindowId_AppListContainer. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); - aura::Window* window = GetAppListView()->GetWidget()->GetNativeWindow(); + aura::Window* window = Shell::Get()->app_list_controller()->GetWindow(); aura::Window* root_window = window->GetRootWindow(); EXPECT_TRUE(root_window->GetChildById(kShellWindowId_AppListContainer) ->Contains(window)); @@ -4869,12 +4903,13 @@ // Turn on tablet mode. The window container should be // kShellWindowId_HomeScreenContainer. EnableTabletMode(true); + aura::Window* window2 = Shell::Get()->app_list_controller()->GetWindow(); EXPECT_TRUE(root_window->GetChildById(kShellWindowId_HomeScreenContainer) - ->Contains(window)); + ->Contains(window2)); } // Tests that the background opacity change for app list. -TEST_F(AppListPresenterHomeLauncherTest, BackgroundOpacity) { +TEST_P(AppListPresenterHomeLauncherTest, BackgroundOpacity) { // ProductivityLauncher uses a different widget for clamshell mode. if (!features::IsProductivityLauncherEnabled()) { // Show app list in non-tablet mode. The background shield opacity should be @@ -4914,7 +4949,7 @@ // Tests that the background blur which is present in clamshell mode does not // show in tablet mode. -TEST_F(AppListPresenterHomeLauncherTest, BackgroundBlur) { +TEST_P(AppListPresenterHomeLauncherTest, BackgroundBlur) { // ProductivityLauncher uses a different widget for clamshell mode. if (!features::IsProductivityLauncherEnabled()) { // Show app list in non-tablet mode. The background blur should be enabled. @@ -4935,38 +4970,39 @@ } // Tests that tapping or clicking on background cannot dismiss the app list. -TEST_F(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) { +TEST_P(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) { // Show app list in non-tablet mode. Click outside search box. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); ui::test::EventGenerator* generator = GetEventGenerator(); - generator->MoveMouseTo(GetPointOutsideSearchbox()); + const gfx::Point origin; + generator->MoveMouseTo(origin); generator->ClickLeftButton(); GetAppListTestHelper()->WaitUntilIdle(); - GetAppListTestHelper()->CheckVisibility(false); + EXPECT_FALSE(IsAppListVisible()); // Show app list in non-tablet mode. Tap outside search box. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); - generator->GestureTapDownAndUp(GetPointOutsideSearchbox()); + generator->GestureTapDownAndUp(origin); GetAppListTestHelper()->WaitUntilIdle(); - GetAppListTestHelper()->CheckVisibility(false); + EXPECT_FALSE(IsAppListVisible()); // Show app list in tablet mode. Click outside search box. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); - generator->MoveMouseTo(GetPointOutsideSearchbox()); + generator->MoveMouseTo(origin); generator->PressLeftButton(); GetAppListTestHelper()->WaitUntilIdle(); - GetAppListTestHelper()->CheckVisibility(true); + EXPECT_TRUE(IsAppListVisible()); // Tap outside search box. - generator->GestureTapDownAndUp(GetPointOutsideSearchbox()); + generator->GestureTapDownAndUp(origin); GetAppListTestHelper()->WaitUntilIdle(); - GetAppListTestHelper()->CheckVisibility(true); + EXPECT_TRUE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, EscapeKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4976,7 +5012,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) { +TEST_P(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4985,7 +5021,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, SearchKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4995,7 +5031,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, EscapeKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -5005,7 +5041,7 @@ EXPECT_TRUE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, BackKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -5015,7 +5051,7 @@ EXPECT_TRUE(IsAppListVisible()); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, SearchKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -5026,7 +5062,7 @@ } // Tests that moving focus outside app list window can dismiss it. -TEST_F(AppListPresenterHomeLauncherTest, FocusOutToDismiss) { +TEST_P(AppListPresenterHomeLauncherTest, FocusOutToDismiss) { // Show app list in non-tablet mode. Move focus to another window. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -5132,7 +5168,11 @@ // Test that the AppListView opacity is reset after it is hidden during the // overview mode animation. -TEST_F(AppListPresenterHomeLauncherTest, LauncherShowsAfterOverviewMode) { +TEST_P(AppListPresenterHomeLauncherTest, LauncherShowsAfterOverviewMode) { + // ProductivityLauncher closes itself in overview in clamshell mode. + if (features::IsProductivityLauncherEnabled()) + return; + // Show the AppList in clamshell mode. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -5156,7 +5196,7 @@ // Tests that tapping home button while home screen is visible and showing // search results moves the home screen to apps container page. -TEST_F(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) { +TEST_P(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5181,7 +5221,7 @@ } // Tests the app list opacity in overview mode. -TEST_F(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) { +TEST_P(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5199,13 +5239,13 @@ EXPECT_EQ(1.0f, layer->opacity()); } -TEST_F(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) { +TEST_P(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); GetAppListTestHelper()->CheckVisibility(false); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewConfirmed) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5213,7 +5253,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewCanceled) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5221,7 +5261,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewAndExitOverviewMode) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5234,7 +5274,7 @@ } // Tests that going home will minimize all windows. -TEST_F(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) { +TEST_P(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) { // Show app list in tablet mode. Maximize all windows. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5271,7 +5311,7 @@ } // Tests that going home will end split view mode. -TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) { +TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) { // Show app list in tablet mode. Enter split view mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5285,7 +5325,7 @@ } // Tests that going home will end overview mode. -TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) { +TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) { // Show app list in tablet mode. Enter overview mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5301,7 +5341,7 @@ // Tests that going home will end overview and split view mode if both are // active (e.g. one side of the split view contains overview). -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewModeWithOverview) { // Show app list in tablet mode. Enter split view mode. EnableTabletMode(true); @@ -5327,7 +5367,7 @@ // Tests that the context menu is triggered in the same way as if we are on // the wallpaper. -TEST_F(AppListPresenterHomeLauncherTest, WallpaperContextMenu) { +TEST_P(AppListPresenterHomeLauncherTest, WallpaperContextMenu) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5370,10 +5410,12 @@ // Tests app list visibility when switching to tablet mode during dragging from // shelf. -// TODO(crbug.com/1281927): Figure out if ProductivityLauncher needs to -// support swipe to open and close. -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, SwitchToTabletModeDuringDraggingFromShelf) { + // ProductivityLauncher doesn't use peeking state or app list dragging. + if (features::IsProductivityLauncherEnabled()) + return; + UpdateDisplay("1080x900"); GetAppListTestHelper()->CheckVisibility(false); @@ -5415,10 +5457,12 @@ // Tests app list visibility when switching to tablet mode during dragging to // close app list. -// TODO(crbug.com/1281927): Figure out if ProductivityLauncher needs to -// support swipe to open and close. -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, SwitchToTabletModeDuringDraggingToClose) { + // ProductivityLauncher doesn't use peeking state or app list dragging. + if (features::IsProductivityLauncherEnabled()) + return; + UpdateDisplay("1080x900"); // Open app list. @@ -5454,7 +5498,7 @@ } // Test backdrop exists for active non-fullscreen window in tablet mode. -TEST_F(AppListPresenterHomeLauncherTest, BackdropTest) { +TEST_P(AppListPresenterHomeLauncherTest, BackdropTest) { WorkspaceControllerTestApi test_helper(ShellTestApi().workspace_controller()); EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5469,7 +5513,7 @@ // Tests that app list is not active when switching to tablet mode if an active // window exists. -TEST_F(AppListPresenterHomeLauncherTest, +TEST_P(AppListPresenterHomeLauncherTest, NotActivateAppListWindowWhenActiveWindowExists) { // No window is active. EXPECT_EQ(nullptr, window_util::GetActiveWindow()); @@ -5589,7 +5633,7 @@ EXPECT_FALSE(GetSearchBoxView()->is_search_box_active()); } -TEST_F(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) { +TEST_P(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) { UpdateDisplay("800x600,1000x768"); TapHomeButton(GetSecondaryDisplay().id());
diff --git a/ash/app_list/app_list_test_api.cc b/ash/app_list/app_list_test_api.cc index dce3639..32e7622 100644 --- a/ash/app_list/app_list_test_api.cc +++ b/ash/app_list/app_list_test_api.cc
@@ -17,6 +17,7 @@ #include "ash/app_list/model/app_list_model.h" #include "ash/app_list/views/app_list_bubble_apps_page.h" #include "ash/app_list/views/app_list_bubble_view.h" +#include "ash/app_list/views/app_list_folder_view.h" #include "ash/app_list/views/app_list_item_view.h" #include "ash/app_list/views/app_list_main_view.h" #include "ash/app_list/views/app_list_reorder_undo_container_view.h" @@ -41,13 +42,15 @@ namespace { +AppListView* GetAppListView() { + return Shell::Get()->app_list_controller()->presenter()->GetView(); +} + PagedAppsGridView* GetPagedAppsGridView() { // This view only exists for tablet launcher and legacy peeking launcher. DCHECK(Shell::Get()->IsInTabletMode() || !features::IsProductivityLauncherEnabled()); - AppListView* app_list_view = - Shell::Get()->app_list_controller()->presenter()->GetView(); - return AppListView::TestApi(app_list_view).GetRootAppsGridView(); + return AppListView::TestApi(GetAppListView()).GetRootAppsGridView(); } AppListBubbleView* GetAppListBubbleView() { @@ -61,6 +64,20 @@ return bubble_view; } +AppListFolderView* GetAppListFolderView() { + // Handle the case that the app list bubble view is effective. + if (features::IsProductivityLauncherEnabled() && + !Shell::Get()->tablet_mode_controller()->InTabletMode()) { + return GetAppListBubbleView()->folder_view_for_test(); + } + + return GetAppListView() + ->app_list_main_view() + ->contents_view() + ->apps_container_view() + ->app_list_folder_view(); +} + AppListReorderUndoContainerView* GetReorderUndoContainerViewFromBubble() { DCHECK(features::IsLauncherAppSortEnabled()); return GetAppListBubbleView()->apps_page()->reorder_undo_container_for_test(); @@ -246,6 +263,14 @@ return GetPagedAppsGridView(); } +AppsGridView* AppListTestApi::GetFolderAppsGridView() { + return GetAppListFolderView()->items_grid_view(); +} + +bool AppListTestApi::IsFolderViewAnimating() const { + return GetAppListFolderView()->IsAnimationRunning(); +} + views::View* AppListTestApi::GetBubbleReorderUndoButton() { return GetReorderUndoContainerViewFromBubble() ->GetToastDismissButtonForTest(); @@ -255,4 +280,15 @@ return GetReorderUndoContainerViewFromBubble()->is_toast_visible_for_test(); } +void AppListTestApi::SetFolderViewAnimationCallback( + base::OnceClosure folder_animation_done_callback) { + AppListFolderView* folder_view = GetAppListFolderView(); + folder_view->SetAnimationDoneTestCallback(base::BindOnce( + [](AppListFolderView* folder_view, + base::OnceClosure folder_animation_done_callback) { + std::move(folder_animation_done_callback).Run(); + }, + folder_view, std::move(folder_animation_done_callback))); +} + } // namespace ash
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index 3ff1cac..4b40ea0 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -9,7 +9,6 @@ #include <vector> #include "ash/app_list/model/app_list_model.h" -#include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_switches.h" #include "base/callback.h" #include "base/files/file_path.h" @@ -43,8 +42,7 @@ for (size_t i = 0; i < results->item_count(); ++i) { if (results->GetItemAt(i)->id() == result_id) { open_search_result_counts_[i]++; - if (app_list_features::IsAssistantSearchEnabled() && - results->GetItemAt(i)->is_omnibox_search()) { + if (results->GetItemAt(i)->is_omnibox_search()) { ++open_assistant_ui_count_; } break;
diff --git a/ash/app_list/model/search/search_model.h b/ash/app_list/model/search/search_model.h index d402b90a..6631d924 100644 --- a/ash/app_list/model/search/search_model.h +++ b/ash/app_list/model/search/search_model.h
@@ -71,7 +71,8 @@ // hidden by its source. Returns null if no such result exists. SearchResult* GetFirstVisibleResult(); - // Deletes all search results. This is used in profile switches. + // Deletes all search results. This is used when moving from zero-state to a + // search query. void DeleteAllResults(); // Delete result by the given id.
diff --git a/ash/app_list/views/app_list_bubble_apps_page.h b/ash/app_list/views/app_list_bubble_apps_page.h index 2a71fbd..70a5c78a 100644 --- a/ash/app_list/views/app_list_bubble_apps_page.h +++ b/ash/app_list/views/app_list_bubble_apps_page.h
@@ -109,6 +109,10 @@ return reorder_undo_container_; } + ScrollViewGradientHelper* gradient_helper_for_test() { + return gradient_helper_.get(); + } + private: friend class AppListTestHelper;
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc index 48dc019..b11fd06d 100644 --- a/ash/app_list/views/app_list_bubble_view.cc +++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -559,6 +559,8 @@ // Restore the layer bounds. This isn't visible because opacity is 0. layer()->SetBounds(layer_bounds); + search_box_view_->ClearSearch(); + // Hide any open folder by showing the apps page. ShowApps(/*folder_item_view=*/nullptr, /*select_folder=*/false);
diff --git a/ash/app_list/views/app_list_bubble_view.h b/ash/app_list/views/app_list_bubble_view.h index de36b8b..6aba51c 100644 --- a/ash/app_list/views/app_list_bubble_view.h +++ b/ash/app_list/views/app_list_bubble_view.h
@@ -102,6 +102,7 @@ views::View* separator_for_test() { return separator_; } bool showing_folder_for_test() { return showing_folder_; } AppListBubbleAppsPage* apps_page_for_test() { return apps_page_; } + AppListFolderView* folder_view_for_test() { return folder_view_; } private: friend class AppListTestHelper;
diff --git a/ash/app_list/views/app_list_bubble_view_unittest.cc b/ash/app_list/views/app_list_bubble_view_unittest.cc index 2302806..6fb0a26e 100644 --- a/ash/app_list/views/app_list_bubble_view_unittest.cc +++ b/ash/app_list/views/app_list_bubble_view_unittest.cc
@@ -27,9 +27,11 @@ #include "ash/app_list/views/search_box_view.h" #include "ash/assistant/model/assistant_ui_model.h" #include "ash/constants/ash_features.h" +#include "ash/controls/scroll_view_gradient_helper.h" #include "ash/public/cpp/assistant/controller/assistant_ui_controller.h" #include "ash/public/cpp/style/color_provider.h" #include "ash/public/cpp/test/assistant_test_api.h" +#include "ash/shelf/gradient_layer_delegate.h" #include "ash/shell.h" #include "ash/style/ash_color_provider.h" #include "ash/system/tray/tray_constants.h" @@ -447,6 +449,38 @@ EXPECT_TRUE(search_box_view->is_search_box_active()); } +TEST_F(AppListBubbleViewTest, ClosingBubbleClearsSearch) { + AddAppItems(1); + ShowAppList(); + + // Enter a query, and verify that search results page is shown. + PressAndReleaseKey(ui::VKEY_A); + + EXPECT_FALSE(GetAppsPage()->GetVisible()); + EXPECT_TRUE(GetSearchPage()->GetVisible()); + EXPECT_FALSE(GetAssistantPage()->GetVisible()); + + views::Textfield* search_box_input = GetSearchBoxView()->search_box(); + EXPECT_TRUE(search_box_input->HasFocus()); + EXPECT_EQ(u"a", search_box_input->GetText()); + TestAppListClient* client = GetAppListTestHelper()->app_list_client(); + EXPECT_EQ(u"a", client->last_search_query()); + + // The app list view and widget are cached after this close. + DismissAppList(); + + // Search box is empty on next show. + ShowAppList(); + EXPECT_TRUE(GetAppsPage()->GetVisible()); + EXPECT_FALSE(GetSearchPage()->GetVisible()); + EXPECT_FALSE(GetAssistantPage()->GetVisible()); + + search_box_input = GetSearchBoxView()->search_box(); + EXPECT_TRUE(search_box_input->HasFocus()); + EXPECT_EQ(u"", search_box_input->GetText()); + EXPECT_EQ(u"", client->last_search_query()); +} + TEST_F(AppListBubbleViewTest, SearchBoxTextUsesPrimaryTextColor) { ShowAppList(); @@ -1127,5 +1161,56 @@ EXPECT_GT(final_scroll_offset, initial_scroll_offset); } +TEST_F(AppListBubbleViewTest, AutoScrollToFitViewOnFocus) { + // Show an app list with enough apps to fill the page and trigger a gradient + // at the bottom. + AddAppItems(50); + ShowAppList(); + + // Scroll view gradient mask layer is created. + auto* scroll_view = GetAppsPage()->scroll_view(); + EXPECT_TRUE(scroll_view->layer()->layer_mask_layer()); + const int rows = base::ClampFloor(50.0 / GetAppsGridView()->cols()); + + // Focus the first item on the last row. + for (int i = 0; i < rows; i++) + PressAndReleaseKey(ui::VKEY_DOWN); + + gfx::Rect app_view_bounds = GetAppsGridView() + ->GetFocusManager() + ->GetFocusedView() + ->GetBoundsInScreen(); + GradientLayerDelegate* gradient_layer = + GetAppsPage()->gradient_helper_for_test()->gradient_layer_for_test(); + gfx::Rect gradient_mask_bounds_start = + gradient_layer->start_fade_zone_bounds(); + gfx::Rect gradient_mask_bounds_end = gradient_layer->end_fade_zone_bounds(); + views::View::ConvertRectToScreen(scroll_view, &gradient_mask_bounds_start); + views::View::ConvertRectToScreen(scroll_view, &gradient_mask_bounds_end); + + // The gradient mask should not obscure the focused app view. + EXPECT_FALSE(gradient_mask_bounds_start.Intersects(app_view_bounds)); + EXPECT_FALSE(gradient_mask_bounds_end.Intersects(app_view_bounds)); + + // Press down arrow two more times to move focus to the first row again. + PressAndReleaseKey(ui::VKEY_DOWN); + PressAndReleaseKey(ui::VKEY_DOWN); + + ASSERT_TRUE(GetAppsGridView()->GetItemViewAt(0)->HasFocus()); + + app_view_bounds = GetAppsGridView() + ->GetFocusManager() + ->GetFocusedView() + ->GetBoundsInScreen(); + gradient_mask_bounds_start = gradient_layer->start_fade_zone_bounds(); + gradient_mask_bounds_end = gradient_layer->end_fade_zone_bounds(); + views::View::ConvertRectToScreen(scroll_view, &gradient_mask_bounds_start); + views::View::ConvertRectToScreen(scroll_view, &gradient_mask_bounds_end); + + // The gradient mask should not obscure the focused app view. + EXPECT_FALSE(gradient_mask_bounds_start.Intersects(app_view_bounds)); + EXPECT_FALSE(gradient_mask_bounds_end.Intersects(app_view_bounds)); +} + } // namespace } // namespace ash
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index b2066729..579f467 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -777,8 +777,6 @@ "Apps.AppListFolder.ShowHide.AnimationSmoothness", smoothness); }))); - hide_for_reparent_ = hide_for_reparent; - if (!features::IsProductivityLauncherEnabled()) { static_cast<PagedAppsGridView*>(items_grid_view_) ->pagination_model() @@ -806,20 +804,18 @@ std::make_unique<ContentsContainerAnimation>(show, hide_for_reparent, this)); - // If the folder view is hiding for folder closure, reset the folder state - // when the animations complete. Not resetting state immediately so the folder - // view keeps tracking folder item view's liveness (so it can reset animations - // if the folder item view gets deleted). - // If the view is hidden for reparent, the state will be cleared when the - // reparent drag ends. - base::RepeatingClosure animation_completion_callback = - !show && !hide_for_reparent - ? base::BarrierClosure( - folder_visibility_animations_.size(), - base::BindOnce(&AppListFolderView::ResetState, - base::Unretained(this), - /*reset_folder_item_view_state=*/true)) - : base::RepeatingClosure(); + base::RepeatingClosure animation_completion_callback; + if (!show) { + animation_completion_callback = base::BarrierClosure( + folder_visibility_animations_.size(), + base::BindOnce(&AppListFolderView::OnHideAnimationDone, + weak_ptr_factory_.GetWeakPtr(), hide_for_reparent)); + } else if (animation_done_test_callback_) { + animation_completion_callback = base::BarrierClosure( + folder_visibility_animations_.size(), + base::BindOnce(&AppListFolderView::OnShowAnimationDone, + weak_ptr_factory_.GetWeakPtr())); + } for (auto& animation : folder_visibility_animations_) animation->ScheduleAnimation(animation_completion_callback); @@ -928,12 +924,32 @@ folder_item_view_observer_.Reset(); folder_item_view_ = nullptr; - hide_for_reparent_ = false; - preferred_bounds_ = gfx::Rect(); folder_item_icon_bounds_ = gfx::Rect(); } +void AppListFolderView::OnShowAnimationDone() { + if (animation_done_test_callback_) + std::move(animation_done_test_callback_).Run(); +} + +void AppListFolderView::OnHideAnimationDone(bool hide_for_reparent) { + // If the folder view is hiding for folder closure, reset the + // folder state when the animations complete. Not resetting state + // immediately so the folder view keeps tracking folder item + // view's liveness (so it can reset animations if the folder item + // view gets deleted). + // If the view is hidden for reparent, the state will be cleared + // when the reparent drag ends. + if (!hide_for_reparent) { + ResetState( + /*reset_folder_item_view_state=*/true); + } + + if (animation_done_test_callback_) + std::move(animation_done_test_callback_).Run(); +} + void AppListFolderView::UpdatePreferredBounds() { if (!folder_item_view_) return; @@ -1005,6 +1021,12 @@ ShrinkGridTileMarginsWhenNeeded(); } +void AppListFolderView::SetAnimationDoneTestCallback( + base::OnceClosure animation_done_callback) { + DCHECK(!animation_done_callback || !animation_done_test_callback_); + animation_done_test_callback_ = std::move(animation_done_callback); +} + void AppListFolderView::RecordAnimationSmoothness() { // RecordAnimationSmoothness is called when ContentsContainerAnimation // ends as well. Do not record show/hide metrics for that.
diff --git a/ash/app_list/views/app_list_folder_view.h b/ash/app_list/views/app_list_folder_view.h index 499de3f2..1440bba 100644 --- a/ash/app_list/views/app_list_folder_view.h +++ b/ash/app_list/views/app_list_folder_view.h
@@ -139,6 +139,9 @@ // to be in the parent view's coordinate system. void SetBoundingBox(const gfx::Rect& bounding_box); + // Sets the callback that runs when the folder animation ends. + void SetAnimationDoneTestCallback(base::OnceClosure animation_done_callback); + AppsGridView* items_grid_view() { return items_grid_view_; } FolderHeaderView* folder_header_view() { return folder_header_view_; } @@ -230,6 +233,14 @@ // false when resetting the folder state due to folder item view deletion. void ResetState(bool restore_folder_item_view_state); + // Called when the animation to show the folder view is completed. + void OnShowAnimationDone(); + + // Called when the animation to hide the folder view is completed. + // `hide_for_reparent` is true if an item in the folder is being reparented to + // the root grid view. + void OnHideAnimationDone(bool hide_for_reparent); + // Controller interface implemented by the container for this view. AppListFolderController* const folder_controller_; @@ -274,8 +285,6 @@ // are relative the the parent view's coordinate system. gfx::Rect bounding_box_; - bool hide_for_reparent_ = false; - std::vector<std::unique_ptr<Animation>> folder_visibility_animations_; // Records smoothness of the folder show/hide animation. @@ -291,6 +300,9 @@ base::ScopedObservation<views::View, views::ViewObserver> folder_item_view_observer_{this}; + // The callback that runs at the end of the folder animation. + base::OnceClosure animation_done_test_callback_; + base::WeakPtrFactory<AppListFolderView> weak_ptr_factory_{this}; };
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index 45881aa..b691070 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -25,6 +25,7 @@ #include "ash/app_list/views/apps_grid_view.h" #include "ash/app_list/views/apps_grid_view_test_api.h" #include "ash/app_list/views/contents_view.h" +#include "ash/app_list/views/continue_section_view.h" #include "ash/app_list/views/expand_arrow_view.h" #include "ash/app_list/views/folder_background_view.h" #include "ash/app_list/views/folder_header_view.h" @@ -49,6 +50,7 @@ #include "ash/public/cpp/presentation_time_recorder.h" #include "ash/public/cpp/test/test_app_list_color_provider.h" #include "ash/search_box/search_box_constants.h" +#include "ash/style/ash_color_provider.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -73,7 +75,6 @@ namespace ash { namespace test { - namespace { constexpr int kInitialItems = 34; @@ -168,23 +169,14 @@ ~TestStartPageSearchResult() override = default; }; -class AppListViewTest : public views::ViewsTestBase, - public testing::WithParamInterface<bool> { +class AppListViewTest : public views::ViewsTestBase { public: AppListViewTest() = default; - AppListViewTest(const AppListViewTest&) = delete; AppListViewTest& operator=(const AppListViewTest&) = delete; - ~AppListViewTest() override = default; void SetUp() override { - if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) { - // Setup right to left environment if necessary. - is_rtl_ = GetParam(); - if (is_rtl_) - base::i18n::SetICUDefaultLocale("he"); - } views::ViewsTestBase::SetUp(); zero_duration_mode_ = std::make_unique<ui::ScopedAnimationDurationScaleMode>( @@ -417,13 +409,13 @@ } } - // Restores the locale to default when destructor is called. - base::test::ScopedRestoreICUDefaultLocale restore_locale_; - // Sets animation durations to zero. std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; - TestAppListColorProvider color_provider_; // Needed by AppListView. + TestAppListColorProvider app_list_color_provider_; // Needed by AppListView. + + // Needed by ProductivityLauncher AppsContainerView::ContinueContainer. + AshColorProvider ash_color_provider_; AppListView* view_ = nullptr; // Owned by native widget. std::unique_ptr<AppListTestViewDelegate> delegate_; @@ -431,11 +423,35 @@ // Used by AppListFolderView::UpdatePreferredBounds. keyboard::KeyboardUIController keyboard_ui_controller_; - - bool is_rtl_ = false; }; -INSTANTIATE_TEST_SUITE_P(Rtl, AppListViewTest, ::testing::Bool()); +// Tests for the legacy "peeking" clamshell launcher. These can be deleted when +// ProductivityLauncher is the default. +class AppListViewPeekingTest : public AppListViewTest { + public: + AppListViewPeekingTest() { + feature_list_.InitAndDisableFeature(features::kProductivityLauncher); + } + + base::test::ScopedFeatureList feature_list_; +}; + +// Tests for tablet mode. Parameterized by ProductivityLauncher. +class AppListViewTabletTest : public AppListViewTest, + public testing::WithParamInterface<bool> { + public: + AppListViewTabletTest() { + const bool enable_productivity_launcher = GetParam(); + feature_list_.InitWithFeatureState(features::kProductivityLauncher, + enable_productivity_launcher); + } + + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P(ProductivityLauncher, + AppListViewTabletTest, + testing::Bool()); // Tests app list view layout for different screen sizes. class AppListViewScalableLayoutTest : public AppListViewTest { @@ -461,6 +477,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// Tests of focus, optionally parameterized by RTL. class AppListViewFocusTest : public views::ViewsTestBase, public testing::WithParamInterface<bool> { public: @@ -488,6 +505,7 @@ view_->InitView(GetContext()); Show(); test_api_ = std::make_unique<AppsGridViewTestApi>(apps_grid_view()); + // May be null for ProductivityLauncher, which does not use chips. suggestions_container_ = contents_view() ->apps_container_view() ->suggestion_chip_container_view_for_test(); @@ -507,7 +525,8 @@ AppListFolderItem* folder_item = model->CreateAndPopulateFolderWithApps(kItemNumInFolder); model->PopulateApps(kAppListItemNum); - suggestions_container()->Update(); + if (suggestions_container_) + suggestions_container_->Update(); EXPECT_EQ(static_cast<size_t>(kAppListItemNum + 1), model->top_level_item_list()->item_count()); EXPECT_EQ(folder_item->id(), @@ -579,6 +598,7 @@ result->set_display_type(data.first); result->set_display_score(display_score); result->set_title(u"Test"); + result->set_best_match(true); results->Add(std::move(result)); } } @@ -623,6 +643,7 @@ result->set_display_type(ash::SearchResultDisplayType::kList); result->set_display_score(score); result->set_title(ASCIIToUTF16(title)); + result->set_best_match(true); GetSearchModel()->results()->Add(std::move(result)); RunPendingMessages(); } @@ -807,6 +828,8 @@ } std::vector<views::View*> GetAllSuggestions() { + // ProductivityLauncher does not use suggestion chips. + DCHECK(!features::IsProductivityLauncherEnabled()); const auto& children = suggestions_container()->children(); std::vector<views::View*> suggestions; std::copy_if(children.cbegin(), children.cend(), @@ -832,10 +855,12 @@ base::test::ScopedFeatureList scoped_feature_list_; private: - TestAppListColorProvider color_provider_; // Needed by AppListView. + TestAppListColorProvider app_list_color_provider_; // Needed by AppListView. + AshColorProvider ash_color_provider_; // Needed by ProductivityLauncher. AppListView* view_ = nullptr; // Owned by native widget. - SearchResultContainerView* suggestions_container_ = - nullptr; // Owned by view hierarchy. + // Owned by view hierarchy. May be null for ProductivityLauncher, which does + // not use suggestion chips. + SearchResultContainerView* suggestions_container_ = nullptr; ExpandArrowView* expand_arrow_view_ = nullptr; // Owned by view hierarchy. std::unique_ptr<AppListTestViewDelegate> delegate_; @@ -847,9 +872,20 @@ keyboard::KeyboardUIController keyboard_ui_controller_; }; -INSTANTIATE_TEST_SUITE_P(All, AppListViewFocusTest, testing::Bool()); +INSTANTIATE_TEST_SUITE_P(Rtl, AppListViewFocusTest, testing::Bool()); -} // namespace +// Tests for the legacy "peeking" clamshell launcher. These can be deleted when +// ProductivityLauncher is the default. +class AppListViewPeekingFocusTest : public AppListViewFocusTest { + public: + AppListViewPeekingFocusTest() { + feature_list_.InitAndDisableFeature(features::kProductivityLauncher); + } + + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P(Rtl, AppListViewPeekingFocusTest, testing::Bool()); // Tests that the initial focus is on search box. TEST_F(AppListViewFocusTest, InitialFocus) { @@ -857,7 +893,7 @@ } // Tests the linear focus traversal in PEEKING state. -TEST_P(AppListViewFocusTest, LinearFocusTraversalInPeekingState) { +TEST_P(AppListViewPeekingFocusTest, LinearFocusTraversalInPeekingState) { Show(); SetAppListState(ash::AppListViewState::kPeeking); @@ -887,6 +923,11 @@ // Tests the linear focus traversal in FULLSCREEN_ALL_APPS state. TEST_P(AppListViewFocusTest, LinearFocusTraversalInFullscreenAllAppsState) { + // TODO(https://crbug.com/1284992): Fix for ProductivityLauncher, which + // does not use suggestion chips. + if (features::IsProductivityLauncherEnabled()) + return; + Show(); SetAppListState(ash::AppListViewState::kFullscreenAllApps); @@ -918,7 +959,7 @@ } // Tests focus traversal in HALF state with opened search box using |VKEY_TAB|. -TEST_F(AppListViewFocusTest, TabFocusTraversalInHalfState) { +TEST_F(AppListViewPeekingFocusTest, TabFocusTraversalInHalfState) { Show(); // Type something in search box to transition to HALF state and populate @@ -972,7 +1013,7 @@ // * search box text is cleared // * search box gets focus, but it's not active // * subsequent tab keys move focus to app list folder view. -TEST_F(AppListViewFocusTest, CloseButtonClearsSearchOnEnter) { +TEST_F(AppListViewPeekingFocusTest, CloseButtonClearsSearchOnEnter) { Show(); // Type something in search box to transition to HALF state and populate @@ -1016,7 +1057,7 @@ // Tests focus traversal in HALF state with opened search box using |VKEY_LEFT| // and |VKEY_RIGHT|. -TEST_P(AppListViewFocusTest, LeftRightFocusTraversalInHalfState) { +TEST_P(AppListViewPeekingFocusTest, LeftRightFocusTraversalInHalfState) { Show(); // Type something in search box to transition to HALF state and populate @@ -1101,24 +1142,42 @@ // Note: For fullscreen app list, the search box is part of the focus cycle // when a folder is open. + // ProductivityLauncher uses recent apps and continue section. + auto* recent_apps_view = apps_container_view->GetRecentApps(); + auto* continue_section_view = apps_container_view->GetContinueSection(); + // Non-ProductivityLauncher uses suggestion chips. auto* suggestion_chip_container = apps_container_view->suggestion_chip_container_view_for_test(); - EXPECT_TRUE(suggestion_chip_container->GetViewAccessibility().IsIgnored()); - EXPECT_TRUE(suggestion_chip_container->GetViewAccessibility().IsLeaf()); + if (features::IsProductivityLauncherEnabled()) { + EXPECT_TRUE(recent_apps_view->GetViewAccessibility().IsIgnored()); + EXPECT_TRUE(recent_apps_view->GetViewAccessibility().IsLeaf()); + EXPECT_TRUE(continue_section_view->GetViewAccessibility().IsIgnored()); + EXPECT_TRUE(continue_section_view->GetViewAccessibility().IsLeaf()); + } else { + EXPECT_TRUE(suggestion_chip_container->GetViewAccessibility().IsIgnored()); + EXPECT_TRUE(suggestion_chip_container->GetViewAccessibility().IsLeaf()); + } EXPECT_TRUE(apps_grid_view()->GetViewAccessibility().IsIgnored()); EXPECT_TRUE(apps_grid_view()->GetViewAccessibility().IsLeaf()); // Close the folder. SimulateKeyPress(ui::VKEY_ESCAPE, false); - EXPECT_FALSE(suggestion_chip_container->GetViewAccessibility().IsIgnored()); - EXPECT_FALSE(suggestion_chip_container->GetViewAccessibility().IsLeaf()); + if (features::IsProductivityLauncherEnabled()) { + EXPECT_FALSE(recent_apps_view->GetViewAccessibility().IsIgnored()); + EXPECT_FALSE(recent_apps_view->GetViewAccessibility().IsLeaf()); + EXPECT_FALSE(continue_section_view->GetViewAccessibility().IsIgnored()); + EXPECT_FALSE(continue_section_view->GetViewAccessibility().IsLeaf()); + } else { + EXPECT_FALSE(suggestion_chip_container->GetViewAccessibility().IsIgnored()); + EXPECT_FALSE(suggestion_chip_container->GetViewAccessibility().IsLeaf()); + } EXPECT_FALSE(apps_grid_view()->GetViewAccessibility().IsIgnored()); EXPECT_FALSE(apps_grid_view()->GetViewAccessibility().IsLeaf()); } // Tests the vertical focus traversal by in PEEKING state. -TEST_P(AppListViewFocusTest, VerticalFocusTraversalInPeekingState) { +TEST_P(AppListViewPeekingFocusTest, VerticalFocusTraversalInPeekingState) { Show(); SetAppListState(ash::AppListViewState::kPeeking); @@ -1144,6 +1203,11 @@ // Tests the vertical focus traversal in FULLSCREEN_ALL_APPS state. TEST_P(AppListViewFocusTest, VerticalFocusTraversalInFullscreenAllAppsState) { + // TODO(https://crbug.com/1284992): Fix for ProductivityLauncher, which + // does not use suggestion chips. + if (features::IsProductivityLauncherEnabled()) + return; + Show(); SetAppListState(ash::AppListViewState::kFullscreenAllApps); @@ -1176,7 +1240,7 @@ } // Tests the vertical focus traversal in HALF state with opened search box. -TEST_F(AppListViewFocusTest, VerticalFocusTraversalInHalfState) { +TEST_F(AppListViewPeekingFocusTest, VerticalFocusTraversalInHalfState) { Show(); // Type something in search box to transition to HALF state and populate @@ -1258,8 +1322,9 @@ } // Tests the vertical focus traversal in FULLSCREEN_ALL_APPS state in the second -// page within folder. -TEST_F(AppListViewFocusTest, VerticalFocusTraversalInSecondPageOfFolder) { +// page within folder. ProductivityLauncher does not use pages for folders. +TEST_F(AppListViewPeekingFocusTest, + VerticalFocusTraversalInSecondPageOfFolder) { Show(); // Transition to FULLSCREEN_ALL_APPS state and open the folder. @@ -1306,7 +1371,7 @@ // Tests that the focus is set back onto search box after all state transitions // besides those going to/from an activated folder. -TEST_F(AppListViewFocusTest, FocusResetAfterStateTransition) { +TEST_F(AppListViewPeekingFocusTest, FocusResetAfterStateTransition) { Show(); // Type something in search box to transition to HALF state and populate @@ -1363,6 +1428,11 @@ // Tests that key event which is not handled by focused view will be redirected // to search box when search box view is active (but not focused). TEST_F(AppListViewFocusTest, RedirectFocusToSearchBox) { + // TODO(https://crbug.com/1284992): Fix for ProductivityLauncher, which + // does not support this behavior and also does not use suggestion chips. + if (features::IsProductivityLauncherEnabled()) + return; + Show(); // Set focus to first suggestion app and type a character. @@ -1552,8 +1622,10 @@ TEST_F(AppListViewFocusTest, SetFocusOnSearchboxWhenActivated) { Show(); - // Set focus to the first suggestion app. - GetAllSuggestions()[0]->RequestFocus(); + // Press tab several times to move focus out of the search box. + SimulateKeyPress(ui::VKEY_TAB, false); + SimulateKeyPress(ui::VKEY_TAB, false); + SimulateKeyPress(ui::VKEY_TAB, false); EXPECT_FALSE(search_box_view()->search_box()->HasFocus()); // Activate the search box. @@ -1704,7 +1776,7 @@ } // Tests that opening the app list opens in peeking mode by default. -TEST_F(AppListViewTest, ShowPeekingByDefault) { +TEST_F(AppListViewPeekingTest, ShowPeekingByDefault) { Initialize(false /*is_tablet_mode*/); Show(); @@ -1712,9 +1784,9 @@ ASSERT_EQ(ash::AppListViewState::kPeeking, view_->app_list_state()); } -TEST_F(AppListViewTest, RecordFolderMetrics_ZeroFolders) { +TEST_P(AppListViewTabletTest, RecordFolderMetrics_ZeroFolders) { base::HistogramTester histogram; - Initialize(/*is_tablet_mode=*/false); + Initialize(/*is_tablet_mode=*/true); delegate_->GetTestModel()->PopulateApps(2); Show(); @@ -1726,9 +1798,9 @@ "Apps.AppsInFolders.FullscreenAppListEnabled", 0)); } -TEST_F(AppListViewTest, RecordFolderMetrics_OneRegularFolder) { +TEST_P(AppListViewTabletTest, RecordFolderMetrics_OneRegularFolder) { base::HistogramTester histogram; - Initialize(/*is_tablet_mode=*/false); + Initialize(/*is_tablet_mode=*/true); delegate_->GetTestModel()->CreateAndPopulateFolderWithApps(2); Show(); @@ -1740,9 +1812,9 @@ "Apps.AppsInFolders.FullscreenAppListEnabled", 2)); } -TEST_F(AppListViewTest, RecordFolderMetrics_OemFolder) { +TEST_P(AppListViewTabletTest, RecordFolderMetrics_OemFolder) { base::HistogramTester histogram; - Initialize(/*is_tablet_mode=*/false); + Initialize(/*is_tablet_mode=*/true); delegate_->GetTestModel()->CreateSingleItemFolder(kOemFolderId, "item_id"); Show(); @@ -1755,9 +1827,9 @@ "Apps.AppsInFolders.FullscreenAppListEnabled", 0)); } -TEST_F(AppListViewTest, RecordFolderMetrics_LinuxAppsFolder) { +TEST_P(AppListViewTabletTest, RecordFolderMetrics_LinuxAppsFolder) { base::HistogramTester histogram; - Initialize(/*is_tablet_mode=*/false); + Initialize(/*is_tablet_mode=*/true); delegate_->GetTestModel()->CreateSingleItemFolder(kCrostiniFolderId, "item_id"); Show(); @@ -1773,8 +1845,9 @@ // Tests that in side shelf mode, the app list opens in fullscreen by default // and verifies that the top rounded corners of the app list background are -// hidden (see https://crbug.com/920082). -TEST_F(AppListViewTest, ShowFullscreenWhenInSideShelfMode) { +// hidden (see https://crbug.com/920082). ProductivityLauncher does not change +// shelf corners. +TEST_F(AppListViewPeekingTest, ShowFullscreenWhenInSideShelfMode) { Initialize(false /*is_tablet_mode*/); Show(true /*is_side_shelf*/); @@ -1797,7 +1870,7 @@ } // Tests that setting empty text in the search box does not change the state. -TEST_F(AppListViewTest, EmptySearchTextStillPeeking) { +TEST_F(AppListViewPeekingTest, EmptySearchTextStillPeeking) { Initialize(false /*is_tablet_mode*/); views::Textfield* search_box = view_->app_list_main_view()->search_box_view()->search_box(); @@ -1808,12 +1881,13 @@ ASSERT_EQ(ash::AppListViewState::kPeeking, view_->app_list_state()); } -TEST_F(AppListViewTest, UpwardMouseWheelScrollTransitionsToFullscreen) { +TEST_F(AppListViewPeekingTest, UpwardMouseWheelScrollTransitionsToFullscreen) { base::HistogramTester histogram_tester; Initialize(false /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); + EXPECT_EQ(AppListViewState::kPeeking, view_->app_list_state()); view_->HandleScroll(gfx::Point(0, 0), gfx::Vector2d(0, 30), ui::ET_MOUSEWHEEL); @@ -1843,7 +1917,8 @@ ASSERT_EQ(1, delegate_->dismiss_count()); } -TEST_F(AppListViewTest, DownwardMouseWheelScrollDismissesPeekingLauncher) { +TEST_F(AppListViewPeekingTest, + DownwardMouseWheelScrollDismissesPeekingLauncher) { Initialize(false /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); @@ -1856,11 +1931,12 @@ EXPECT_EQ(1, delegate_->dismiss_count()); } -TEST_F(AppListViewTest, UpwardGestureScrollTransitionsToFullscreen) { +TEST_F(AppListViewPeekingTest, UpwardGestureScrollTransitionsToFullscreen) { base::HistogramTester histogram_tester; Initialize(false /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); + EXPECT_EQ(AppListViewState::kPeeking, view_->app_list_state()); view_->HandleScroll(gfx::Point(0, 0), gfx::Vector2d(0, 30), ui::ET_SCROLL); @@ -1871,7 +1947,7 @@ "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0); } -TEST_F(AppListViewTest, DownwardGestureScrollDismissesPeekingLauncher) { +TEST_F(AppListViewPeekingTest, DownwardGestureScrollDismissesPeekingLauncher) { Initialize(false /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); @@ -1884,7 +1960,7 @@ } // Tests that typing text after opening transitions from peeking to half. -TEST_F(AppListViewTest, TypingPeekingToHalf) { +TEST_F(AppListViewPeekingTest, TypingPeekingToHalf) { Initialize(false /*is_tablet_mode*/); views::Textfield* search_box = view_->app_list_main_view()->search_box_view()->search_box(); @@ -1899,7 +1975,7 @@ } // Tests that typing when in fullscreen changes the state to fullscreen search. -TEST_F(AppListViewTest, TypingFullscreenToFullscreenSearch) { +TEST_F(AppListViewPeekingTest, TypingFullscreenToFullscreenSearch) { Initialize(false /*is_tablet_mode*/); Show(); view_->SetState(ash::AppListViewState::kFullscreenAllApps); @@ -1931,7 +2007,7 @@ } // Tests that pressing escape when in peeking closes the app list. -TEST_F(AppListViewTest, EscapeKeyPeekingToClosed) { +TEST_F(AppListViewPeekingTest, EscapeKeyPeekingToClosed) { Initialize(false /*is_tablet_mode*/); Show(); @@ -1941,7 +2017,7 @@ } // Tests that pressing escape when in half screen changes the state to peeking. -TEST_F(AppListViewTest, EscapeKeyHalfToPeeking) { +TEST_F(AppListViewPeekingTest, EscapeKeyHalfToPeeking) { Initialize(false /*is_tablet_mode*/); Show(); @@ -1952,7 +2028,7 @@ } // Tests that pressing escape when in fullscreen changes the state to closed. -TEST_F(AppListViewTest, EscapeKeyFullscreenToClosed) { +TEST_F(AppListViewPeekingTest, EscapeKeyFullscreenToClosed) { Initialize(false /*is_tablet_mode*/); view_->SetState(ash::AppListViewState::kFullscreenAllApps); @@ -1963,20 +2039,20 @@ } // Tests that pressing escape when in fullscreen side-shelf closes the app list. -TEST_F(AppListViewTest, EscapeKeySideShelfFullscreenToClosed) { +TEST_F(AppListViewPeekingTest, EscapeKeySideShelfFullscreenToClosed) { // Put into fullscreen by using side-shelf. Initialize(false /*is_tablet_mode*/); - Show(); + Show(/*is_side_shelf=*/true); view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); ASSERT_EQ(1, delegate_->dismiss_count()); } // Tests that pressing escape when in tablet mode keeps app list in fullscreen. -TEST_F(AppListViewTest, EscapeKeyTabletModeStayFullscreen) { +TEST_P(AppListViewTabletTest, EscapeKeyTabletModeStayFullscreen) { // Put into fullscreen by using tablet mode. - Initialize(true /*is_tablet_mode*/); + Initialize(/*is_tablet_mode=*/true); Show(); view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); @@ -1985,7 +2061,7 @@ } // Tests that pressing escape when in fullscreen search changes to fullscreen. -TEST_F(AppListViewTest, EscapeKeyFullscreenSearchToFullscreen) { +TEST_F(AppListViewPeekingTest, EscapeKeyFullscreenSearchToFullscreen) { Initialize(false /*is_tablet_mode*/); Show(); view_->SetState(ash::AppListViewState::kFullscreenAllApps); @@ -1997,7 +2073,7 @@ } // Tests that pressing escape when in sideshelf search changes to fullscreen. -TEST_F(AppListViewTest, EscapeKeySideShelfSearchToFullscreen) { +TEST_F(AppListViewPeekingTest, EscapeKeySideShelfSearchToFullscreen) { // Put into fullscreen using side-shelf. Initialize(false /*is_tablet_mode*/); @@ -2010,7 +2086,7 @@ // Tests that in fullscreen, the app list has multiple pages with enough apps. TEST_F(AppListViewTest, PopulateAppsCreatesAnotherPage) { - Initialize(false /*is_tablet_mode*/); + Initialize(/*is_tablet_mode=*/true); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); @@ -2031,7 +2107,7 @@ } // Tests that opening in peeking mode sets the correct height. -TEST_P(AppListViewTest, OpenInPeekingCorrectHeight) { +TEST_F(AppListViewPeekingTest, OpenInPeekingCorrectHeight) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2040,8 +2116,8 @@ view_->GetCurrentAppListHeight()); } -// Tests that opening in peeking mode sets the correct height. -TEST_F(AppListViewTest, OpenInFullscreenCorrectHeight) { +// Tests that opening in fullscreen mode sets the correct height. +TEST_F(AppListViewPeekingTest, OpenInFullscreenCorrectHeight) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2052,7 +2128,7 @@ // Tests that AppListView::SetState succeeds when the state has been set to // CLOSED. -TEST_F(AppListViewTest, SetStateFailsWhenClosing) { +TEST_F(AppListViewPeekingTest, SetStateFailsWhenClosing) { Initialize(false /*is_tablet_mode*/); Show(); view_->SetState(ash::AppListViewState::kClosed); @@ -2062,7 +2138,7 @@ ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); } -TEST_F(AppListViewTest, AppsGridViewVisibilityOnReopening) { +TEST_F(AppListViewPeekingTest, AppsGridViewVisibilityOnReopening) { Initialize(false /*is_tablet_mode*/); Show(); view_->SetState(ash::AppListViewState::kFullscreenAllApps); @@ -2079,7 +2155,7 @@ EXPECT_TRUE(IsViewVisibleOnScreen(apps_grid_view())); } -TEST_F(AppListViewTest, AppsGridViewExpandHintingOnReopening) { +TEST_F(AppListViewPeekingTest, AppsGridViewExpandHintingOnReopening) { ui::ScopedAnimationDurationScaleMode non_zero_duration( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); Initialize(false /*is_tablet_mode*/); @@ -2101,7 +2177,7 @@ // Tests that going into a folder view, then setting the AppListState to PEEKING // hides the folder view. -TEST_F(AppListViewTest, FolderViewToPeeking) { +TEST_F(AppListViewPeekingTest, FolderViewToPeeking) { Initialize(false /*is_tablet_mode*/); AppListTestModel* model = delegate_->GetTestModel(); model->PopulateApps(kInitialItems); @@ -2129,8 +2205,8 @@ } // Tests that a tap or click in an empty region of the AppsGridView closes the -// AppList. -TEST_F(AppListViewTest, TapAndClickWithinAppsGridView) { +// AppList. ProductivityLauncher does not have this behavior. +TEST_F(AppListViewPeekingTest, TapAndClickWithinAppsGridView) { Initialize(false /*is_tablet_mode*/); // Populate the AppList with a small number of apps so there is an empty // region to click. @@ -2174,7 +2250,7 @@ } // Tests that search box should not become a rectangle during drag. -TEST_F(AppListViewTest, SearchBoxCornerRadiusDuringDragging) { +TEST_F(AppListViewPeekingTest, SearchBoxCornerRadiusDuringDragging) { base::HistogramTester histogram_tester; Initialize(false /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); @@ -2244,9 +2320,33 @@ } // Tests displaying the app list and performs a standard set of checks on its -// top level views. Then closes the window. -TEST_F(AppListViewTest, DisplayTest) { - Initialize(false /*is_tablet_mode*/); +// top level views. +TEST_F(AppListViewPeekingTest, DisplayTest) { + Initialize(/*is_tablet_mode=*/false); + EXPECT_EQ(-1, GetPaginationModel()->total_pages()); + delegate_->GetTestModel()->PopulateApps(kInitialItems); + + Show(); + + // |view_| bounds equal to the root window's size. + EXPECT_EQ("800x600", view_->bounds().size().ToString()); + + EXPECT_EQ(2, GetPaginationModel()->total_pages()); + EXPECT_EQ(0, GetPaginationModel()->selected_page()); + + // Checks on the main view. + AppListMainView* main_view = view_->app_list_main_view(); + EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); + EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view())); + + ash::AppListState expected = ash::AppListState::kStateApps; + EXPECT_TRUE(main_view->contents_view()->IsStateActive(expected)); + EXPECT_EQ(expected, delegate_->GetCurrentAppListPage()); +} + +// As above above, but tests tablet mode with and without ProductivityLauncher. +TEST_P(AppListViewTabletTest, DisplayTest) { + Initialize(/*is_tablet_mode=*/true); EXPECT_EQ(-1, GetPaginationModel()->total_pages()); delegate_->GetTestModel()->PopulateApps(kInitialItems); @@ -2269,11 +2369,12 @@ } // Tests switching rapidly between multiple pages of the launcher. +// TODO(https://crbug.com/1280300): Fix or skip for ProductivityLauncher. TEST_F(AppListViewTest, PageSwitchingAnimationTest) { ui::ScopedAnimationDurationScaleMode non_zero_duration( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); - Initialize(false /*is_tablet_mode*/); + Initialize(/*is_tablet_mode=*/false); Show(); AppListMainView* main_view = view_->app_list_main_view(); // Checks on the main view. @@ -2427,7 +2528,7 @@ } // Tests that a context menu can be shown between app icons in tablet mode. -TEST_F(AppListViewTest, ShowContextMenuBetweenAppsInTabletMode) { +TEST_P(AppListViewTabletTest, ShowContextMenuBetweenAppsInTabletMode) { Initialize(true /*is_tablet_mode*/); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); @@ -2458,7 +2559,7 @@ } // Tests that context menus are not shown between app icons in clamshell mode. -TEST_F(AppListViewTest, DontShowContextMenuBetweenAppsInClamshellMode) { +TEST_F(AppListViewPeekingTest, DontShowContextMenuBetweenAppsInClamshellMode) { Initialize(false /* disable tablet mode */); delegate_->GetTestModel()->PopulateApps(kInitialItems); Show(); @@ -2588,7 +2689,7 @@ // Tests that, in tablet mode, the current app list page doesn't immediately // reset to the initial page when app list is closed and re-opened. -TEST_F(AppListViewTest, PagePersistanceTabletModeTest) { +TEST_P(AppListViewTabletTest, PagePersistanceTabletModeTest) { Initialize(true /*is_tablet_mode*/); AppListTestModel* model = delegate_->GetTestModel(); @@ -2611,12 +2712,9 @@ } // Tests selecting search result to show embedded Assistant UI. -TEST_F(AppListViewFocusTest, ShowEmbeddedAssistantUI) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {app_list_features::kEnableAssistantSearch}, {}); - ASSERT_TRUE(app_list_features::IsAssistantSearchEnabled()); - +// TODO(https://crbug.com/1280300): Figure out if ProductivityLauncher needs a +// version of this test. ProductivityLauncherSearchView has its own test suite. +TEST_F(AppListViewPeekingFocusTest, ShowEmbeddedAssistantUI) { Show(); // Initially the search box is inactive, hitting Enter to activate it. @@ -2647,7 +2745,7 @@ // Tests that the correct contents is visible in the contents_view upon // reshowing. See b/142069648 for the details. -TEST_F(AppListViewTest, AppsGridVisibilityOnResetForShow) { +TEST_F(AppListViewPeekingTest, AppsGridVisibilityOnResetForShow) { Initialize(true /*is_tablet_mode*/); Show(); @@ -2686,7 +2784,7 @@ // Tests that pressing escape in embedded Assistant UI returns to peeking // if the Assistant UI was launched from half screen. -TEST_F(AppListViewTest, EscapeKeyInEmbeddedAssistantUIReturnsToPeeking) { +TEST_F(AppListViewPeekingTest, EscapeKeyInEmbeddedAssistantUIReturnsToPeeking) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2705,7 +2803,7 @@ // Tests that clicking empty region in AppListview when showing Assistant UI // should go back to peeking state. -TEST_F(AppListViewTest, ClickOutsideEmbeddedAssistantUIToPeeking) { +TEST_F(AppListViewPeekingTest, ClickOutsideEmbeddedAssistantUIToPeeking) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2734,7 +2832,8 @@ } // Tests that expand arrow is not visible when showing embedded Assistant UI. -TEST_F(AppListViewTest, ExpandArrowNotVisibleInEmbeddedAssistantUI) { +// ProductivityLauncher does not have an expand arrow. +TEST_F(AppListViewPeekingTest, ExpandArrowNotVisibleInEmbeddedAssistantUI) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2748,9 +2847,10 @@ contents_view()->expand_arrow_view()->layer()->GetTargetOpacity()); } -// Tests the expand arrow view opacity updtes correctly when transitioning -// between various app list view states. -TEST_F(AppListViewTest, ExpandArrowViewVisibilityTest) { +// Tests the expand arrow view opacity updates correctly when transitioning +// between various app list view states. ProductivityLauncher does not have an +// expand arrow. +TEST_F(AppListViewPeekingTest, ExpandArrowViewVisibilityTest) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2778,9 +2878,11 @@ ASSERT_EQ(contents_view()->expand_arrow_view()->layer()->opacity(), 1.0f); } -// Tests the expand arrow view opacity updtes correctly when transitioning +// Tests the expand arrow view opacity updates correctly when transitioning // between various app list view states with app list state animations enabled. -TEST_F(AppListViewTest, ExpandArrowViewVisibilityWithStateAnimationsTest) { +// ProductivityLauncher does not have an expand arrow. +TEST_F(AppListViewPeekingTest, + ExpandArrowViewVisibilityWithStateAnimationsTest) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2815,7 +2917,8 @@ } // Tests that search box is not visible when showing embedded Assistant UI. -TEST_F(AppListViewTest, SearchBoxViewNotVisibleInEmbeddedAssistantUI) { +// ProductivityLauncher has tests for this in AppListBubbleViewTest. +TEST_F(AppListViewPeekingTest, SearchBoxViewNotVisibleInEmbeddedAssistantUI) { Initialize(false /*is_tablet_mode*/); Show(); @@ -2828,8 +2931,8 @@ } // Tests that the expand arrow cannot be seen when opening the app list with -// side shelf enabled. -TEST_F(AppListViewTest, ExpandArrowNotVisibleWithSideShelf) { +// side shelf enabled. ProductivityLauncher does not have an expand arrow. +TEST_F(AppListViewPeekingTest, ExpandArrowNotVisibleWithSideShelf) { Initialize(false /*is_tablet_mode*/); Show(true /*is_side_shelf*/); @@ -3070,8 +3173,8 @@ } // Tests that page switching in folder doesn't record AppListPageSwitcherSource -// metric. -TEST_F(AppListViewFocusTest, PageSwitchingNotRecordingMetric) { +// metric. ProductivityLauncher does not use pages in folders. +TEST_F(AppListViewPeekingFocusTest, PageSwitchingNotRecordingMetric) { base::HistogramTester histogram_tester; Show(); @@ -3095,5 +3198,6 @@ histogram_tester.ExpectTotalCount("Apps.AppListPageSwitcherSource", 0); } +} // namespace } // namespace test } // namespace ash
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index 790b567..469574f 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -283,6 +283,7 @@ recent_apps_->layer()->SetFillsBoundsOpaquely(false); separator_ = AddChildView(std::make_unique<views::Separator>()); + DCHECK(ColorProvider::Get()); separator_->SetColor(ColorProvider::Get()->GetContentLayerColor( ColorProvider::ContentLayerType::kSeparatorColor)); separator_->SetPreferredSize( @@ -1307,6 +1308,12 @@ suggestion_chip_container_view_->DisableFocusForShowingActiveFolder( disabled); } + if (auto* recent_apps = GetRecentApps(); recent_apps) { + recent_apps->DisableFocusForShowingActiveFolder(disabled); + } + if (auto* continue_section = GetContinueSection(); continue_section) { + continue_section->DisableFocusForShowingActiveFolder(disabled); + } apps_grid_view_->DisableFocusForShowingActiveFolder(disabled); // Ignore the page switcher in accessibility tree so that buttons inside it
diff --git a/ash/app_list/views/apps_grid_view_test_api.cc b/ash/app_list/views/apps_grid_view_test_api.cc index 27b6ca62..dc1ac92 100644 --- a/ash/app_list/views/apps_grid_view_test_api.cc +++ b/ash/app_list/views/apps_grid_view_test_api.cc
@@ -130,6 +130,18 @@ waiter.Wait(); } +void AppsGridViewTestApi::FireReorderTimerAndWaitForAnimationDone() { + base::OneShotTimer* timer = &view_->reorder_timer_; + if (timer->IsRunning()) + timer->FireNow(); + + WaitForItemMoveAnimationDone(); +} + +void AppsGridViewTestApi::FireFolderItemReparentTimer() { + view_->FireFolderItemReparentTimerForTest(); +} + gfx::Rect AppsGridViewTestApi::GetDragIconBoundsInAppsGridView() { if (!view_->drag_icon_proxy_) return gfx::Rect();
diff --git a/ash/app_list/views/apps_grid_view_test_api.h b/ash/app_list/views/apps_grid_view_test_api.h index c28b94a..bdd5aa6 100644 --- a/ash/app_list/views/apps_grid_view_test_api.h +++ b/ash/app_list/views/apps_grid_view_test_api.h
@@ -62,6 +62,13 @@ void WaitForItemMoveAnimationDone(); + // Fires the reordering timer if the timer is running. Then waits for the + // reordering animation to complete. + void FireReorderTimerAndWaitForAnimationDone(); + + // Fires the timer for reparenting items from a folder apps grid. + void FireFolderItemReparentTimer(); + void Update() { view_->Update(); } // Returns the drag icon proxy view's bounds in the apps grid coordinates.
diff --git a/ash/app_list/views/assistant/assistant_test_api_impl.cc b/ash/app_list/views/assistant/assistant_test_api_impl.cc index 310f3287..1e20643 100644 --- a/ash/app_list/views/assistant/assistant_test_api_impl.cc +++ b/ash/app_list/views/assistant/assistant_test_api_impl.cc
@@ -57,9 +57,8 @@ bool AssistantTestApiImpl::IsVisible() { if (!TabletMode::Get()->InTabletMode() && features::IsProductivityLauncherEnabled()) { - auto* bubble_view = GetAppListBubbleView(); - // `bubble_view` is null when the bubble launcher is closed. - return bubble_view && bubble_view->assistant_page_->GetVisible(); + return Shell::Get()->app_list_controller()->IsVisible() && + GetAppListBubbleView()->assistant_page_->GetVisible(); } return AppListViewsHaveBeenCreated() && page_view()->GetVisible(); }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index db4df1c..3939c2d 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -3830,9 +3830,6 @@ <message name="IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE" desc="The text of the notification that informs the user the screen recording is blocked due to existence of protected content."> Screen recording is not allowed when protected content is visible </message> - <message name="IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_TITLE" desc="The title of the notification when capture mode is disabled because of confidential content."> - Can't capture confidential content - </message> <message name="IDS_ASH_SCREEN_CAPTURE_POLICY_DISABLED_TITLE" desc="The title of the notification when capture mode is disabled because of a policy."> Can't capture content </message> @@ -3842,9 +3839,6 @@ <message name="IDS_ASH_SCREEN_CAPTURE_HDCP_STOPPED_TITLE" desc="The title of the notification when video capture is stopped due to protected content showing up on the screen."> Can't record protected content </message> - <message name="IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_MESSAGE" desc="The text of the notification when capture mode is disabled because of confidential content."> - Administrator policy disables screen capture when confidential content is visible - </message> <message name="IDS_ASH_SCREEN_CAPTURE_POLICY_DISABLED_MESSAGE" desc="The text of the notification when capture mode is disabled because of a policy."> Administrator policy disables screen capture </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_MESSAGE.png.sha1 deleted file mode 100644 index 39f59ed..0000000 --- a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_MESSAGE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -45fb7abc98866005fd68b8b4c2a888572c992442 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_TITLE.png.sha1 deleted file mode 100644 index 39f59ed..0000000 --- a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -45fb7abc98866005fd68b8b4c2a888572c992442 \ No newline at end of file
diff --git a/ash/assistant/assistant_controller_impl_unittest.cc b/ash/assistant/assistant_controller_impl_unittest.cc index 9fac96b..77fc516a 100644 --- a/ash/assistant/assistant_controller_impl_unittest.cc +++ b/ash/assistant/assistant_controller_impl_unittest.cc
@@ -247,6 +247,10 @@ TEST_F(AssistantControllerImplTest, ColorModeIsSetWhenAssistantIsReadyFlagOff) { ASSERT_FALSE(chromeos::features::IsDarkLightModeEnabled()); + // ProductivityLauncher uses DarkLightMode colors. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kProductivityLauncher); + controller()->SetAssistant(test_assistant_service()); ASSERT_TRUE(test_assistant_service()->dark_mode_enabled().has_value());
diff --git a/ash/assistant/assistant_ui_controller_impl.cc b/ash/assistant/assistant_ui_controller_impl.cc index 3533b3a..058817d 100644 --- a/ash/assistant/assistant_ui_controller_impl.cc +++ b/ash/assistant/assistant_ui_controller_impl.cc
@@ -44,15 +44,12 @@ // Toast ----------------------------------------------------------------------- -constexpr int kToastDurationMs = 2500; - constexpr char kStylusPromptToastId[] = "stylus_prompt_for_embedded_ui"; constexpr char kUnboundServiceToastId[] = "assistant_controller_unbound_service"; void ShowToast(const std::string& id, int message_id) { - ToastData toast(id, l10n_util::GetStringUTF16(message_id), kToastDurationMs, - absl::nullopt); + ToastData toast(id, l10n_util::GetStringUTF16(message_id)); Shell::Get()->toast_manager()->Show(toast); }
diff --git a/ash/assistant/ui/colors/assistant_colors_util_unittest.cc b/ash/assistant/ui/colors/assistant_colors_util_unittest.cc index e7f4858..6c96bc0 100644 --- a/ash/assistant/ui/colors/assistant_colors_util_unittest.cc +++ b/ash/assistant/ui/colors/assistant_colors_util_unittest.cc
@@ -45,6 +45,10 @@ TEST_F(AssistantColorsUtilUnittest, AssistantColorFlagOff) { ASSERT_FALSE(chromeos::features::IsDarkLightModeEnabled()); + // ProductivityLauncher uses DarkLightMode colors. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kProductivityLauncher); + EXPECT_EQ( ResolveAssistantColor(assistant_colors::ColorName::kBgAssistantPlate), SK_ColorWHITE); @@ -58,6 +62,10 @@ TEST_F(AssistantColorsUtilUnittest, AssistantColorFlagOffFallback) { ASSERT_FALSE(chromeos::features::IsDarkLightModeEnabled()); + // ProductivityLauncher uses DarkLightMode colors. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kProductivityLauncher); + EXPECT_EQ(ResolveAssistantColor(assistant_colors::ColorName::kGoogleBlue100), assistant_colors::ResolveColor( assistant_colors::ColorName::kGoogleBlue100,
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 350f558..64ea460 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -261,9 +261,6 @@ case CaptureAllowance::kDisallowedByPolicy: return for_title ? IDS_ASH_SCREEN_CAPTURE_POLICY_DISABLED_TITLE : IDS_ASH_SCREEN_CAPTURE_POLICY_DISABLED_MESSAGE; - case CaptureAllowance::kDisallowedByDlp: - return for_title ? IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_TITLE - : IDS_ASH_SCREEN_CAPTURE_DLP_DISABLED_MESSAGE; case CaptureAllowance::kDisallowedByHdcp: return for_title ? IDS_ASH_SCREEN_CAPTURE_HDCP_STOPPED_TITLE : IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE; @@ -980,15 +977,6 @@ FinalizeRecording(/*success=*/false, gfx::ImageSkia()); } -CaptureAllowance CaptureModeController::IsCaptureAllowedByEnterprisePolicies( - const CaptureParams& capture_params) const { - if (!delegate_->IsCaptureAllowedByPolicy()) { - return CaptureAllowance::kDisallowedByPolicy; - } - - return CaptureAllowance::kAllowed; -} - void CaptureModeController::FinalizeRecording(bool success, const gfx::ImageSkia& thumbnail) { // If |success| is false, then recording has been force-terminated due to a @@ -1032,8 +1020,7 @@ // Note that |type_| may not necessarily be |kImage| here, since this may be // called to take an instant fullscreen screenshot for the keyboard shortcut, // which doesn't go through the capture mode UI, and doesn't change |type_|. - DCHECK_EQ(CaptureAllowance::kAllowed, - IsCaptureAllowedByEnterprisePolicies(capture_params)); + DCHECK(delegate_->IsCaptureAllowedByPolicy()); // Stop the capture session now, so as not to take a screenshot of the capture // bar. @@ -1067,8 +1054,7 @@ void CaptureModeController::CaptureVideo(const CaptureParams& capture_params) { DCHECK_EQ(CaptureModeType::kVideo, type_); - DCHECK_EQ(CaptureAllowance::kAllowed, - IsCaptureAllowedByEnterprisePolicies(capture_params)); + DCHECK(delegate_->IsCaptureAllowedByPolicy()); if (skip_count_down_ui_) { OnVideoRecordCountDownFinished();
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 7f86f8b..7f7fbe8 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -285,12 +285,6 @@ // Called back when the mojo pipe to the recording service gets disconnected. void OnRecordingServiceDisconnected(); - // Returns whether doing a screen capture is currently allowed by enterprise - // policies and a reason otherwise. - // ShouldBlockRecordingForContentProtection() should be used for HDCP checks. - CaptureAllowance IsCaptureAllowedByEnterprisePolicies( - const CaptureParams& capture_params) const; - // Terminates the recording service process, closes any recording-related UI // elements (only if |success| is false as this indicates that recording was // not ended normally by calling EndVideoRecording()), and shows the video
diff --git a/ash/capture_mode/capture_mode_types.h b/ash/capture_mode/capture_mode_types.h index 6415f08..3fda37b 100644 --- a/ash/capture_mode/capture_mode_types.h +++ b/ash/capture_mode/capture_mode_types.h
@@ -24,8 +24,6 @@ enum class CaptureAllowance { // Capture mode is allowed. kAllowed, - // Capture mode is blocked due to admin-enforced Data Leak Prevention policy. - kDisallowedByDlp, // Capture mode is blocked due to admin-enforced device policy. kDisallowedByPolicy, // Video recording is blocked due to app- or content- enforced content
diff --git a/ash/components/arc/compat_mode/metrics.cc b/ash/components/arc/compat_mode/metrics.cc index 4dbfa18..97ca6ce 100644 --- a/ash/components/arc/compat_mode/metrics.cc +++ b/ash/components/arc/compat_mode/metrics.cc
@@ -41,6 +41,11 @@ base::UmaHistogramEnumeration(GetStateHistogramName(type), state); } +void RecordRightClickConversionResultHistogram( + RightClickConversionResultHistogramResult result) { + base::UmaHistogramEnumeration("Arc.CompatMode.RightClickConversion", result); +} + const char* GetResizeLockActionNameForTesting( // IN-TEST ResizeLockActionType type) { return GetActionName(type);
diff --git a/ash/components/arc/compat_mode/metrics.h b/ash/components/arc/compat_mode/metrics.h index ca13794..18329fa 100644 --- a/ash/components/arc/compat_mode/metrics.h +++ b/ash/components/arc/compat_mode/metrics.h
@@ -20,11 +20,23 @@ InitialState, }; +// The assigned values cannot be renumbered or reordered because it's used for +// enum histogram. +enum class RightClickConversionResultHistogramResult { + kDisabled = 0, + kConverted = 1, + kNotConverted = 2, + kMaxValue = kNotConverted, +}; + void RecordResizeLockAction(ResizeLockActionType type); void RecordResizeLockStateHistogram(ResizeLockStateHistogramType type, mojom::ArcResizeLockState state); +void RecordRightClickConversionResultHistogram( + RightClickConversionResultHistogramResult result); + const char* GetResizeLockActionNameForTesting(ResizeLockActionType type); const char* GetResizeLockStateHistogramNameForTesting( ResizeLockStateHistogramType type);
diff --git a/ash/components/arc/compat_mode/resize_util.cc b/ash/components/arc/compat_mode/resize_util.cc index b39ff627..ba6c140 100644 --- a/ash/components/arc/compat_mode/resize_util.cc +++ b/ash/components/arc/compat_mode/resize_util.cc
@@ -116,14 +116,10 @@ constexpr char kTurnOffResizeLockToastId[] = "arc.compat_mode.turn_off_resize_lock"; - constexpr int kToastDurationMs = 3500; toast_manager->Cancel(kTurnOffResizeLockToastId); ash::ToastData toast( kTurnOffResizeLockToastId, - l10n_util::GetStringUTF16(IDS_ARC_COMPAT_MODE_DISABLE_RESIZE_LOCK_TOAST), - kToastDurationMs, - /*dismiss_text=*/absl::nullopt, - /*visible_on_lock_screen=*/false); + l10n_util::GetStringUTF16(IDS_ARC_COMPAT_MODE_DISABLE_RESIZE_LOCK_TOAST)); toast_manager->Show(toast); }
diff --git a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc index dc585b11..12c413a7 100644 --- a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc +++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc
@@ -5,6 +5,7 @@ #include "ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ash/components/arc/arc_features.h" +#include "ash/components/arc/compat_mode/metrics.h" #include "ash/shell.h" #include "base/bind.h" #include "base/ignore_result.h" @@ -110,12 +111,20 @@ const ui::MouseEvent& mouse_event = *event.AsMouseEvent(); if (mouse_event.IsRightMouseButton() || mouse_event.IsLeftMouseButton()) { - if (!base::FeatureList::IsEnabled(arc::kRightClickLongPress)) + if (!base::FeatureList::IsEnabled(arc::kRightClickLongPress)) { + RecordRightClickConversionResultHistogram( + RightClickConversionResultHistogramResult::kDisabled); return SendEvent(continuation, &event); + } - if (!in_resize_locked) + if (!in_resize_locked) { + RecordRightClickConversionResultHistogram( + RightClickConversionResultHistogramResult::kNotConverted); return SendEvent(continuation, &event); + } + RecordRightClickConversionResultHistogram( + RightClickConversionResultHistogramResult::kConverted); return RewriteMouseClickEvent(mouse_event, continuation); }
diff --git a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc index 01ad069..fae80a3b 100644 --- a/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc +++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc
@@ -5,7 +5,9 @@ #include "ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ash/components/arc/arc_features.h" +#include "ash/components/arc/compat_mode/metrics.h" #include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "ui/events/test/event_generator.h" #include "ui/views/test/views_test_base.h" @@ -90,6 +92,7 @@ } base::test::ScopedFeatureList feature_list_; + base::HistogramTester histogram_tester; }; TEST_F(TouchModeMouseRewriterTest, RightClickConvertedToLongPress) { @@ -111,6 +114,10 @@ EXPECT_TRUE(view->left_pressed()); EXPECT_FALSE(view->right_pressed()); + histogram_tester.ExpectUniqueSample( + "Arc.CompatMode.RightClickConversion", + RightClickConversionResultHistogramResult::kConverted, 1); + // Immediately release the right button. It will not generate any event. generator.ReleaseRightButton(); EXPECT_TRUE(view->left_pressed()); @@ -124,6 +131,71 @@ touch_mode_mouse_rewriter.DisableForWindow(widget->GetNativeWindow()); } +TEST_F(TouchModeMouseRewriterTest, FeatureIsDisabled) { + // Disable kRightClickLongPress + feature_list_.Reset(); + feature_list_.InitWithFeatures({}, {arc::kRightClickLongPress}); + + std::unique_ptr<views::Widget> widget = + CreateTestWidget(views::Widget::InitParams::TYPE_CONTROL); + LongPressReceiverView* view = + widget->SetContentsView(std::make_unique<LongPressReceiverView>()); + widget->Show(); + + TouchModeMouseRewriter touch_mode_mouse_rewriter; + touch_mode_mouse_rewriter.EnableForWindow(widget->GetNativeWindow()); + ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); + EXPECT_FALSE(view->left_pressed()); + EXPECT_FALSE(view->right_pressed()); + + // Press the right button. + generator.PressRightButton(); + EXPECT_TRUE(view->right_pressed()); + + histogram_tester.ExpectUniqueSample( + "Arc.CompatMode.RightClickConversion", + RightClickConversionResultHistogramResult::kDisabled, 1); + + // Immediately release the right button. + generator.ReleaseRightButton(); + EXPECT_FALSE(view->right_pressed()); + + touch_mode_mouse_rewriter.DisableForWindow(widget->GetNativeWindow()); +} + +TEST_F(TouchModeMouseRewriterTest, DisabledForWindow) { + std::unique_ptr<views::Widget> widget = + CreateTestWidget(views::Widget::InitParams::TYPE_CONTROL); + LongPressReceiverView* view = + widget->SetContentsView(std::make_unique<LongPressReceiverView>()); + widget->Show(); + + TouchModeMouseRewriter touch_mode_mouse_rewriter; + touch_mode_mouse_rewriter.EnableForWindow(widget->GetNativeWindow()); + + std::unique_ptr<views::Widget> widget2 = + CreateTestWidget(views::Widget::InitParams::TYPE_CONTROL); + LongPressReceiverView* view2 = + widget2->SetContentsView(std::make_unique<LongPressReceiverView>()); + widget2->Show(); + // Not enabled for the widget2. + ui::test::EventGenerator generator(GetContext(), widget2->GetNativeWindow()); + EXPECT_FALSE(view->left_pressed()); + EXPECT_FALSE(view->right_pressed()); + + // Press the right button. + generator.PressRightButton(); + EXPECT_TRUE(view2->right_pressed()); + + histogram_tester.ExpectUniqueSample( + "Arc.CompatMode.RightClickConversion", + RightClickConversionResultHistogramResult::kNotConverted, 1); + + // Immediately release the right button. + generator.ReleaseRightButton(); + EXPECT_FALSE(view2->right_pressed()); +} + TEST_F(TouchModeMouseRewriterTest, LeftPressedBeforeRightClick) { std::unique_ptr<views::Widget> widget = CreateTestWidget(views::Widget::InitParams::TYPE_CONTROL);
diff --git a/ash/components/arc/session/arc_session_impl.cc b/ash/components/arc/session/arc_session_impl.cc index f0e4640..3128d1e 100644 --- a/ash/components/arc/session/arc_session_impl.cc +++ b/ash/components/arc/session/arc_session_impl.cc
@@ -730,7 +730,7 @@ case State::WAITING_FOR_NUM_CORES: if (scheduler_configuration_manager_) // for testing scheduler_configuration_manager_->RemoveObserver(this); - FALLTHROUGH; + [[fallthrough]]; case State::NOT_STARTED: // If |Stop()| is called while waiting for LCD density or CPU cores // information, it can directly move to stopped state.
diff --git a/ash/components/fwupd/BUILD.gn b/ash/components/fwupd/BUILD.gn index 396d1440..d6c6f1c 100644 --- a/ash/components/fwupd/BUILD.gn +++ b/ash/components/fwupd/BUILD.gn
@@ -10,6 +10,7 @@ defines = [ "IS_ASH_FIRMWARE_UPDATE_MANAGER_IMPL" ] deps = [ + "//ash/public/cpp", "//ash/public/mojom", "//ash/webui/firmware_update_ui/mojom", "//base:base", @@ -29,14 +30,21 @@ deps = [ ":fwupd", "//ash/constants", + "//ash/public/cpp", "//ash/public/mojom", "//ash/webui/firmware_update_ui/mojom", "//base/test:test_support", "//chromeos/dbus/fwupd", "//dbus:test_support", + "//services/network:test_support", + "//services/network/public/cpp", "//testing/gmock", "//testing/gtest", ] - sources = [ "firmware_update_manager_unittest.cc" ] + sources = [ + "fake_fwupd_download_client.cc", + "fake_fwupd_download_client.h", + "firmware_update_manager_unittest.cc", + ] }
diff --git a/ash/components/fwupd/fake_fwupd_download_client.cc b/ash/components/fwupd/fake_fwupd_download_client.cc new file mode 100644 index 0000000..6649b59 --- /dev/null +++ b/ash/components/fwupd/fake_fwupd_download_client.cc
@@ -0,0 +1,81 @@ +// 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/components/fwupd/fake_fwupd_download_client.h" + +#include <memory> +#include <utility> + +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" + +namespace { + +class FakeSharedURLLoaderFactory : public network::SharedURLLoaderFactory { + public: + FakeSharedURLLoaderFactory() = default; + FakeSharedURLLoaderFactory(const FakeSharedURLLoaderFactory&) = delete; + FakeSharedURLLoaderFactory& operator=(const FakeSharedURLLoaderFactory&) = + delete; + + // network::mojom::URLLoaderFactory implementation: + void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) + override { + test_url_loader_factory_.Clone(std::move(receiver)); + } + + void CreateLoaderAndStart( + mojo::PendingReceiver<network::mojom::URLLoader> loader, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + mojo::PendingRemote<network::mojom::URLLoaderClient> client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) + override { + test_url_loader_factory_.CreateLoaderAndStart( + std::move(loader), request_id, options, request, std::move(client), + traffic_annotation); + } + + // network::SharedURLLoaderFactory implementation: + std::unique_ptr<network::PendingSharedURLLoaderFactory> Clone() override { + NOTREACHED(); + return nullptr; + } + + network::TestURLLoaderFactory& test_url_loader_factory() { + return test_url_loader_factory_; + } + + private: + friend class base::RefCounted<FakeSharedURLLoaderFactory>; + + ~FakeSharedURLLoaderFactory() override = default; + + network::TestURLLoaderFactory test_url_loader_factory_; +}; + +} // namespace + +namespace ash { + +FakeFwupdDownloadClient::FakeFwupdDownloadClient() + : url_loader_factory_(base::MakeRefCounted<FakeSharedURLLoaderFactory>()) {} +FakeFwupdDownloadClient::~FakeFwupdDownloadClient() = default; + +scoped_refptr<network::SharedURLLoaderFactory> +FakeFwupdDownloadClient::GetURLLoaderFactory() { + return url_loader_factory_; +} + +network::TestURLLoaderFactory& +FakeFwupdDownloadClient::test_url_loader_factory() { + return static_cast<FakeSharedURLLoaderFactory*>(url_loader_factory_.get()) + ->test_url_loader_factory(); +} + +} // namespace ash \ No newline at end of file
diff --git a/ash/components/fwupd/fake_fwupd_download_client.h b/ash/components/fwupd/fake_fwupd_download_client.h new file mode 100644 index 0000000..3f47de20 --- /dev/null +++ b/ash/components/fwupd/fake_fwupd_download_client.h
@@ -0,0 +1,38 @@ +// 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_COMPONENTS_FWUPD_FAKE_FWUPD_DOWNLOAD_CLIENT_H_ +#define ASH_COMPONENTS_FWUPD_FAKE_FWUPD_DOWNLOAD_CLIENT_H_ + +#include "ash/public/cpp/fwupd_download_client.h" +#include "base/component_export.h" +#include "services/network/test/test_url_loader_factory.h" + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace ash { + +// A fake implementation of FwupdDownloadClient used for testing. +class COMPONENT_EXPORT(ASH_FIRMWARE_UPDATE_MANAGER) FakeFwupdDownloadClient + : public ash::FwupdDownloadClient { + public: + FakeFwupdDownloadClient(); + FakeFwupdDownloadClient(const FwupdDownloadClient&) = delete; + FakeFwupdDownloadClient& operator=(const FwupdDownloadClient&) = delete; + ~FakeFwupdDownloadClient() override; + + // ash::FwupdDownloadClient: + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; + + network::TestURLLoaderFactory& test_url_loader_factory(); + + private: + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; +}; + +} // namespace ash + +#endif // ASH_COMPONENTS_FWUPD_FAKE_FWUPD_DOWNLOAD_CLIENT_H_
diff --git a/ash/components/fwupd/firmware_update_manager.cc b/ash/components/fwupd/firmware_update_manager.cc index 290e99f..a6e4d93a6 100644 --- a/ash/components/fwupd/firmware_update_manager.cc +++ b/ash/components/fwupd/firmware_update_manager.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "ash/public/cpp/fwupd_download_client.h" #include "ash/webui/firmware_update_ui/mojom/firmware_update.mojom.h" #include "base/base_paths.h" #include "base/check_op.h" @@ -24,6 +25,13 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" +#include "net/traffic_annotation/network_traffic_annotation.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/fetch_api.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" +#include "url/gurl.h" namespace ash { @@ -32,6 +40,12 @@ const char kBaseRootPath[] = "firmware-updates"; const char kCachePath[] = "cache"; const char kCabFileExtension[] = ".cab"; +const char kFirmwareMirrorPrefix[] = + "https://storage.googleapis.com/chromeos-localmirror/lvfs/"; + +const char kSampleFirmwareUpgrade[] = + "c15a0df7386812781d1f376fe54729e64f69b2a8a6c4b580914d4f6740e4fcc3-HP-USBC_" + "DOCK_G5-V1.0.13.0.cab"; FirmwareUpdateManager* g_instance = nullptr; @@ -70,6 +84,47 @@ return update; } +constexpr net::NetworkTrafficAnnotationTag kFwupdFirmwareUpdateNetworkTag = + net::DefineNetworkTrafficAnnotation("fwupd_firmware_update", R"( + semantics { + sender: "FWUPD firmware update" + description: + "Get the firmware update patch file from url and store it in the " + "the device cache. This is used to update a specific peripheral's " + "firmware." + + trigger: + "Triggered by the user when they explicitly use the Firmware Update" + " UI to update their peripheral." + data: "None." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "This feature is used when the user updates their firmware." + policy_exception_justification: + "This request is made based on the user decision to update " + "firmware." + })"); + +std::unique_ptr<network::SimpleURLLoader> CreateSimpleURLLoader(GURL url) { + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = url; + resource_request->method = "GET"; + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + + return network::SimpleURLLoader::Create(std::move(resource_request), + kFwupdFirmwareUpdateNetworkTag); +} + +int GetResponseCode(network::SimpleURLLoader* simple_loader) { + if (simple_loader->ResponseInfo() && simple_loader->ResponseInfo()->headers) + return simple_loader->ResponseInfo()->headers->response_code(); + else + return -1; +} + } // namespace FirmwareUpdateManager::FirmwareUpdateManager() @@ -141,7 +196,7 @@ .Append(FILE_PATH_LITERAL(kCachePath)); base::OnceClosure dir_created_callback = - base::BindOnce(&FirmwareUpdateManager::OnCacheDirectoryCreated, + base::BindOnce(&FirmwareUpdateManager::CreateLocalPatchFile, weak_ptr_factory_.GetWeakPtr(), cache_path, device_id, release, std::move(callback)); @@ -151,14 +206,14 @@ [](const base::FilePath& path) { if (!CreateDirIfNotExists(path)) { LOG(ERROR) << "Cannot create firmware update directory, " - << " may be created already."; + << "may be created already."; } }, cache_path), std::move(dir_created_callback)); } -void FirmwareUpdateManager::OnCacheDirectoryCreated( +void FirmwareUpdateManager::CreateLocalPatchFile( const base::FilePath& cache_path, const std::string& device_id, int release, @@ -166,6 +221,71 @@ const base::FilePath patch_path = cache_path.Append(GetFilenameFromDevice(device_id, release)); + // Create the patch file. + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce( + [](const base::FilePath& patch_path) { + // TODO(michaelcheco): Verify that creating the empty file is + // necessary. + const bool write_file_success = + base::WriteFile(patch_path, /*data=*/""); + if (!write_file_success) { + LOG(ERROR) << "Writing into the file: " << patch_path + << " failed."; + } + return write_file_success; + }, + patch_path), + base::BindOnce(&FirmwareUpdateManager::DownloadFileToInternal, + weak_ptr_factory_.GetWeakPtr(), patch_path, device_id, + std::move(callback))); +} + +void FirmwareUpdateManager::DownloadFileToInternal( + const base::FilePath& patch_path, + const std::string& device_id, + base::OnceCallback<void()> callback, + bool write_file_success) { + if (!write_file_success) { + return; + } + const std::string url = + std::string(kFirmwareMirrorPrefix) + std::string(kSampleFirmwareUpgrade); + GURL download_url(fake_url_for_testing_.empty() ? url + : fake_url_for_testing_); + + std::unique_ptr<network::SimpleURLLoader> simple_loader = + CreateSimpleURLLoader(download_url); + DCHECK(FwupdDownloadClient::Get()); + + scoped_refptr<network::SharedURLLoaderFactory> loader_factory = + FwupdDownloadClient::Get()->GetURLLoaderFactory(); + // Save the pointer before moving `simple_loader` in the following call to + // `DownloadToFile()`. + auto* loader_ptr = simple_loader.get(); + + loader_ptr->DownloadToFile( + loader_factory.get(), + base::BindOnce(&FirmwareUpdateManager::OnUrlDownloadedToFile, + weak_ptr_factory_.GetWeakPtr(), device_id, + std::move(simple_loader), std::move(callback)), + patch_path); +} + +void FirmwareUpdateManager::OnUrlDownloadedToFile( + const std::string& device_id, + std::unique_ptr<network::SimpleURLLoader> simple_loader, + base::OnceCallback<void()> callback, + base::FilePath download_path) { + if (simple_loader->NetError() != net::OK) { + LOG(ERROR) << "Downloading to file failed with error code: " + << GetResponseCode(simple_loader.get()) << " with network error " + << simple_loader->NetError(); + std::move(callback).Run(); + return; + } + // TODO(jimmyxgong): Determine if this options map can be static or will need // to remain dynamic. // Fwupd Install Dbus flags, flag documentation can be found in @@ -176,7 +296,7 @@ {"allow-reinstall", true}}; task_runner_->PostTaskAndReplyWithResult( - FROM_HERE, base::BindOnce(&OpenFileAndGetFileDescriptor, patch_path), + FROM_HERE, base::BindOnce(&OpenFileAndGetFileDescriptor, download_path), base::BindOnce(&FirmwareUpdateManager::InstallUpdate, weak_ptr_factory_.GetWeakPtr(), device_id, std::move(options), std::move(callback)));
diff --git a/ash/components/fwupd/firmware_update_manager.h b/ash/components/fwupd/firmware_update_manager.h index 55165a1..9c397e50 100644 --- a/ash/components/fwupd/firmware_update_manager.h +++ b/ash/components/fwupd/firmware_update_manager.h
@@ -23,6 +23,12 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" +namespace network { + +class SimpleURLLoader; + +} // namespace network + namespace ash { // FirmwareUpdateManager contains all logic that runs the firmware update SWA. class COMPONENT_EXPORT(ASH_FIRMWARE_UPDATE_MANAGER) FirmwareUpdateManager @@ -92,10 +98,21 @@ base::OnceCallback<void()> callback, base::ScopedFD file_descriptor); - void OnCacheDirectoryCreated(const base::FilePath& root_path, - const std::string& device_id, - int release, - base::OnceCallback<void()> callback); + void CreateLocalPatchFile(const base::FilePath& cache_path, + const std::string& device_id, + int release, + base::OnceCallback<void()> callback); + + void DownloadFileToInternal(const base::FilePath& patch_path, + const std::string& device_id, + base::OnceCallback<void()> callback, + bool write_file_success); + + void OnUrlDownloadedToFile( + const std::string& device_id, + std::unique_ptr<network::SimpleURLLoader> simple_loader, + base::OnceCallback<void()> callback, + base::FilePath download_path); // Notifies observers registered with ObservePeripheralUpdates() the current // list of devices with pending updates (if any). @@ -103,6 +120,10 @@ bool HasPendingUpdates(); + void SetFakeUrlForTesting(const std::string& fake_url) { + fake_url_for_testing_ = fake_url; + } + // Map of a device ID to `FwupdDevice` which is waiting for the list // of updates. base::flat_map<std::string, chromeos::FwupdDevice> devices_pending_update_; @@ -111,6 +132,9 @@ // empty then this list is not yet complete. std::vector<firmware_update::mojom::FirmwareUpdatePtr> updates_; + // Only used for testing if StartInstall() queries to a fake URL. + std::string fake_url_for_testing_; + // Remotes for tracking observers that will be notified of changes to the // list of firmware updates. mojo::RemoteSet<firmware_update::mojom::UpdateObserver>
diff --git a/ash/components/fwupd/firmware_update_manager_unittest.cc b/ash/components/fwupd/firmware_update_manager_unittest.cc index f4b4a15c..bad84e5 100644 --- a/ash/components/fwupd/firmware_update_manager_unittest.cc +++ b/ash/components/fwupd/firmware_update_manager_unittest.cc
@@ -9,6 +9,7 @@ #include <memory> #include <string> +#include "ash/components/fwupd/fake_fwupd_download_client.h" #include "ash/constants/ash_features.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -23,6 +24,8 @@ #include "dbus/mock_object_proxy.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "services/network/public/cpp/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" @@ -105,6 +108,7 @@ dbus_client_ = FwupdClient::Create(); dbus_client_->InitForTesting(bus_.get()); + fake_fwupd_download_client_ = std::make_unique<FakeFwupdDownloadClient>(); firmware_update_manager_ = std::make_unique<FirmwareUpdateManager>(); } FirmwareUpdateManagerTest(const FirmwareUpdateManagerTest&) = delete; @@ -133,6 +137,10 @@ loop.Run(); } + void SetFakeUrlForTesting(const std::string& fake_url) { + firmware_update_manager_->SetFakeUrlForTesting(fake_url); + } + std::unique_ptr<dbus::Response> CreateEmptyDeviceResponse() { auto response = dbus::Response::CreateEmpty(); @@ -297,8 +305,13 @@ base::RunLoop().RunUntilIdle(); } + network::TestURLLoaderFactory& GetTestUrlLoaderFactory() { + return fake_fwupd_download_client_->test_url_loader_factory(); + } + // `FwupdClient` must be be before `FirmwareUpdateManager`. std::unique_ptr<FwupdClient> dbus_client_; + std::unique_ptr<FakeFwupdDownloadClient> fake_fwupd_download_client_; std::unique_ptr<FirmwareUpdateManager> firmware_update_manager_; // Mock bus for simulating calls. @@ -407,25 +420,27 @@ dbus_responses_.push_back(dbus::Response::CreateEmpty()); - base::FilePath root_dir; - CHECK(base::PathService::Get(base::DIR_TEMP, &root_dir)); - const base::FilePath root_path = - root_dir.Append(FILE_PATH_LITERAL(kDownloadDir)) - .Append(FILE_PATH_LITERAL(kCacheDir)); - - const std::string test_filename = - std::string(kFakeDeviceIdForTesting) + std::string(kCabExtension); - base::FilePath full_path = root_path.Append(test_filename); - // Create a temporary file to simulate a .cab available for install. - base::WriteFile(full_path, "", 0); - EXPECT_TRUE(base::PathExists(full_path)); - base::RunLoop().RunUntilIdle(); + std::string fake_url = "https://faketesturl/"; + std::unique_ptr<FirmwareUpdateManager> firmware_update_manager_; + SetFakeUrlForTesting(fake_url); + GetTestUrlLoaderFactory().AddResponse(fake_url, ""); EXPECT_EQ(0, GetOnInstallResponseCallbackCallCountForTesting()); StartInstall(std::string(kFakeDeviceIdForTesting), /*release=*/0); base::RunLoop().RunUntilIdle(); + base::FilePath root_dir; + CHECK(base::PathService::Get(base::DIR_TEMP, &root_dir)); + const base::FilePath root_path = + root_dir.Append(FILE_PATH_LITERAL(kDownloadDir)) + .Append(FILE_PATH_LITERAL(kCacheDir)); + const std::string test_filename = + std::string(kFakeDeviceIdForTesting) + std::string(kCabExtension); + base::FilePath full_path = root_path.Append(test_filename); + // Check that that expected patch file was created. + EXPECT_TRUE(base::PathExists(full_path)); + EXPECT_EQ(1, GetOnInstallResponseCallbackCallCountForTesting()); }
diff --git a/ash/components/phonehub/camera_roll_manager_impl_unittest.cc b/ash/components/phonehub/camera_roll_manager_impl_unittest.cc index 508478d6..3e6b7b2 100644 --- a/ash/components/phonehub/camera_roll_manager_impl_unittest.cc +++ b/ash/components/phonehub/camera_roll_manager_impl_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/components/phonehub/camera_roll_manager_impl.h" +#include "ash/components/phonehub/camera_roll_download_manager.h" #include "ash/components/phonehub/camera_roll_item.h" #include "ash/components/phonehub/camera_roll_thumbnail_decoder_impl.h" #include "ash/components/phonehub/fake_camera_roll_download_manager.h" @@ -24,6 +25,7 @@ #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" @@ -49,12 +51,24 @@ on_camera_roll_items_changed_call_count_++; } - int GetOnCameraRollViewUiStateUpdatedCallCount() const { + int on_camera_roll_items_changed_call_count() const { return on_camera_roll_items_changed_call_count_; } + void OnCameraRollDownloadError( + CameraRollManager::Observer::DownloadErrorType error_type, + const proto::CameraRollItemMetadata& metadata) override { + last_download_error_ = absl::make_optional(error_type); + } + + CameraRollManager::Observer::DownloadErrorType last_download_error() const { + return last_download_error_.value(); + } + private: int on_camera_roll_items_changed_call_count_ = 0; + absl::optional<CameraRollManager::Observer::DownloadErrorType> + last_download_error_ = absl::nullopt; }; // Registers preferences for @@ -160,7 +174,11 @@ } int GetOnCameraRollViewUiStateUpdatedCallCount() const { - return fake_observer_.GetOnCameraRollViewUiStateUpdatedCallCount(); + return fake_observer_.on_camera_roll_items_changed_call_count(); + } + + CameraRollManager::Observer::DownloadErrorType GetLastDownloadError() const { + return fake_observer_.last_download_error(); } int GetCurrentItemsCount() const { @@ -577,6 +595,57 @@ camera_roll_manager()->ui_state()); } +TEST_F(CameraRollManagerImplTest, EnableFromOptInDialog) { + SetCameraRollFeatureState(FeatureState::kDisabledByUser); + proto::PhoneStatusSnapshot snapshot; + proto::CameraRollAccessState* access_state = + snapshot.mutable_properties()->mutable_camera_roll_access_state(); + access_state->set_storage_permission_granted(true); + fake_message_receiver_.NotifyPhoneStatusSnapshotReceived(snapshot); + EXPECT_EQ(CameraRollManager::CameraRollUiState::CAN_OPT_IN, + camera_roll_manager()->ui_state()); + + camera_roll_manager()->EnableCameraRollFeatureInSystemSetting(); + // Verify that the CameraRollManager attempted to enable the feature via the + // MultideviceSetupClient. Then actually set the feature state to + // kEnabledByUser since the FakeMultideviceSetupClient doesn't do that. + fake_multidevice_setup_client_->InvokePendingSetFeatureEnabledStateCallback( + /*expected_feature=*/chromeos::multidevice_setup::mojom::Feature:: + kPhoneHubCameraRoll, + /*expected_enabled=*/true, + /*expected_auth_token=*/absl::nullopt, + /*success=*/true); + SetCameraRollFeatureState(FeatureState::kEnabledByUser); + // The UI should change into the loading view after the setting is enabled and + // before the items are received. + EXPECT_EQ(CameraRollManager::CameraRollUiState::LOADING_VIEW, + camera_roll_manager()->ui_state()); + + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key2"); + PopulateItemProto(response.add_items(), "key1"); + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kCompleted); + EXPECT_EQ(CameraRollManager::CameraRollUiState::ITEMS_VISIBLE, + camera_roll_manager()->ui_state()); +} + +TEST_F(CameraRollManagerImplTest, DismissOptInDialog) { + SetCameraRollFeatureState(FeatureState::kDisabledByUser); + proto::PhoneStatusSnapshot snapshot; + proto::CameraRollAccessState* access_state = + snapshot.mutable_properties()->mutable_camera_roll_access_state(); + access_state->set_storage_permission_granted(true); + fake_message_receiver_.NotifyPhoneStatusSnapshotReceived(snapshot); + EXPECT_EQ(CameraRollManager::CameraRollUiState::CAN_OPT_IN, + camera_roll_manager()->ui_state()); + + camera_roll_manager()->OnCameraRollOnboardingUiDismissed(); + + EXPECT_EQ(CameraRollManager::CameraRollUiState::SHOULD_HIDE, + camera_roll_manager()->ui_state()); +} + TEST_F(CameraRollManagerImplTest, DownloadItem) { // Make an item available to CameraRollManager. proto::FetchCameraRollItemsResponse response; @@ -641,7 +710,7 @@ EXPECT_EQ(0UL, GetSentInitiateCameraRollItemTransferRequestCount()); } -TEST_F(CameraRollManagerImplTest, DownloadItemAndCreatePayloadFilesFail) { +TEST_F(CameraRollManagerImplTest, DownloadItemFailedWithGenericError) { // Make an item available to CameraRollManager. proto::FetchCameraRollItemsResponse response; PopulateItemProto(response.add_items(), "key1"); @@ -652,16 +721,65 @@ // Request to download the item that was added. camera_roll_manager()->DownloadItem(item_to_download.metadata()); - EXPECT_EQ(1UL, GetSentFetchCameraRollItemDataRequestCount()); - EXPECT_EQ("key1", GetRecentFetchCameraRollItemDataRequest().metadata().key()); - - fake_camera_roll_download_manager()->set_should_create_payload_files_succeed( - false); + fake_camera_roll_download_manager()->set_expected_create_payload_files_result( + CameraRollDownloadManager::CreatePayloadFilesResult::kInvalidFileName); SendFetchCameraRollItemDataResponse( item_to_download.metadata(), proto::FetchCameraRollItemDataResponse::AVAILABLE, /*payload_id=*/1234); + EXPECT_EQ(0UL, GetSentInitiateCameraRollItemTransferRequestCount()); + EXPECT_EQ(CameraRollManager::Observer::DownloadErrorType::kGenericError, + GetLastDownloadError()); +} + +TEST_F(CameraRollManagerImplTest, DownloadItemFailedWithInsufficientStorage) { + // Make an item available to CameraRollManager. + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key1"); + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kCompleted); + const CameraRollItem& item_to_download = + camera_roll_manager()->current_items().back(); + + // Request to download the item that was added. + camera_roll_manager()->DownloadItem(item_to_download.metadata()); + fake_camera_roll_download_manager()->set_expected_create_payload_files_result( + CameraRollDownloadManager::CreatePayloadFilesResult:: + kInsufficientDiskSpace); + SendFetchCameraRollItemDataResponse( + item_to_download.metadata(), + proto::FetchCameraRollItemDataResponse::AVAILABLE, + /*payload_id=*/1234); + + EXPECT_EQ(0UL, GetSentInitiateCameraRollItemTransferRequestCount()); + EXPECT_EQ( + CameraRollManager::Observer::DownloadErrorType::kInsufficientStorage, + GetLastDownloadError()); +} + +TEST_F(CameraRollManagerImplTest, DownloadItemFailedWithNetworkError) { + // Make an item available to CameraRollManager. + proto::FetchCameraRollItemsResponse response; + PopulateItemProto(response.add_items(), "key1"); + fake_message_receiver_.NotifyFetchCameraRollItemsResponseReceived(response); + CompleteThumbnailDecoding(BatchDecodeResult::kCompleted); + const CameraRollItem& item_to_download = + camera_roll_manager()->current_items().back(); + + // Request to download the item that was added. + camera_roll_manager()->DownloadItem(item_to_download.metadata()); + SendFetchCameraRollItemDataResponse( + item_to_download.metadata(), + proto::FetchCameraRollItemDataResponse::AVAILABLE, + /*payload_id=*/1234); + SendFileTransferUpdate(/*payload_id=*/1234, FileTransferStatus::kInProgress, + /*total_bytes=*/1000, /*bytes_transferred=*/200); + SendFileTransferUpdate(/*payload_id=*/1234, FileTransferStatus::kFailure, + /*total_bytes=*/0, /*bytes_transferred=*/0); + + EXPECT_EQ(CameraRollManager::Observer::DownloadErrorType::kNetworkConnection, + GetLastDownloadError()); } TEST_F(CameraRollManagerImplTest, DownloadItemAndRegisterPayloadFileFail) {
diff --git a/ash/components/phonehub/fake_camera_roll_download_manager.cc b/ash/components/phonehub/fake_camera_roll_download_manager.cc index ce35659..91e130d 100644 --- a/ash/components/phonehub/fake_camera_roll_download_manager.cc +++ b/ash/components/phonehub/fake_camera_roll_download_manager.cc
@@ -24,18 +24,20 @@ int64_t payload_id, const phonehub::proto::CameraRollItemMetadata& item_metadata, CreatePayloadFilesCallback payload_files_callback) { - if (should_create_payload_files_succeed_) { + absl::optional<chromeos::secure_channel::mojom::PayloadFilesPtr> + payload_files; + if (expected_create_payload_files_result_ == + CreatePayloadFilesResult::kSuccess) { + payload_files = absl::make_optional( + chromeos::secure_channel::mojom::PayloadFiles::New()); payload_update_map_.emplace( payload_id, std::vector<chromeos::secure_channel::mojom::FileTransferUpdatePtr>()); - std::move(payload_files_callback) - .Run(CreatePayloadFilesResult::kSuccess, - absl::make_optional( - chromeos::secure_channel::mojom::PayloadFiles::New())); } else { - std::move(payload_files_callback) - .Run(CreatePayloadFilesResult::kInvalidFileName, absl::nullopt); + payload_files = absl::nullopt; } + std::move(payload_files_callback) + .Run(expected_create_payload_files_result_, std::move(payload_files)); } void FakeCameraRollDownloadManager::UpdateDownloadProgress(
diff --git a/ash/components/phonehub/fake_camera_roll_download_manager.h b/ash/components/phonehub/fake_camera_roll_download_manager.h index b1e2f5f2..157d747 100644 --- a/ash/components/phonehub/fake_camera_roll_download_manager.h +++ b/ash/components/phonehub/fake_camera_roll_download_manager.h
@@ -29,16 +29,18 @@ chromeos::secure_channel::mojom::FileTransferUpdatePtr update) override; void DeleteFile(int64_t payload_id) override; - void set_should_create_payload_files_succeed( - bool should_create_payload_files_succeed) { - should_create_payload_files_succeed_ = should_create_payload_files_succeed; + void set_expected_create_payload_files_result( + CreatePayloadFilesResult expected_create_payload_files_result) { + expected_create_payload_files_result_ = + expected_create_payload_files_result; } const std::vector<chromeos::secure_channel::mojom::FileTransferUpdatePtr>& GetFileTransferUpdates(int64_t payload_id) const; private: - bool should_create_payload_files_succeed_ = true; + CreatePayloadFilesResult expected_create_payload_files_result_ = + CreatePayloadFilesResult::kSuccess; // A map from payload IDs to the list of FileTransferUpdate received for each // payload.
diff --git a/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.cc b/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.cc index d846deb..c9fb6a7 100644 --- a/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.cc +++ b/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.cc
@@ -73,7 +73,7 @@ } bool ProximityAuthLocalStatePrefManager::IsEasyUnlockAllowed() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (user_prefs) { absl::optional<bool> pref_value = user_prefs->FindBoolKey( chromeos::multidevice_setup::kSmartLockAllowedPrefName); @@ -86,7 +86,7 @@ } bool ProximityAuthLocalStatePrefManager::IsEasyUnlockEnabled() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (user_prefs) { absl::optional<bool> pref_value = user_prefs->FindBoolKey( chromeos::multidevice_setup::kSmartLockEnabledPrefName); @@ -104,7 +104,7 @@ } bool ProximityAuthLocalStatePrefManager::IsChromeOSLoginAllowed() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (user_prefs) { absl::optional<bool> pref_value = user_prefs->FindBoolKey( chromeos::multidevice_setup::kSmartLockSigninAllowedPrefName); @@ -117,7 +117,7 @@ } bool ProximityAuthLocalStatePrefManager::IsSmartLockEligible() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (user_prefs) { absl::optional<bool> pref_value = user_prefs->FindBoolKey(prefs::kSmartLockEligiblePrefName); @@ -135,7 +135,7 @@ } bool ProximityAuthLocalStatePrefManager::IsChromeOSLoginEnabled() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (user_prefs) { absl::optional<bool> pref_value = user_prefs->FindBoolKey(prefs::kProximityAuthIsChromeOSLoginEnabled); @@ -175,7 +175,7 @@ } bool ProximityAuthLocalStatePrefManager::HasShownLoginDisabledMessage() const { - const base::DictionaryValue* user_prefs = GetActiveUserPrefsDictionary(); + const base::Value* user_prefs = GetActiveUserPrefsDictionary(); if (!user_prefs) return false; @@ -184,21 +184,20 @@ .value_or(false); } -const base::DictionaryValue* +const base::Value* ProximityAuthLocalStatePrefManager::GetActiveUserPrefsDictionary() const { if (!active_user_.is_valid()) { PA_LOG(ERROR) << "No active account."; return nullptr; } - const base::DictionaryValue* all_user_prefs_dict = - &base::Value::AsDictionaryValue( - *local_state_->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs)); + const base::Value* all_user_prefs_dict = + local_state_->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs); DCHECK(all_user_prefs_dict); - const base::DictionaryValue* current_user_prefs; - if (!all_user_prefs_dict->GetDictionaryWithoutPathExpansion( - active_user_.GetUserEmail(), ¤t_user_prefs)) { + const base::Value* current_user_prefs = + all_user_prefs_dict->FindDictKey(active_user_.GetUserEmail()); + if (!current_user_prefs) { PA_LOG(ERROR) << "Failed to find prefs for current user."; return nullptr; }
diff --git a/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.h b/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.h index 8037597a..dda698a 100644 --- a/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.h +++ b/ash/components/proximity_auth/proximity_auth_local_state_pref_manager.h
@@ -12,7 +12,7 @@ class PrefService; namespace base { -class DictionaryValue; +class Value; } // namespace base namespace proximity_auth { @@ -62,7 +62,7 @@ void SetHasShownLoginDisabledMessage(bool has_shown) override; bool HasShownLoginDisabledMessage() const override; - const base::DictionaryValue* GetActiveUserPrefsDictionary() const; + const base::Value* GetActiveUserPrefsDictionary() const; // Contains local state preferences that outlive the lifetime of this object // and across process restarts. Not owned and must outlive this instance.
diff --git a/ash/components/proximity_auth/proximity_auth_profile_pref_manager.cc b/ash/components/proximity_auth/proximity_auth_profile_pref_manager.cc index a6b0fbf..62cf3bb 100644 --- a/ash/components/proximity_auth/proximity_auth_profile_pref_manager.cc +++ b/ash/components/proximity_auth/proximity_auth_profile_pref_manager.cc
@@ -217,14 +217,15 @@ } bool ProximityAuthProfilePrefManager::HasShownLoginDisabledMessage() const { - const base::DictionaryValue* all_user_prefs_dict = - &base::Value::AsDictionaryValue( - *local_state_->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs)); - const base::DictionaryValue* current_user_prefs; - if (!all_user_prefs_dict || - !all_user_prefs_dict->GetDictionaryWithoutPathExpansion( - account_id_.GetUserEmail(), ¤t_user_prefs) || - !current_user_prefs) { + const base::Value* all_user_prefs_dict = + local_state_->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs); + if (!all_user_prefs_dict) { + PA_LOG(ERROR) << "Failed to find local state prefs for current user."; + return false; + } + const base::Value* current_user_prefs = + all_user_prefs_dict->FindDictKey(account_id_.GetUserEmail()); + if (!current_user_prefs) { PA_LOG(ERROR) << "Failed to find local state prefs for current user."; return false; }
diff --git a/ash/components/settings/cros_settings_names.cc b/ash/components/settings/cros_settings_names.cc index 971f13af..e2aa9b1 100644 --- a/ash/components/settings/cros_settings_names.cc +++ b/ash/components/settings/cros_settings_names.cc
@@ -243,6 +243,9 @@ // A boolean pref that determines whether the login/logout events are reported. const char kReportDeviceLoginLogout[] = "cros.reporting.report_login_logout"; +// Determines whether CRD session events are reported. +const char kReportCRDSessions[] = "cros.reporting.report_crd_sessions"; + // Determines whether heartbeats should be sent to the policy service via // the GCM channel. const char kHeartbeatEnabled[] = "cros.device_status.heartbeat_enabled";
diff --git a/ash/components/settings/cros_settings_names.h b/ash/components/settings/cros_settings_names.h index 4c0cbe3..bcdc72f 100644 --- a/ash/components/settings/cros_settings_names.h +++ b/ash/components/settings/cros_settings_names.h
@@ -133,6 +133,8 @@ COMPONENT_EXPORT(ASH_SETTINGS) extern const char kReportDeviceLoginLogout[]; COMPONENT_EXPORT(ASH_SETTINGS) +extern const char kReportCRDSessions[]; +COMPONENT_EXPORT(ASH_SETTINGS) extern const char kReportDeviceNetworkTelemetryCollectionRateMs[]; COMPONENT_EXPORT(ASH_SETTINGS) extern const char kReportDeviceNetworkTelemetryEventCheckingRateMs[];
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index 6cc5ced..db48836 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -387,12 +387,11 @@ // A boolean pref that enable fullscreen alert bubble. // TODO(zxdan): Change to an allowlist in M89. const char kFullscreenAlertEnabled[] = "ash.fullscreen_alert_enabled"; -// A list of URLs that are exempt from ash's fullscreen notification. To prevent -// fake login screens, the notification is normally shown when the device -// returns from sleep, low brightness or the lock screen and is still in full -// screen mode. -const char kFullscreenNotificationUrlExemptList[] = - "ash.fullscreen_notification_url_exempt_list"; +// A list of URLs that are allowed to continue full screen mode after session +// unlock without a notification. To prevent fake login screens, the device +// normally exits full screen mode before locking a session. +const char kKeepFullscreenWithoutNotificationUrlAllowList[] = + "ash.keep_fullscreen_without_notification_url_allow_list"; // A boolean pref storing whether the gesture education notification has ever // been shown to the user, which we use to stop showing it again.
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index 81a82ee..f80163b 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -193,7 +193,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFullscreenAlertEnabled[]; COMPONENT_EXPORT(ASH_CONSTANTS) -extern const char kFullscreenNotificationUrlExemptList[]; +extern const char kKeepFullscreenWithoutNotificationUrlAllowList[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kGestureEducationNotificationShown[];
diff --git a/ash/controls/scroll_view_gradient_helper.cc b/ash/controls/scroll_view_gradient_helper.cc index 1bb20fe..9d64aa8 100644 --- a/ash/controls/scroll_view_gradient_helper.cc +++ b/ash/controls/scroll_view_gradient_helper.cc
@@ -35,10 +35,12 @@ scroll_view_->AddContentsScrollEndedCallback( base::BindRepeating(&ScrollViewGradientHelper::UpdateGradientZone, base::Unretained(this))); + scroll_view_->SetPreferredViewportMargins(gfx::Insets(kGradientHeight, 0)); } ScrollViewGradientHelper::~ScrollViewGradientHelper() { RemoveMaskLayer(); + scroll_view_->SetPreferredViewportMargins(gfx::Insets()); } void ScrollViewGradientHelper::UpdateGradientZone() {
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc index 3bb430e..06f3ade 100644 --- a/ash/login/login_screen_controller.cc +++ b/ash/login/login_screen_controller.cc
@@ -291,10 +291,9 @@ } void LoginScreenController::ShowKioskAppError(const std::string& message) { - ToastData toast_data( - "KioskAppError", base::UTF8ToUTF16(message), -1 /*duration_ms*/, - absl::optional<std::u16string>(std::u16string()) /*dismiss_text*/, - true /*visible_on_lock_screen*/); + ToastData toast_data("KioskAppError", base::UTF8ToUTF16(message), + ToastData::kInfiniteDuration, + /*visible_on_lock_screen=*/true); Shell::Get()->toast_manager()->Show(toast_data); }
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 70826b3f..7c83d032 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1094,6 +1094,7 @@ return; big_view->auth_user()->NotifySmartLockAuthResult(success); + LayoutAuth(big_view, /*opt_to_hide=*/nullptr, /*animate=*/true); } void LockContentsView::OnAuthEnabledForUser(const AccountId& user) {
diff --git a/ash/login/ui/login_auth_factors_view.cc b/ash/login/ui/login_auth_factors_view.cc index 2b32068..326589a 100644 --- a/ash/login/ui/login_auth_factors_view.cc +++ b/ash/login/ui/login_auth_factors_view.cc
@@ -39,6 +39,9 @@ constexpr int kIconTopSpacingDp = 10; constexpr int kArrowButtonSizeDp = 32; constexpr base::TimeDelta kErrorTimeout = base::Seconds(3); +constexpr int kLabelMaxLines = 3; +constexpr int kLabelLineHeightDp = 20; +constexpr int kLabelHeightDp = kLabelMaxLines * kLabelLineHeightDp; // The values of this enum should be nearly the same as the values of // AuthFactorState, except instead of kErrorTemporary and kErrorPermanent, we @@ -138,7 +141,10 @@ SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorSecondary)); SetMultiLine(true); + SetMaxLines(kLabelMaxLines); + SetLineHeight(kLabelLineHeightDp); SizeToFit(kAuthFactorsViewWidthDp); + SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_TOP); } AuthFactorsLabel(const AuthFactorsLabel&) = delete; @@ -159,9 +165,7 @@ // views::View: gfx::Size CalculatePreferredSize() const override { - gfx::Size size = views::View::CalculatePreferredSize(); - size.set_width(kAuthFactorsViewWidthDp); - return size; + return gfx::Size(kAuthFactorsViewWidthDp, kLabelHeightDp); } void SetAccessibleName(const std::u16string& name) { @@ -209,13 +213,20 @@ } LoginAuthFactorsView::LoginAuthFactorsView( - base::RepeatingClosure on_click_to_enter) - : on_click_to_enter_callback_(on_click_to_enter) { + base::RepeatingClosure on_click_to_enter, + base::RepeatingCallback<void(bool)> on_click_required_changed) + : on_click_to_enter_callback_(on_click_to_enter), + on_click_required_changed_callback_(on_click_required_changed) { + DCHECK(on_click_required_changed); + SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); SetBorder(views::CreateEmptyBorder(kIconTopSpacingDp, 0, 0, 0)); - SetBoxLayout(this); + auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); + layout->SetOrientation(views::LayoutOrientation::kVertical); + layout->SetMainAxisAlignment(views::LayoutAlignment::kCenter); + layout->SetCrossAxisAlignment(views::LayoutAlignment::kCenter); auth_factor_icon_row_ = AddChildView(std::make_unique<views::View>()); auto* animating_layout = auth_factor_icon_row_->SetLayoutManager( @@ -262,6 +273,11 @@ checkmark_icon_->SetVisible(false); label_ = AddChildView(std::make_unique<AuthFactorsLabel>()); + label_->SetProperty( + views::kMarginsKey, + gfx::Insets(/*top=*/kSpacingBetweenIconsAndLabelDp, /*left=*/0, + /*bottom=*/0, + /*right=*/0)); } LoginAuthFactorsView::~LoginAuthFactorsView() = default; @@ -308,6 +324,18 @@ error_timer_.Stop(); } + // Fire a callback whenever entering/leaving the kClickRequired state. Avoid + // firing the callback for the kAuthenticated state since we do not want to + // change the visibility of the password/PIN fields when transitioning from + // kClickRequired to kAuthenticated. + bool should_show_arrow_button = + state == PrioritizedAuthFactorViewState::kClickRequired; + if (on_click_required_changed_callback_ && + should_show_arrow_button != arrow_button_->GetVisible() && + state != PrioritizedAuthFactorViewState::kAuthenticated) { + on_click_required_changed_callback_.Run(should_show_arrow_button); + } + int ready_label_id; size_t num_factors_in_error_background_state; switch (state) { @@ -324,7 +352,6 @@ return; case PrioritizedAuthFactorViewState::kClickRequired: // An auth factor requires a click to enter. Show arrow button. - // TODO(crbug.com/1233614): collapse password/pin ShowArrowButton(); SetLabelTextAndAccessibleName(IDS_AUTH_FACTOR_LABEL_CLICK_TO_ENTER, IDS_AUTH_FACTOR_LABEL_CLICK_TO_ENTER); @@ -440,6 +467,16 @@ int accessible_name_id) { label_->SetText(l10n_util::GetStringUTF16(label_id)); label_->SetAccessibleName(l10n_util::GetStringUTF16(accessible_name_id)); + + // Add margin to the bottom of the label to ensure that the total height of + // the label and margin is always |kLabelMaxLines| lines. + int bottom_margin = + (kLabelMaxLines - label_->GetRequiredLines()) * label_->GetLineHeight(); + label_->SetProperty( + views::kMarginsKey, + gfx::Insets(/*top=*/kSpacingBetweenIconsAndLabelDp, /*left=*/0, + /*bottom=*/std::max(bottom_margin, 0), + /*right=*/0)); } int LoginAuthFactorsView::GetReadyLabelId() const { @@ -550,6 +587,7 @@ arrow_button_->EnableLoadingAnimation(false); arrow_button_->RunTransformAnimation(); arrow_nudge_animation_->RunNudgeAnimation(); + arrow_button_->RequestFocus(); } else { arrow_nudge_animation_->StopAnimating(); arrow_button_->StopAnimating();
diff --git a/ash/login/ui/login_auth_factors_view.h b/ash/login/ui/login_auth_factors_view.h index 1b6940b..0a0fc8d 100644 --- a/ash/login/ui/login_auth_factors_view.h +++ b/ash/login/ui/login_auth_factors_view.h
@@ -51,7 +51,9 @@ LoginAuthFactorsView* const view_; }; - explicit LoginAuthFactorsView(base::RepeatingClosure on_click_to_enter); + LoginAuthFactorsView( + base::RepeatingClosure on_click_to_enter, + base::RepeatingCallback<void(bool)> on_click_required_changed); LoginAuthFactorsView(LoginAuthFactorsView&) = delete; LoginAuthFactorsView& operator=(LoginAuthFactorsView&) = delete; ~LoginAuthFactorsView() override; @@ -148,6 +150,7 @@ std::vector<std::unique_ptr<AuthFactorModel>> auth_factors_; base::RepeatingClosure on_click_to_enter_callback_; + base::RepeatingCallback<void(bool)> on_click_required_changed_callback_; base::OneShotTimer error_timer_; };
diff --git a/ash/login/ui/login_auth_factors_view_unittest.cc b/ash/login/ui/login_auth_factors_view_unittest.cc index 0045e41..1fd88e39 100644 --- a/ash/login/ui/login_auth_factors_view_unittest.cc +++ b/ash/login/ui/login_auth_factors_view_unittest.cc
@@ -130,16 +130,18 @@ AshTestBase::SetUp(); // We proxy |view_| inside of |container_| so we can control layout. - // TODO(crbug.com/1233614): Add layout tests to check positioning/ordering - // of icons. + // TODO(crbug.com/1233614): Add layout tests to check + // positioning/ordering of icons. container_ = std::make_unique<views::View>(); container_->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - view_ = container_->AddChildView( - std::make_unique<LoginAuthFactorsView>(base::BindRepeating( + view_ = container_->AddChildView(std::make_unique<LoginAuthFactorsView>( + base::BindRepeating( &LoginAuthFactorsViewUnittest::set_click_to_enter_called, - base::Unretained(this), true))); + base::Unretained(this), true), + base::BindRepeating(&LoginAuthFactorsViewUnittest::set_click_required, + base::Unretained(this)))); } void TearDown() override { @@ -171,11 +173,16 @@ click_to_enter_called_ = called; } + void set_click_required(bool click_required) { + click_required_ = click_required; + } + base::test::ScopedFeatureList feature_list_; std::unique_ptr<views::View> container_; LoginAuthFactorsView* view_ = nullptr; // Owned by container. std::vector<FakeAuthFactorModel*> auth_factors_; bool click_to_enter_called_ = false; + bool click_required_ = false; }; TEST_F(LoginAuthFactorsViewUnittest, NotVisibleIfNoAuthFactors) { @@ -297,6 +304,8 @@ ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); AddAuthFactors({AuthFactorType::kFingerprint, AuthFactorType::kSmartLock}); + ASSERT_FALSE(click_required_); + LoginAuthFactorsView::TestApi test_api(view_); auth_factors_[0]->state_ = AuthFactorState::kReady; auth_factors_[1]->state_ = AuthFactorState::kClickRequired; @@ -310,6 +319,12 @@ EXPECT_FALSE(test_api.auth_factor_icon_row()->GetVisible()); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTH_FACTOR_LABEL_CLICK_TO_ENTER), test_api.label()->GetText()); + EXPECT_TRUE(click_required_); + + auth_factors_[1]->state_ = AuthFactorState::kReady; + test_api.UpdateState(); + + EXPECT_FALSE(click_required_); } TEST_F(LoginAuthFactorsViewUnittest, ClickingArrowButton) {
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index a0c57d9..3ce8092 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -140,6 +140,10 @@ constexpr int kLockedTpmMessageDeltaDp = 0; constexpr int kLockedTpmMessageRoundedCornerRadiusDp = 8; +constexpr int kAuthFactorClickRequiredSlideUpDistanceDp = 42; +constexpr base::TimeDelta kAuthFactorClickRequiredSlideUpDuration = + base::Milliseconds(600); + constexpr int kNonEmptyWidthDp = 1; gfx::Size SizeFromHeight(int height) { return gfx::Size(kNonEmptyWidthDp, height); @@ -1135,13 +1139,20 @@ std::make_unique<SmartLockAuthFactorModel>(base::BindRepeating( &LoginAuthUserView::OnUserViewTap, base::Unretained(this))); smart_lock_auth_factor_model_ = smart_lock_auth_factor_model.get(); - auth_factors_view = - std::make_unique<LoginAuthFactorsView>(base::BindRepeating( + auth_factors_view = std::make_unique<LoginAuthFactorsView>( + base::BindRepeating( &SmartLockAuthFactorModel::OnArrowButtonTapOrClickEvent, - base::Unretained(smart_lock_auth_factor_model_))); + base::Unretained(smart_lock_auth_factor_model_)), + base::BindRepeating( + &LoginAuthUserView::OnAuthFactorClickRequiredChanged, + base::Unretained(this))); auth_factors_view_ = auth_factors_view.get(); auth_factors_view_->AddAuthFactor(std::move(fingerprint_auth_factor_model)); auth_factors_view_->AddAuthFactor(std::move(smart_lock_auth_factor_model)); + + // Needed for up/down sliding animation. + auth_factors_view_->SetPaintToLayer(); + auth_factors_view_->layer()->SetFillsBoundsOpaquely(false); } else { fingerprint_view = std::make_unique<FingerprintView>(); fingerprint_view_ = fingerprint_view.get(); @@ -1411,6 +1422,9 @@ } stop_animation(challenge_response_view_); stop_animation(pin_password_toggle_); + if (auth_factors_view_) { + stop_animation(auth_factors_view_); + } DCHECK(!previous_state_); previous_state_ = std::make_unique<UiState>(this); @@ -1430,6 +1444,8 @@ // Animate the user info (ie, icon, name) up or down the screen. { int non_pin_y_end_in_screen = GetBoundsInScreen().y(); + auto prev_transform_y = + layer()->GetAnimator()->GetTargetTransform().To2dTranslation().y(); // Transform the layer so the user view renders where it used to be. This // requires a y offset. @@ -1437,8 +1453,8 @@ // but it seems that the timing gets slightly out of sync with the PIN // animation. auto move_to_center = std::make_unique<ui::InterpolatedTranslation>( - gfx::PointF(0, previous_state_->non_pin_y_start_in_screen - - non_pin_y_end_in_screen), + gfx::PointF(0, previous_state_->non_pin_y_start_in_screen + + prev_transform_y - non_pin_y_end_in_screen), gfx::PointF()); auto transition = ui::LayerAnimationElement::CreateInterpolatedTransformElement( @@ -1535,8 +1551,7 @@ //////// // Fade the fingerprint view if it is being hidden or shown. - - if (fingerprint_view_ && + if (!smart_lock_ui_revamp_enabled_ && fingerprint_view_ && previous_state_->has_fingerprint != current_state.has_fingerprint) { float opacity_start = 0, opacity_end = 1; if (!current_state.has_fingerprint) @@ -1555,6 +1570,39 @@ } //////// + // Slide the auth factors view up/down when entering/leaving the click + // required state. + if (smart_lock_ui_revamp_enabled_) { + { + CHECK(auth_factors_view_); + ui::ScopedLayerAnimationSettings settings( + auth_factors_view_->layer()->GetAnimator()); + settings.SetTransitionDuration(kAuthFactorClickRequiredSlideUpDuration); + settings.SetTweenType(gfx::Tween::Type::ACCEL_20_DECEL_100); + + gfx::Transform transform; + transform.Translate(/*x=*/0, + /*y=*/auth_factor_has_click_required_ + ? -kAuthFactorClickRequiredSlideUpDistanceDp + : 0); + auth_factors_view_->layer()->GetAnimator()->SetTransform(transform); + } + + // Translate the user view to its previous position when in the click + // required state. This prevents the user view from moving when the password + // view collapses. + if (auth_factor_has_click_required_) { + layer()->GetAnimator()->StopAnimating(); + int non_pin_y_end_in_screen = GetBoundsInScreen().y(); + gfx::Transform transform; + transform.Translate(/*x=*/0, + /*y=*/previous_state_->non_pin_y_start_in_screen - + non_pin_y_end_in_screen); + layer()->GetAnimator()->SetTransform(transform); + } + } + + //////// // Fade the challenge response (Smart Card) if it is being hidden or shown. if (previous_state_->has_challenge_response != current_state.has_challenge_response) { @@ -1776,6 +1824,13 @@ pin_view_->OnPasswordTextChanged(is_empty); } +void LoginAuthUserView::OnAuthFactorClickRequiredChanged(bool click_required) { + if (click_required == auth_factor_has_click_required_) { + return; + } + auth_factor_has_click_required_ = click_required; +} + bool LoginAuthUserView::HasAuthMethod(AuthMethods auth_method) const { return (auth_methods_ & auth_method) != 0; } @@ -1858,9 +1913,10 @@ // - Online sign in message shown // - Disabled message shown // - No password auth available + // - Auth factors view is showing "click to enter" if (HasAuthMethod(AUTH_CHALLENGE_RESPONSE) || HasAuthMethod(AUTH_ONLINE_SIGN_IN) || HasAuthMethod(AUTH_DISABLED) || - !HasAuthMethod(AUTH_PASSWORD)) { + !HasAuthMethod(AUTH_PASSWORD) || auth_factor_has_click_required_) { input_field_mode_ = InputFieldMode::NONE; return; }
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h index 52e428e..2e491247 100644 --- a/ash/login/ui/login_auth_user_view.h +++ b/ash/login/ui/login_auth_user_view.h
@@ -231,6 +231,11 @@ void OnPasswordTextChanged(bool is_empty); void OnPinTextChanged(bool is_empty); + // Called when the |auth_factors_view_| enters or leaves the "click to enter" + // state, which indicates that the user has authenticated with an auth factor + // but is required to click a button to complete login/unlock. + void OnAuthFactorClickRequiredChanged(bool click_required); + // Helper method to check if an auth method is enable. Use it like this: // bool has_tap = HasAuthMethod(AUTH_TAP). bool HasAuthMethod(AuthMethods auth_method) const; @@ -317,6 +322,8 @@ // `ApplyAnimationPostLayout`. std::unique_ptr<UiState> previous_state_; + bool auth_factor_has_click_required_ = false; + base::WeakPtrFactory<LoginAuthUserView> weak_factory_{this}; };
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index 3a2779b..63262866 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -505,21 +505,21 @@ } if (language_menu_view_) { - advanced_view_->RemoveChildView(language_menu_view_); - delete language_menu_view_; + advanced_view_->RemoveChildViewT(language_menu_view_); + language_menu_view_ = nullptr; } - language_menu_view_ = new PublicAccountMenuView( + auto language_menu_view = std::make_unique<PublicAccountMenuView>( language_items_, selected_language_index, base::BindRepeating(&RightPaneView::OnLanguageSelected, weak_factory_.GetWeakPtr())); - language_menu_view_->SetTooltipTextAndAccessibleName( + language_menu_view->SetTooltipTextAndAccessibleName( l10n_util::GetStringUTF16( IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME)); int after_title_after_padding_index = advanced_view_->GetIndexOf(language_title_) + 2; - advanced_view_->AddChildViewAt(language_menu_view_, - after_title_after_padding_index); + language_menu_view_ = advanced_view_->AddChildViewAt( + std::move(language_menu_view), after_title_after_padding_index); } void PopulateKeyboardItems( @@ -540,21 +540,21 @@ } if (keyboard_menu_view_) { - advanced_view_->RemoveChildView(keyboard_menu_view_); - delete keyboard_menu_view_; + advanced_view_->RemoveChildViewT(keyboard_menu_view_); + keyboard_menu_view_ = nullptr; } - keyboard_menu_view_ = new PublicAccountMenuView( + auto keyboard_menu_view = std::make_unique<PublicAccountMenuView>( keyboard_items_, selected_keyboard_index, base::BindRepeating(&RightPaneView::OnKeyboardSelected, weak_factory_.GetWeakPtr())); - keyboard_menu_view_->SetTooltipTextAndAccessibleName( + keyboard_menu_view->SetTooltipTextAndAccessibleName( l10n_util::GetStringUTF16( IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME)); int after_title_after_padding_index = advanced_view_->GetIndexOf(keyboard_title_) + 2; - advanced_view_->AddChildViewAt(keyboard_menu_view_, - after_title_after_padding_index); + keyboard_menu_view_ = advanced_view_->AddChildViewAt( + std::move(keyboard_menu_view), after_title_after_padding_index); } PublicAccountMenuView* GetLanguageMenuView() { return language_menu_view_; }
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc index 63a5f5f..d00aa308 100644 --- a/ash/projector/projector_controller_impl.cc +++ b/ash/projector/projector_controller_impl.cc
@@ -184,6 +184,11 @@ result.reasons = { NewScreencastPreconditionReason::kSodaDownloadInProgress}; return result; + case SpeechRecognitionAvailability::kSodaInstallationError: + result.state = NewScreencastPreconditionState::kDisabled; + result.reasons = { + NewScreencastPreconditionReason::kSodaInstallationError}; + return result; case SpeechRecognitionAvailability::kAvailable: break; }
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index d637941..747cb19 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -364,7 +364,6 @@ "//chromeos/ui/base", "//chromeos/ui/frame", "//chromeos/ui/vector_icons", - "//components/favicon_base:favicon_base", "//components/language/core/browser:browser", "//components/pref_registry", "//components/prefs", @@ -469,7 +468,6 @@ deps = [ ":cpp", "//base", - "//components/favicon_base:favicon_base", "//services/device/public/cpp:test_support", "//services/network/public/cpp:cpp", "//testing/gmock",
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index cbdae59..47a63cef 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -25,13 +25,6 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableSuggestedLocalFiles{ "EnableSuggestedLocalFiles", base::FEATURE_DISABLED_BY_DEFAULT}; - -// "EnableEmbeddedAssistantUI" is used in finch experiment therefore we cannot -// change it until fully launched. It is used to redirect Launcher search to -// Assistant search. -const base::Feature kEnableAssistantSearch{"EnableEmbeddedAssistantUI", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kEnableAppListLaunchRecording{ "EnableAppListLaunchRecording", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kLauncherSettingsSearch{"LauncherSettingsSearch", @@ -77,10 +70,6 @@ return base::FeatureList::IsEnabled(kEnableSuggestedLocalFiles); } -bool IsAssistantSearchEnabled() { - return base::FeatureList::IsEnabled(kEnableAssistantSearch); -} - bool IsLauncherSettingsSearchEnabled() { return base::FeatureList::IsEnabled(kLauncherSettingsSearch); }
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h index d7247dc3..39ed24a 100644 --- a/ash/public/cpp/app_list/app_list_features.h +++ b/ash/public/cpp/app_list/app_list_features.h
@@ -43,9 +43,6 @@ // Enables local file suggestions in the suggestion chips. ASH_PUBLIC_EXPORT extern const base::Feature kEnableSuggestedLocalFiles; -// Enables the Assistant search redirection in the app list. -ASH_PUBLIC_EXPORT extern const base::Feature kEnableAssistantSearch; - // Enables hashed recording of a app list launches. ASH_PUBLIC_EXPORT extern const base::Feature kEnableAppListLaunchRecording; @@ -79,7 +76,6 @@ ASH_PUBLIC_EXPORT bool IsAppReinstallZeroStateEnabled(); ASH_PUBLIC_EXPORT bool IsSuggestedFilesEnabled(); ASH_PUBLIC_EXPORT bool IsSuggestedLocalFilesEnabled(); -ASH_PUBLIC_EXPORT bool IsAssistantSearchEnabled(); ASH_PUBLIC_EXPORT bool IsAppListLaunchRecordingEnabled(); ASH_PUBLIC_EXPORT bool IsFuzzyAppSearchEnabled(); ASH_PUBLIC_EXPORT bool IsExactMatchForNonLatinLocaleEnabled();
diff --git a/ash/public/cpp/desks_templates_delegate.h b/ash/public/cpp/desks_templates_delegate.h index 0e337bc..8617a6194 100644 --- a/ash/public/cpp/desks_templates_delegate.h +++ b/ash/public/cpp/desks_templates_delegate.h
@@ -8,8 +8,7 @@ #include <string> #include "ash/public/cpp/ash_public_export.h" -#include "components/favicon_base/favicon_callback.h" -#include "components/services/app_service/public/cpp/icon_types.h" +#include "base/callback.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace app_restore { @@ -71,18 +70,17 @@ // Fetches the favicon for `page_url` and returns it via the provided // `callback`. `callback` may be called synchronously. - virtual void GetFaviconForUrl(const std::string& page_url, - int desired_icon_size, - favicon_base::FaviconRawBitmapCallback callback, - base::CancelableTaskTracker* tracker) const = 0; + virtual void GetFaviconForUrl( + const std::string& page_url, + base::OnceCallback<void(const gfx::ImageSkia&)> callback, + base::CancelableTaskTracker* tracker) const = 0; // Fetches the icon for the app with `app_id` and returns it via the provided // `callback`. `callback` may be called synchronously. virtual void GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) - const = 0; + base::OnceCallback<void(const gfx::ImageSkia&)> callback) const = 0; // Launches apps into the active desk. Ran immediately after a desk is created // for a template.
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h index 1456344..81b34ef5 100644 --- a/ash/public/cpp/projector/projector_controller.h +++ b/ash/public/cpp/projector/projector_controller.h
@@ -31,6 +31,8 @@ kSodaNotInstalled, // SODA binary and language packs are downloading. kSodaInstalling, + // SODA installation failed. + kSodaInstallationError, // SODA is available to be used. kAvailable };
diff --git a/ash/public/cpp/projector/projector_new_screencast_precondition.h b/ash/public/cpp/projector/projector_new_screencast_precondition.h index e60dedc..5aee910c 100644 --- a/ash/public/cpp/projector/projector_new_screencast_precondition.h +++ b/ash/public/cpp/projector/projector_new_screencast_precondition.h
@@ -31,6 +31,7 @@ // NewScreencastPreconditionReason enum in // //ash/webui/projector_app/resources/communication/message_types.js. enum class ASH_PUBLIC_EXPORT NewScreencastPreconditionReason { + kSodaInstallationError = 0, kOnDeviceSpeechRecognitionNotSupported = 1, kUserLocaleNotSupported = 2, kInProjectorSession = 3,
diff --git a/ash/public/cpp/test/app_list_test_api.h b/ash/public/cpp/test/app_list_test_api.h index ee25e8d..cf8c5bf 100644 --- a/ash/public/cpp/test/app_list_test_api.h +++ b/ash/public/cpp/test/app_list_test_api.h
@@ -86,6 +86,12 @@ // bubble launcher is enabled or PagedAppsGridView otherwise. AppsGridView* GetTopLevelAppsGridView(); + // Returns the apps grid view in the folder. + AppsGridView* GetFolderAppsGridView(); + + // Returns whether the folder view is under animation. + bool IsFolderViewAnimating() const; + // Returns the app list bubble's undo button that reverts the temporary // sorting order when triggered. views::View* GetBubbleReorderUndoButton(); @@ -93,6 +99,11 @@ // Returns the visibility of the app list bubble's undo toast where the undo // button is located. bool GetBubbleReorderUndoToastVisibility() const; + + // Registers a callback that runs when all the animations scheduled to show or + // hide the folder view complete. + void SetFolderViewAnimationCallback( + base::OnceClosure folder_animation_done_callback); }; } // namespace ash
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.cc b/ash/public/cpp/test/test_desks_templates_delegate.cc index 0189e7e4..e624ada 100644 --- a/ash/public/cpp/test/test_desks_templates_delegate.cc +++ b/ash/public/cpp/test/test_desks_templates_delegate.cc
@@ -40,14 +40,13 @@ void TestDesksTemplatesDelegate::GetFaviconForUrl( const std::string& page_url, - int desired_icon_size, - favicon_base::FaviconRawBitmapCallback callback, + base::OnceCallback<void(const gfx::ImageSkia&)> callback, base::CancelableTaskTracker* tracker) const {} void TestDesksTemplatesDelegate::GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) const {} + base::OnceCallback<void(const gfx::ImageSkia&)> callback) const {} void TestDesksTemplatesDelegate::LaunchAppsFromTemplate( std::unique_ptr<DeskTemplate> desk_template) {}
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.h b/ash/public/cpp/test/test_desks_templates_delegate.h index be16352..d1efed29 100644 --- a/ash/public/cpp/test/test_desks_templates_delegate.h +++ b/ash/public/cpp/test/test_desks_templates_delegate.h
@@ -48,14 +48,14 @@ absl::optional<gfx::ImageSkia> MaybeRetrieveIconForSpecialIdentifier( const std::string& identifier, const ui::ColorProvider* color_provider) const override; - void GetFaviconForUrl(const std::string& page_url, - int desired_icon_size, - favicon_base::FaviconRawBitmapCallback callback, - base::CancelableTaskTracker* tracker) const override; - void GetIconForAppId(const std::string& app_id, - int desired_icon_size, - base::OnceCallback<void(apps::IconValuePtr icon_value)> - callback) const override; + void GetFaviconForUrl( + const std::string& page_url, + base::OnceCallback<void(const gfx::ImageSkia&)> callback, + base::CancelableTaskTracker* tracker) const override; + void GetIconForAppId( + const std::string& app_id, + int desired_icon_size, + base::OnceCallback<void(const gfx::ImageSkia&)> callback) const override; void LaunchAppsFromTemplate( std::unique_ptr<DeskTemplate> desk_template) override; bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
diff --git a/ash/public/cpp/toast_data.cc b/ash/public/cpp/toast_data.cc index 4222777..498b108 100644 --- a/ash/public/cpp/toast_data.cc +++ b/ash/public/cpp/toast_data.cc
@@ -11,13 +11,13 @@ ToastData::ToastData(std::string id, const std::u16string& text, int32_t duration_ms, - const absl::optional<std::u16string>& dismiss_text, - bool visible_on_lock_screen) + bool visible_on_lock_screen, + const absl::optional<std::u16string>& dismiss_text) : id(std::move(id)), text(text), duration_ms(duration_ms), - dismiss_text(dismiss_text), - visible_on_lock_screen(visible_on_lock_screen) {} + visible_on_lock_screen(visible_on_lock_screen), + dismiss_text(dismiss_text) {} ToastData::ToastData(const ToastData& other) = default;
diff --git a/ash/public/cpp/toast_data.h b/ash/public/cpp/toast_data.h index 7b0c1eb..2b47a4af 100644 --- a/ash/public/cpp/toast_data.h +++ b/ash/public/cpp/toast_data.h
@@ -17,20 +17,21 @@ // "|duration_ms| == -1" means the toast view should be displayed until the // dismiss button is clicked. static const int32_t kInfiniteDuration = -1; + static const int32_t kDefaultToastDurationMs = 6 * 1000; ToastData(std::string id, const std::u16string& text, - int32_t duration_ms, - const absl::optional<std::u16string>& dismiss_text, - bool visible_on_lock_screen = false); + int32_t duration_ms = kDefaultToastDurationMs, + bool visible_on_lock_screen = false, + const absl::optional<std::u16string>& dismiss_text = absl::nullopt); ToastData(const ToastData& other); ~ToastData(); std::string id; std::u16string text; int32_t duration_ms; - absl::optional<std::u16string> dismiss_text; bool visible_on_lock_screen; + absl::optional<std::u16string> dismiss_text; bool is_managed = false; base::RepeatingClosure dismiss_callback; };
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller_client.h b/ash/public/cpp/wallpaper/wallpaper_controller_client.h index 2b65b38..0e557bc2 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller_client.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller_client.h
@@ -45,9 +45,10 @@ const std::string& collection_id, DailyWallpaperUrlFetchedCallback callback) = 0; - // Returns true if image was successfully saved. - virtual bool SaveWallpaperToDriveFs(const AccountId& account_id, - const base::FilePath& origin) = 0; + virtual void SaveWallpaperToDriveFs( + const AccountId& account_id, + const base::FilePath& origin, + base::OnceCallback<void(bool)> wallpaper_saved_callback) = 0; virtual base::FilePath GetWallpaperPathFromDriveFs( const AccountId& account_id) = 0;
diff --git a/ash/quick_pair/common/account_key_failure.h b/ash/quick_pair/common/account_key_failure.h index fd0a133..b45b62b4 100644 --- a/ash/quick_pair/common/account_key_failure.h +++ b/ash/quick_pair/common/account_key_failure.h
@@ -11,11 +11,15 @@ namespace ash { namespace quick_pair { +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. This enum should be kept in sync with +// the FastPairAccountKeyFailure enum in src/tools/metrics/histograms/enums.xml. enum class AccountKeyFailure { // Failed to find the Account Key GATT characteristic. kAccountKeyCharacteristicDiscovery = 0, // Failed to write to the Account Key GATT characteristic. kAccountKeyCharacteristicWrite = 1, + kMaxValue = kAccountKeyCharacteristicWrite, }; COMPONENT_EXPORT(QUICK_PAIR_COMMON)
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc index f31b8bb..3ce4e034 100644 --- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
@@ -11,6 +11,39 @@ namespace { +// Error strings should be kept in sync with the strings reflected in +// device/bluetooth/bluez/bluetooth_socket_bluez.cc. +const char kAcceptFailedString[] = "Failed to accept connection."; +const char kInvalidUUIDString[] = "Invalid UUID"; +const char kSocketNotListeningString[] = "Socket is not listening."; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. This enum should be kept in sync +// with the BluetoothConnectToServiceError enum in +// src/tools/metrics/histograms/enums.xml. +enum class ConnectToServiceError { + kUnknownError = 0, + kAcceptFailed = 1, + kInvalidUUID = 2, + kSocketNotListening = 3, + kMaxValue = kSocketNotListening, +}; + +ConnectToServiceError GetConnectToServiceError(const std::string& error) { + if (error == kAcceptFailedString) + return ConnectToServiceError::kAcceptFailed; + + if (error == kInvalidUUIDString) + return ConnectToServiceError::kInvalidUUID; + + if (error == kSocketNotListeningString) + return ConnectToServiceError::kSocketNotListening; + + DCHECK(error != kSocketNotListeningString && error != kInvalidUUIDString && + error != kAcceptFailedString); + return ConnectToServiceError::kUnknownError; +} + const char kEngagementFlowInitialMetric[] = "Bluetooth.ChromeOS.FastPair.EngagementFunnel.Steps.InitialPairingProtocol"; const char kEngagementFlowSubsequentMetric[] = @@ -44,19 +77,20 @@ const char kFastPairPairResultRetroactiveMetric[] = "Bluetooth.ChromeOS.FastPair.Pairing.Result.RetroactivePairingProtocol"; const char kFastPairAccountKeyWriteResultInitialMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result.InitialPairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result." + "InitialPairingProtocol"; const char kFastPairAccountKeyWriteResultSubsequentMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result." + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result." "SubsequentPairingProtocol"; const char kFastPairAccountKeyWriteResultRetroactiveMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result." + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result." "RetroactivePairingProtocol"; const char kFastPairAccountKeyWriteFailureInitialMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyFailure.InitialPairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Failure.InitialPairingProtocol"; const char kFastPairAccountKeyWriteFailureSubsequentMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyFailure.SubsequentPairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Failure.SubsequentPairingProtocol"; const char kFastPairAccountKeyWriteFailureRetroactiveMetric[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyFailure.RetroactivePairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Failure.RetroactivePairingProtocol"; const char kKeyGenerationResultMetric[] = "Bluetooth.ChromeOS.FastPair.KeyGenerationResult"; const char kDataEncryptorCreateResultMetric[] = @@ -73,6 +107,39 @@ "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.DecryptTime"; const char kKeyBasedCharacteristicDecryptResult[] = "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.DecryptResult"; +const char kWritePasskeyCharacteristicResult[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.Result"; +const char kWritePasskeyCharacteristicPairFailure[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.PairFailure"; +const char kWritePasskeyCharacteristicGattError[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.GattErrorReason"; +const char kNotifyPasskeyCharacteristicTime[] = + "Bluetooth.ChromeOS.FastPair.Passkey.NotifyTime"; +const char kPasskeyCharacteristicDecryptTime[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Time"; +const char kPasskeyCharacteristicDecryptResult[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Result"; +const char kWriteAccountKeyCharacteristicResult[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result"; +const char kWriteAccountKeyCharacteristicGattError[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.GattErrorReason"; +const char kWriteAccountKeyTime[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.TotalTime"; +const char kTotalDataEncryptorCreateTime[] = + "Bluetooth.ChromeOS.FastPair.FastPairDataEncryptor.CreateTime"; +const char kMessageStreamReceiveResult[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.Receive.Result"; +const char kMessageStreamReceiveError[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.Receive.ErrorReason"; +const char kMessageStreamConnectToServiceError[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.ErrorReason"; +const char kMessageStreamConnectToServiceResult[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.Result"; +const char kMessageStreamConnectToServiceTime[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService." + "TotalConnectTime"; +const char kDeviceMetadataFetchResult[] = + "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Result"; } // namespace @@ -145,7 +212,7 @@ device::BluetoothDevice::ConnectErrorCode error_code) { base::UmaHistogramEnumeration( kGattConnectionErrorMetric, error_code, - device::BluetoothDevice::NUM_CONNECT_ERROR_CODES); + device::BluetoothDevice::ConnectErrorCode::NUM_CONNECT_ERROR_CODES); } void RecordPairingResult(const Device& device, bool success) { @@ -182,16 +249,16 @@ AccountKeyFailure failure) { switch (device.protocol) { case Protocol::kFastPairInitial: - base::UmaHistogramSparse(kFastPairAccountKeyWriteFailureInitialMetric, - static_cast<int>(failure)); + base::UmaHistogramEnumeration( + kFastPairAccountKeyWriteFailureInitialMetric, failure); break; case Protocol::kFastPairRetroactive: - base::UmaHistogramSparse(kFastPairAccountKeyWriteFailureRetroactiveMetric, - static_cast<int>(failure)); + base::UmaHistogramEnumeration( + kFastPairAccountKeyWriteFailureRetroactiveMetric, failure); break; case Protocol::kFastPairSubsequent: - base::UmaHistogramSparse(kFastPairAccountKeyWriteFailureSubsequentMetric, - static_cast<int>(failure)); + base::UmaHistogramEnumeration( + kFastPairAccountKeyWriteFailureSubsequentMetric, failure); break; } } @@ -247,5 +314,76 @@ base::UmaHistogramBoolean(kKeyBasedCharacteristicDecryptResult, success); } +void RecordWritePasskeyCharacteristicResult(bool success) { + base::UmaHistogramBoolean(kWritePasskeyCharacteristicResult, success); +} + +void RecordWritePasskeyCharacteristicPairFailure(PairFailure failure) { + base::UmaHistogramEnumeration(kWritePasskeyCharacteristicPairFailure, + failure); +} + +void RecordWritePasskeyGattError( + device::BluetoothGattService::GattErrorCode error) { + base::UmaHistogramEnumeration(kWritePasskeyCharacteristicGattError, error); +} + +void RecordNotifyPasskeyCharacteristicTime(base::TimeDelta total_notify_time) { + base::UmaHistogramTimes(kNotifyPasskeyCharacteristicTime, total_notify_time); +} + +void RecordPasskeyCharacteristicDecryptTime(base::TimeDelta decrypt_time) { + base::UmaHistogramTimes(kPasskeyCharacteristicDecryptTime, decrypt_time); +} + +void RecordPasskeyCharacteristicDecryptResult(bool success) { + base::UmaHistogramBoolean(kPasskeyCharacteristicDecryptResult, success); +} + +void RecordWriteAccountKeyCharacteristicResult(bool success) { + base::UmaHistogramBoolean(kWriteAccountKeyCharacteristicResult, success); +} + +void RecordWriteAccountKeyGattError( + device::BluetoothGattService::GattErrorCode error) { + base::UmaHistogramEnumeration(kWriteAccountKeyCharacteristicGattError, error); +} + +void RecordWriteAccountKeyTime(base::TimeDelta write_time) { + base::UmaHistogramTimes(kWriteAccountKeyTime, write_time); +} + +void RecordTotalDataEncryptorCreateTime(base::TimeDelta total_create_time) { + base::UmaHistogramTimes(kTotalDataEncryptorCreateTime, total_create_time); +} + +void RecordMessageStreamReceiveResult(bool success) { + base::UmaHistogramBoolean(kMessageStreamReceiveResult, success); +} + +void RecordMessageStreamReceiveError( + device::BluetoothSocket::ErrorReason error) { + base::UmaHistogramEnumeration(kMessageStreamReceiveError, error); +} + +void RecordMessageStreamConnectToServiceResult(bool success) { + base::UmaHistogramBoolean(kMessageStreamConnectToServiceResult, success); +} + +void RecordMessageStreamConnectToServiceError(const std::string& error) { + base::UmaHistogramEnumeration(kMessageStreamConnectToServiceError, + GetConnectToServiceError(error)); +} + +void RecordMessageStreamConnectToServiceTime( + base::TimeDelta total_connect_time) { + base::UmaHistogramTimes(kMessageStreamConnectToServiceTime, + total_connect_time); +} + +void RecordDeviceMetadataFetchResult(bool success) { + base::UmaHistogramBoolean(kDeviceMetadataFetchResult, success); +} + } // namespace quick_pair } // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h index c32c1ff..9eb26eec 100644 --- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
@@ -10,6 +10,7 @@ #include "base/component_export.h" #include "base/time/time.h" #include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_socket.h" namespace ash { namespace quick_pair { @@ -126,6 +127,58 @@ COMPONENT_EXPORT(QUICK_PAIR_COMMON) void RecordKeyBasedCharacteristicDecryptResult(bool success); +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWritePasskeyCharacteristicResult(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWritePasskeyCharacteristicPairFailure(PairFailure failure); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWritePasskeyGattError( + device::BluetoothGattService::GattErrorCode error); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordNotifyPasskeyCharacteristicTime(base::TimeDelta total_notify_time); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordPasskeyCharacteristicDecryptTime(base::TimeDelta decrypt_time); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordPasskeyCharacteristicDecryptResult(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWriteAccountKeyCharacteristicResult(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWriteAccountKeyGattError( + device::BluetoothGattService::GattErrorCode error); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordWriteAccountKeyTime(base::TimeDelta write_time); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordTotalDataEncryptorCreateTime(base::TimeDelta total_create_time); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordMessageStreamReceiveResult(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordMessageStreamReceiveError( + device::BluetoothSocket::ErrorReason error); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordMessageStreamConnectToServiceResult(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordMessageStreamConnectToServiceError(const std::string& error); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordMessageStreamConnectToServiceTime( + base::TimeDelta total_connect_time); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordDeviceMetadataFetchResult(bool success); + } // namespace quick_pair } // namespace ash
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc index 8edb4d3..7c51cca 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc
@@ -110,9 +110,8 @@ << device_address_ << "]."; device->CreateGattConnection( base::BindOnce(&FastPairGattServiceClientImpl::OnGattConnection, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()), kFastPairBluetoothUuid); - gatt_connection_start_time_ = base::TimeTicks::Now(); gatt_service_discovery_timer_.Start( FROM_HERE, kGattOperationTimeout, base::BindOnce(&FastPairGattServiceClientImpl::NotifyInitializedError, @@ -123,6 +122,7 @@ FastPairGattServiceClientImpl::~FastPairGattServiceClientImpl() = default; void FastPairGattServiceClientImpl::OnGattConnection( + base::TimeTicks gatt_connection_start_time, std::unique_ptr<device::BluetoothGattConnection> gatt_connection, absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) { RecordGattConnectionResult(/*success=*/!error_code.has_value()); @@ -137,7 +137,7 @@ << "Successful creation of GATT connection to device at address:[" << device_address_ << "]."; RecordTotalGattConnectionTime(base::TimeTicks::Now() - - gatt_connection_start_time_); + gatt_connection_start_time); gatt_connection_ = std::move(gatt_connection); } } @@ -441,7 +441,7 @@ fast_pair_data_encryptor->EncryptBytes( CreatePasskeyBlock(message_type, passkey)); - notify_keybased_start_time_ = base::TimeTicks::Now(); + notify_passkey_start_time_ = base::TimeTicks::Now(); passkey_characteristic_->WriteRemoteCharacteristic( std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()), device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, @@ -468,7 +468,7 @@ std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()), device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKey, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()), base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKeyError, weak_ptr_factory_.GetWeakPtr())); } @@ -494,6 +494,8 @@ } else if (characteristic == passkey_characteristic_ && passkey_write_response_callback_) { passkey_write_request_timer_.Stop(); + RecordNotifyPasskeyCharacteristicTime(base::TimeTicks::Now() - + notify_passkey_start_time_); std::move(passkey_write_response_callback_) .Run(value, /*failure=*/absl::nullopt); } @@ -523,14 +525,18 @@ QP_LOG(WARNING) << "WriteRemoteCharacteristic to passkey pairing " "characteristic failed due to GATT error: " << ToString(error); + RecordWritePasskeyGattError(error); NotifyWritePasskeyError(PairFailure::kPasskeyPairingCharacteristicWrite); } -void FastPairGattServiceClientImpl::OnWriteAccountKey() { +void FastPairGattServiceClientImpl::OnWriteAccountKey( + base::TimeTicks write_account_key_start_time) { QP_LOG(VERBOSE) << "WriteRemoteCharacteristic to account key characteristic successful."; DCHECK(write_account_key_callback_); - std::move(write_account_key_callback_).Run(absl::nullopt); + RecordWriteAccountKeyTime(base::TimeTicks::Now() - + write_account_key_start_time); + std::move(write_account_key_callback_).Run(/*failure=*/absl::nullopt); } void FastPairGattServiceClientImpl::OnWriteAccountKeyError( @@ -538,6 +544,7 @@ QP_LOG(WARNING) << "WriteRemoteCharacteristic to account key characteristic " "failed due to GATT error: " << ToString(error); + RecordWriteAccountKeyGattError(error); NotifyWriteAccountKeyError(error); }
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h index 366d93dc..ae8cf1c7c 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h
@@ -111,6 +111,7 @@ // Callback from the adapter's call to create GATT connection. void OnGattConnection( + base::TimeTicks gatt_connection_start_time, std::unique_ptr<device::BluetoothGattConnection> gatt_connection, absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code); @@ -153,7 +154,7 @@ void OnWriteRequestError(device::BluetoothGattService::GattErrorCode error); void OnWritePasskey(); void OnWritePasskeyError(device::BluetoothGattService::GattErrorCode error); - void OnWriteAccountKey(); + void OnWriteAccountKey(base::TimeTicks write_account_key_start_time); void OnWriteAccountKeyError( device::BluetoothGattService::GattErrorCode error); @@ -176,9 +177,9 @@ std::string device_address_; bool is_initialized_ = false; - // Initial timestamps used to calculate duration to log to metrics. - base::TimeTicks gatt_connection_start_time_; + // Initial timestamps used to calculate duration to log to metrics.; base::TimeTicks notify_keybased_start_time_; + base::TimeTicks notify_passkey_start_time_; device::BluetoothRemoteGattCharacteristic* key_based_characteristic_ = nullptr;
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_unittest.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_unittest.cc index f4e0aa5c..75bd8fd 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_unittest.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_unittest.cc
@@ -48,6 +48,14 @@ "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.Write.GattErrorReason"; const char kNotifyKeyBasedCharacteristicTime[] = "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.NotifyTime"; +const char kWritePasskeyCharacteristicGattError[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.GattErrorReason"; +const char kNotifyPasskeyCharacteristicTime[] = + "Bluetooth.ChromeOS.FastPair.Passkey.NotifyTime"; +const char kWriteAccountKeyCharacteristicGattError[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.GattErrorReason"; +const char kWriteAccountKeyTimeMetric[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.TotalTime"; constexpr base::TimeDelta kConnectingTestTimeout = base::Seconds(5); @@ -547,7 +555,9 @@ histogram_tester().ExpectTotalCount(kTotalGattConnectionTime, 0); histogram_tester().ExpectTotalCount(kGattConnectionResult, 0); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); SuccessfulGattConnectionSetUp(); FastForwardTimeByConnetingTimeout(); NotifyGattDiscoveryCompleteForService(); @@ -558,14 +568,18 @@ histogram_tester().ExpectTotalCount(kGattConnectionResult, 1); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); } TEST_F(FastPairGattServiceClientTest, FailedGattConnection) { histogram_tester().ExpectTotalCount(kTotalGattConnectionTime, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kGattConnectionResult, 0); histogram_tester().ExpectTotalCount(kGattConnectionErrorMetric, 0); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); FailedGattConnectionSetUp(); EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kCreateGattConnection); EXPECT_FALSE(ServiceIsSet()); @@ -575,6 +589,8 @@ histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kTotalGattConnectionTime, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); } TEST_F(FastPairGattServiceClientTest, GattConnectionSuccess) { @@ -583,6 +599,8 @@ histogram_tester().ExpectTotalCount(kGattConnectionErrorMetric, 0); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); histogram_tester().ExpectTotalCount(kTotalGattConnectionTime, 1); @@ -590,6 +608,8 @@ histogram_tester().ExpectTotalCount(kGattConnectionErrorMetric, 0); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicGattError, 0); histogram_tester().ExpectTotalCount(kNotifyKeyBasedCharacteristicTime, 0); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); } TEST_F(FastPairGattServiceClientTest, IgnoreNonFastPairServices) { @@ -630,12 +650,14 @@ } TEST_F(FastPairGattServiceClientTest, StartNotifyPasskeyFailure) { + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); SuccessfulGattConnectionSetUp(); SetPasskeyNotifySessionError(true); NotifyGattDiscoveryCompleteForService(); EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kPasskeyCharacteristicNotifySession); EXPECT_FALSE(ServiceIsSet()); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); } TEST_F(FastPairGattServiceClientTest, StartNotifyKeybasedFailure) { @@ -650,12 +672,14 @@ } TEST_F(FastPairGattServiceClientTest, PasskeyStartNotifyTimeout) { + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); SetPasskeyNotifySessionTimeout(true); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kPasskeyCharacteristicNotifySessionTimeout); EXPECT_FALSE(ServiceIsSet()); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); } TEST_F(FastPairGattServiceClientTest, KeyBasedStartNotifyTimeout) { @@ -710,6 +734,8 @@ PairFailure::kKeyBasedPairingResponseTimeout); } TEST_F(FastPairGattServiceClientTest, WritePasskeyRequest) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 0); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); EXPECT_EQ(GetInitializedCallbackResult(), absl::nullopt); @@ -717,9 +743,12 @@ WriteRequestToPasskey(); TriggerPasskeyGattChanged(); EXPECT_EQ(GetWriteCallbackResult(), absl::nullopt); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); + histogram_tester().ExpectTotalCount(kNotifyPasskeyCharacteristicTime, 1); } TEST_F(FastPairGattServiceClientTest, WritePasskeyRequestError) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); SetPasskeyWriteError(); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); @@ -729,9 +758,11 @@ TriggerKeyBasedGattChanged(); EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kPasskeyPairingCharacteristicWrite); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 1); } TEST_F(FastPairGattServiceClientTest, WritePasskeyRequestTimeout) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); SetWritePasskeyTimeout(); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); @@ -740,9 +771,13 @@ WriteRequestToPasskey(); TriggerKeyBasedGattChanged(); EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kPasskeyResponseTimeout); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicGattError, 0); } TEST_F(FastPairGattServiceClientTest, WriteAccountKey) { + histogram_tester().ExpectTotalCount(kWriteAccountKeyCharacteristicGattError, + 0); + histogram_tester().ExpectTotalCount(kWriteAccountKeyTimeMetric, 0); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); EXPECT_EQ(GetInitializedCallbackResult(), absl::nullopt); @@ -752,9 +787,15 @@ EXPECT_EQ(GetWriteCallbackResult(), absl::nullopt); WriteAccountKey(); EXPECT_EQ(GetAccountKeyCallback(), absl::nullopt); + histogram_tester().ExpectTotalCount(kWriteAccountKeyCharacteristicGattError, + 0); + histogram_tester().ExpectTotalCount(kWriteAccountKeyTimeMetric, 1); } TEST_F(FastPairGattServiceClientTest, WriteAccountKeyFailure) { + histogram_tester().ExpectTotalCount(kWriteAccountKeyCharacteristicGattError, + 0); + histogram_tester().ExpectTotalCount(kWriteAccountKeyTimeMetric, 0); SetAccountKeyCharacteristicWriteError(true); SuccessfulGattConnectionSetUp(); NotifyGattDiscoveryCompleteForService(); @@ -765,6 +806,9 @@ EXPECT_EQ(GetWriteCallbackResult(), absl::nullopt); WriteAccountKey(); EXPECT_NE(GetAccountKeyCallback(), absl::nullopt); + histogram_tester().ExpectTotalCount(kWriteAccountKeyCharacteristicGattError, + 1); + histogram_tester().ExpectTotalCount(kWriteAccountKeyTimeMetric, 0); } } // namespace quick_pair
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.cc index 8b66c58..73c5893c 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.cc
@@ -54,10 +54,11 @@ FastPairDataEncryptorImpl::Factory::CreateAsync( device_, base::BindOnce(&FastPairHandshakeImpl::OnDataEncryptorCreateAsync, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); } void FastPairHandshakeImpl::OnDataEncryptorCreateAsync( + base::TimeTicks encryptor_create_start_time, std::unique_ptr<FastPairDataEncryptor> fast_pair_data_encryptor) { bool success = fast_pair_data_encryptor != nullptr; RecordDataEncryptorCreateResult(/*success=*/success); @@ -73,6 +74,8 @@ fast_pair_data_encryptor_ = std::move(fast_pair_data_encryptor); QP_LOG(INFO) << __func__ << ": Fast Pair GATT service client initialization successful."; + RecordTotalDataEncryptorCreateTime(base::TimeTicks::Now() - + encryptor_create_start_time); bool is_retroactive = device_->protocol == Protocol::kFastPairRetroactive;
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h index 9a96e613..f32f9c3 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h
@@ -27,6 +27,7 @@ private: void OnGattClientInitializedCallback(absl::optional<PairFailure> failure); void OnDataEncryptorCreateAsync( + base::TimeTicks encryptor_create_start_time, std::unique_ptr<FastPairDataEncryptor> fast_pair_data_encryptor); void OnWriteResponse(std::vector<uint8_t> response_bytes, absl::optional<PairFailure> failure); @@ -34,6 +35,8 @@ base::TimeTicks decrypt_start_time, const absl::optional<DecryptedResponse>& response); + base::TimeTicks encryptor_create_start_time_; + base::WeakPtrFactory<FastPairHandshakeImpl> weak_ptr_factory_{this}; };
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl_unittest.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl_unittest.cc index f7ff0c5..57d9864 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl_unittest.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl_unittest.cc
@@ -103,6 +103,8 @@ "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.DecryptTime"; const char kKeyBasedCharacteristicDecryptResult[] = "Bluetooth.ChromeOS.FastPair.KeyBasedPairing.DecryptResult"; +const char kTotalDataEncryptorCreateTimeMetric[] = + "Bluetooth.ChromeOS.FastPair.FastPairDataEncryptor.CreateTime"; } // namespace @@ -171,6 +173,7 @@ histogram_tester().ExpectTotalCount(kDataEncryptorCreateResultMetric, 0); histogram_tester().ExpectTotalCount( kWriteKeyBasedCharacteristicPairFailureMetric, 0); + histogram_tester().ExpectTotalCount(kTotalDataEncryptorCreateTimeMetric, 0); data_encryptor_factory_.SetFailedRetrieval(); fake_fast_pair_gatt_service_client()->RunOnGattClientInitializedCallback(); EXPECT_EQ(failure_.value(), PairFailure::kDataEncryptorRetrieval); @@ -180,6 +183,7 @@ 0); histogram_tester().ExpectTotalCount( kWriteKeyBasedCharacteristicPairFailureMetric, 0); + histogram_tester().ExpectTotalCount(kTotalDataEncryptorCreateTimeMetric, 0); } TEST_F(FastPairHandshakeImplTest, WriteResponseError) { @@ -188,12 +192,14 @@ 0); histogram_tester().ExpectTotalCount( kWriteKeyBasedCharacteristicPairFailureMetric, 0); + histogram_tester().ExpectTotalCount(kTotalDataEncryptorCreateTimeMetric, 0); fake_fast_pair_gatt_service_client()->RunOnGattClientInitializedCallback(); fake_fast_pair_gatt_service_client()->RunWriteResponseCallback( std::vector<uint8_t>(), PairFailure::kKeyBasedPairingCharacteristicWrite); EXPECT_EQ(failure_.value(), PairFailure::kKeyBasedPairingCharacteristicWrite); EXPECT_FALSE(handshake_->completed_successfully()); histogram_tester().ExpectTotalCount(kDataEncryptorCreateResultMetric, 1); + histogram_tester().ExpectTotalCount(kTotalDataEncryptorCreateTimeMetric, 1); histogram_tester().ExpectTotalCount(kWriteKeyBasedCharacteristicResultMetric, 1); histogram_tester().ExpectTotalCount(
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.cc b/ash/quick_pair/keyed_service/quick_pair_mediator.cc index f6cf807..bffbcad 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator.cc +++ b/ash/quick_pair/keyed_service/quick_pair_mediator.cc
@@ -20,6 +20,8 @@ #include "ash/quick_pair/message_stream/message_stream_lookup_impl.h" #include "ash/quick_pair/pairing/pairer_broker_impl.h" #include "ash/quick_pair/pairing/retroactive_pairing_detector_impl.h" +#include "ash/quick_pair/repository/fast_pair/device_id_map.h" +#include "ash/quick_pair/repository/fast_pair/device_image_store.h" #include "ash/quick_pair/repository/fast_pair/pending_write_store.h" #include "ash/quick_pair/repository/fast_pair/saved_device_registry.h" #include "ash/quick_pair/repository/fast_pair_repository_impl.h" @@ -115,8 +117,8 @@ // static void Mediator::RegisterLocalStatePrefs(PrefRegistrySimple* registry) { - // TODO(dclasson): register future local state prefs here. - return; + DeviceIdMap::RegisterLocalStatePrefs(registry); + DeviceImageStore::RegisterLocalStatePrefs(registry); } chromeos::bluetooth_config::FastPairDelegate* Mediator::GetFastPairDelegate() {
diff --git a/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc b/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc index 7999402..53c3f1a 100644 --- a/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc +++ b/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc
@@ -63,14 +63,15 @@ const char kFastPairPairResultMetricRetroactive[] = "Bluetooth.ChromeOS.FastPair.Pairing.Result.RetroactivePairingProtocol"; const char kFastPairAccountKeyWriteResultMetricInitial[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result.InitialPairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result." + "InitialPairingProtocol"; const char kFastPairAccountKeyWriteResultMetricRetroactive[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result." + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result." "RetroactivePairingProtocol"; const char kFastPairAccountKeyWriteFailureMetricInitial[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyFailure.InitialPairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Failure.InitialPairingProtocol"; const char kFastPairAccountKeyWriteFailureMetricRetroactive[] = - "Bluetooth.ChromeOS.FastPair.AccountKeyFailure.RetroactivePairingProtocol"; + "Bluetooth.ChromeOS.FastPair.AccountKey.Failure.RetroactivePairingProtocol"; constexpr char kTestDeviceAddress[] = "11:12:13:14:15:16"; constexpr char kTestBleDeviceName[] = "Test Device Name";
diff --git a/ash/quick_pair/message_stream/message_stream.cc b/ash/quick_pair/message_stream/message_stream.cc index e419eb7..066a1cf 100644 --- a/ash/quick_pair/message_stream/message_stream.cc +++ b/ash/quick_pair/message_stream/message_stream.cc
@@ -4,6 +4,7 @@ #include "ash/quick_pair/message_stream/message_stream.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" #include "ash/quick_pair/common/logging.h" #include "ash/services/quick_pair/quick_pair_process.h" #include "ash/services/quick_pair/quick_pair_process_manager.h" @@ -65,6 +66,7 @@ void MessageStream::ReceiveDataSuccess(int buffer_size, scoped_refptr<net::IOBuffer> io_buffer) { + RecordMessageStreamReceiveResult(/*success=*/true); receive_retry_counter_ = 0; if (!io_buffer->data()) { @@ -89,6 +91,8 @@ void MessageStream::ReceiveDataError(device::BluetoothSocket::ErrorReason error, const std::string& error_message) { QP_LOG(INFO) << __func__ << ": Error: " << error_message; + RecordMessageStreamReceiveResult(/*success=*/false); + RecordMessageStreamReceiveError(error); if (error == device::BluetoothSocket::ErrorReason::kDisconnected) { OnSocketDisconnected();
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc index d9180ddd..575e610 100644 --- a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc +++ b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc
@@ -5,6 +5,7 @@ #include "ash/quick_pair/message_stream/message_stream_lookup_impl.h" #include "ash/quick_pair/common/constants.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" #include "ash/quick_pair/common/logging.h" #include "base/containers/contains.h" #include "device/bluetooth/bluetooth_adapter_factory.h" @@ -103,7 +104,8 @@ device->ConnectToService( /*uuid=*/kMessageStreamUuid, /*callback=*/ base::BindOnce(&MessageStreamLookupImpl::OnConnected, - weak_ptr_factory_.GetWeakPtr(), device_address), + weak_ptr_factory_.GetWeakPtr(), device_address, + base::TimeTicks::Now()), /*error_callback=*/ base::BindOnce(&MessageStreamLookupImpl::OnConnectError, weak_ptr_factory_.GetWeakPtr())); @@ -111,8 +113,13 @@ void MessageStreamLookupImpl::OnConnected( std::string device_address, + base::TimeTicks connect_to_service_start_time, scoped_refptr<device::BluetoothSocket> socket) { QP_LOG(VERBOSE) << __func__; + RecordMessageStreamConnectToServiceResult(/*success=*/true); + RecordMessageStreamConnectToServiceTime(base::TimeTicks::Now() - + connect_to_service_start_time); + std::unique_ptr<MessageStream> message_stream = std::make_unique<MessageStream>(device_address, std::move(socket)); @@ -124,6 +131,8 @@ void MessageStreamLookupImpl::OnConnectError(const std::string& error_message) { QP_LOG(INFO) << __func__ << ": Error = [ " << error_message << "]."; + RecordMessageStreamConnectToServiceResult(/*success=*/false); + RecordMessageStreamConnectToServiceError(error_message); } } // namespace quick_pair
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl.h b/ash/quick_pair/message_stream/message_stream_lookup_impl.h index 5908e5a..3381519 100644 --- a/ash/quick_pair/message_stream/message_stream_lookup_impl.h +++ b/ash/quick_pair/message_stream/message_stream_lookup_impl.h
@@ -14,6 +14,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" +#include "base/time/time.h" #include "device/bluetooth/bluetooth_adapter.h" namespace device { @@ -53,6 +54,7 @@ // Create RFCOMM connection callbacks. void OnConnected(std::string device_address, + base::TimeTicks connect_to_service_start_time, scoped_refptr<device::BluetoothSocket> socket); void OnConnectError(const std::string& error_message);
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_unittest.cc b/ash/quick_pair/message_stream/message_stream_lookup_unittest.cc index afa93d3..16ea2d7c 100644 --- a/ash/quick_pair/message_stream/message_stream_lookup_unittest.cc +++ b/ash/quick_pair/message_stream/message_stream_lookup_unittest.cc
@@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_socket.h" @@ -27,6 +28,14 @@ const device::BluetoothUUID kMessageStreamUuid( "df21fe2c-2515-4fdb-8886-f12c4d67927c"); +const char kMessageStreamConnectToServiceError[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.ErrorReason"; +const char kMessageStreamConnectToServiceResult[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.Result"; +const char kMessageStreamConnectToServiceTime[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService." + "TotalConnectTime"; + } // namespace namespace ash { @@ -124,8 +133,11 @@ message_stream_ = message_stream; } + base::HistogramTester& histogram_tester() { return histogram_tester_; } + protected: base::test::SingleThreadTaskEnvironment task_enviornment_; + base::HistogramTester histogram_tester_; MessageStream* message_stream_ = nullptr; scoped_refptr<MessageStreamFakeBluetoothAdapter> adapter_; MessageStreamFakeBluetoothDevice* device_; @@ -133,15 +145,27 @@ }; TEST_F(MessageStreamLookupTest, ConnectDevice_NoMessageStreamUUid) { + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 0); + SetConnectToServiceError(); EXPECT_EQ(GetMessageStream(), nullptr); NotifyDeviceConnectedStateChanged(/*is_now_connected=*/true); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GetMessageStream(), nullptr); + + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 0); } TEST_F(MessageStreamLookupTest, ConnectDevice_ConnectToServiceFailure) { + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 0); + device_->AddUUID(kMessageStreamUuid); SetConnectToServiceError(); @@ -149,15 +173,27 @@ NotifyDeviceConnectedStateChanged(/*is_now_connected=*/true); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GetMessageStream(), nullptr); + + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 1); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 1); } TEST_F(MessageStreamLookupTest, ConnectDevice_ConnectToServiceSuccess) { + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 0); + device_->AddUUID(kMessageStreamUuid); EXPECT_EQ(GetMessageStream(), nullptr); NotifyDeviceConnectedStateChanged(/*is_now_connected=*/true); base::RunLoop().RunUntilIdle(); EXPECT_NE(GetMessageStream(), nullptr); + + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceError, 0); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceTime, 1); + histogram_tester().ExpectTotalCount(kMessageStreamConnectToServiceResult, 1); } TEST_F(MessageStreamLookupTest,
diff --git a/ash/quick_pair/message_stream/message_stream_unittest.cc b/ash/quick_pair/message_stream/message_stream_unittest.cc index f77005d1..0fb5e385 100644 --- a/ash/quick_pair/message_stream/message_stream_unittest.cc +++ b/ash/quick_pair/message_stream/message_stream_unittest.cc
@@ -16,6 +16,7 @@ #include "base/callback.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "device/bluetooth/bluetooth_socket.h" #include "testing/gtest/include/gtest/gtest.h" @@ -96,6 +97,11 @@ constexpr int kMessageStorageCapacity = 1000; constexpr char kTestDeviceAddress[] = "11:12:13:14:15:16"; +const char kMessageStreamReceiveResultMetric[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.Receive.Result"; +const char kMessageStreamReceiveErrorMetric[] = + "Bluetooth.ChromeOS.FastPair.MessageStream.Receive.ErrorReason"; + } // namespace namespace ash { @@ -207,7 +213,10 @@ sdk_version_ = sdk_version; } + base::HistogramTester& histogram_tester() { return histogram_tester_; } + protected: + base::HistogramTester histogram_tester_; scoped_refptr<FakeBluetoothSocket> fake_socket_ = base::MakeRefCounted<FakeBluetoothSocket>(); std::unique_ptr<MessageStream> message_stream_; @@ -231,6 +240,9 @@ }; TEST_F(MessageStreamTest, ReceiveMessages_Observation_SuccessfulMessage) { + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 0); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 0); + EXPECT_TRUE(model_id_.empty()); EXPECT_TRUE(message_stream_->messages().empty()); @@ -241,9 +253,15 @@ EXPECT_EQ(model_id_, kModelIdString); EXPECT_FALSE(message_stream_->messages().empty()); + + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 1); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 0); } TEST_F(MessageStreamTest, ReceiveMessages_Observation_NullMessage) { + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 0); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 0); + EXPECT_TRUE(model_id_.empty()); EXPECT_TRUE(message_stream_->messages().empty()); @@ -254,6 +272,9 @@ EXPECT_TRUE(message_stream_->messages().empty()); EXPECT_TRUE(model_id_.empty()); + + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 1); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 0); } TEST_F(MessageStreamTest, ReceiveMessages_GetMessages) { @@ -284,6 +305,9 @@ } TEST_F(MessageStreamTest, ReceiveMessages_SocketDisconnect) { + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 0); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 0); + EXPECT_FALSE(on_socket_disconnected_); EXPECT_TRUE(message_stream_->messages().empty()); @@ -295,6 +319,9 @@ EXPECT_TRUE(message_stream_->messages().empty()); EXPECT_TRUE(on_socket_disconnected_); + + histogram_tester().ExpectTotalCount(kMessageStreamReceiveResultMetric, 1); + histogram_tester().ExpectTotalCount(kMessageStreamReceiveErrorMetric, 1); } TEST_F(MessageStreamTest, ReceiveMessages_FailureAfterMaxRetries) {
diff --git a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.cc b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.cc index 056208f9..c29dadfa 100644 --- a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.cc +++ b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/system_tray_client.h" #include "ash/quick_pair/common/account_key_failure.h" #include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" #include "ash/quick_pair/common/logging.h" #include "ash/quick_pair/common/pair_failure.h" #include "ash/quick_pair/common/protocol.h" @@ -196,22 +197,28 @@ void FastPairPairer::OnPasskeyResponse(std::vector<uint8_t> response_bytes, absl::optional<PairFailure> failure) { + RecordWritePasskeyCharacteristicResult(/*success=*/!failure.has_value()); + if (failure) { + RecordWritePasskeyCharacteristicPairFailure(failure.value()); std::move(pair_failed_callback_).Run(device_, failure.value()); return; } fast_pair_handshake_->fast_pair_data_encryptor()->ParseDecryptedPasskey( - response_bytes, base::BindOnce(&FastPairPairer::OnParseDecryptedPasskey, - weak_ptr_factory_.GetWeakPtr())); + response_bytes, + base::BindOnce(&FastPairPairer::OnParseDecryptedPasskey, + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); } void FastPairPairer::OnParseDecryptedPasskey( + base::TimeTicks decrypt_start_time, const absl::optional<DecryptedPasskey>& passkey) { if (!passkey) { QP_LOG(WARNING) << "Missing decrypted passkey from parse."; std::move(pair_failed_callback_) .Run(device_, PairFailure::kPasskeyDecryptFailure); + RecordPasskeyCharacteristicDecryptResult(/*success=*/false); return; } @@ -222,6 +229,7 @@ << ". Actual: " << MessageTypeToString(passkey->message_type); std::move(pair_failed_callback_) .Run(device_, PairFailure::kIncorrectPasskeyResponseType); + RecordPasskeyCharacteristicDecryptResult(/*success=*/false); return; } @@ -230,9 +238,14 @@ << ". Actual: " << passkey->passkey; std::move(pair_failed_callback_) .Run(device_, PairFailure::kPasskeyMismatch); + RecordPasskeyCharacteristicDecryptResult(/*success=*/false); return; } + RecordPasskeyCharacteristicDecryptResult(/*success=*/true); + RecordPasskeyCharacteristicDecryptTime(base::TimeTicks::Now() - + decrypt_start_time); + device::BluetoothDevice* pairing_device = adapter_->GetDevice(pairing_device_address_); @@ -270,6 +283,8 @@ void FastPairPairer::OnWriteAccountKey( std::array<uint8_t, 16> account_key, absl::optional<device::BluetoothGattService::GattErrorCode> error) { + RecordWriteAccountKeyCharacteristicResult(/*success=*/!error.has_value()); + if (error) { QP_LOG(WARNING) << "Failed to write account key to device due to Gatt Error: "
diff --git a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.h b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.h index 6865967..72c6397 100644 --- a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.h +++ b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer.h
@@ -13,6 +13,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" +#include "base/time/time.h" #include "device/bluetooth/bluetooth_device.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -83,7 +84,8 @@ absl::optional<PairFailure> failure); // FastPairDataEncryptor::ParseDecryptedPasskey callback - void OnParseDecryptedPasskey(const absl::optional<DecryptedPasskey>& passkey); + void OnParseDecryptedPasskey(base::TimeTicks decrypt_start_time, + const absl::optional<DecryptedPasskey>& passkey); // Creates a 16-byte array of random bytes with a first byte of 0x04 to // signal Fast Pair account key, and then writes to the device.
diff --git a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_unittest.cc b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_unittest.cc index d4a07b36..d0b1efac 100644 --- a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_unittest.cc +++ b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_unittest.cc
@@ -32,6 +32,7 @@ #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "device/bluetooth/test/mock_bluetooth_adapter.h" @@ -65,6 +66,17 @@ constexpr char kDeviceName[] = "test_device_name"; constexpr char kBluetoothCanonicalizedAddress[] = "0C:0E:4C:C8:05:08"; +const char kWritePasskeyCharacteristicResultMetric[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.Result"; +const char kWritePasskeyCharacteristicPairFailureMetric[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Write.PairFailure"; +const char kPasskeyCharacteristicDecryptTime[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Time"; +const char kPasskeyCharacteristicDecryptResult[] = + "Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Result"; +const char kWriteAccountKeyCharacteristicResultMetric[] = + "Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result"; + class FakeBluetoothAdapter : public testing::NiceMock<device::MockBluetoothAdapter> { public: @@ -221,6 +233,8 @@ return fake; } + base::HistogramTester& histogram_tester() { return histogram_tester_; } + void SetDecryptResponseForIncorrectMessageType() { DecryptedResponse response(FastPairMessageType::kSeekersPasskey, kAddressBytes, kRequestSaltBytes); @@ -308,6 +322,7 @@ pairing_procedure_complete_; FakeFastPairRepository fast_pair_repository_; std::unique_ptr<FastPairPairer> pairer_; + base::HistogramTester histogram_tester_; FakeFastPairGattServiceClient* gatt_service_client_ = nullptr; FakeFastPairDataEncryptor* data_encryptor_ = nullptr; @@ -392,25 +407,47 @@ } TEST_F(FastPairPairerTest, SuccessfulDecryptedResponseConnectSuccess_Initial) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); CreatePairer(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GetPairFailure(), absl::nullopt); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); } TEST_F(FastPairPairerTest, SuccessfulDecryptedResponseConnectSuccess_Subsequent) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); CreatePairer(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GetPairFailure(), absl::nullopt); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyFailure_Initial) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -421,9 +458,21 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback({}, PairFailure::kPasskeyPairingCharacteristicWrite); EXPECT_EQ(GetPairFailure(), PairFailure::kPasskeyPairingCharacteristicWrite); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 1); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyFailure_Subsequent) { + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 0); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); @@ -434,9 +483,17 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback({}, PairFailure::kPasskeyPairingCharacteristicWrite); EXPECT_EQ(GetPairFailure(), PairFailure::kPasskeyPairingCharacteristicWrite); + histogram_tester().ExpectTotalCount(kWritePasskeyCharacteristicResultMetric, + 1); + histogram_tester().ExpectTotalCount( + kWritePasskeyCharacteristicPairFailureMetric, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyIncorrectMessageType_Initial) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -448,10 +505,14 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kIncorrectPasskeyResponseType); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyIncorrectMessageType_Subsequent) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); @@ -463,9 +524,13 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kIncorrectPasskeyResponseType); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyMismatch_Initial) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -477,9 +542,13 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kPasskeyMismatch); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, ParseDecryptedPasskeyMismatch_Subsequent) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); @@ -491,9 +560,13 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kPasskeyMismatch); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, PairedDeviceLost_Initial) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -505,9 +578,13 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kPairingDeviceLost); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, PairedDeviceLost_Subsequent) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); @@ -519,9 +596,12 @@ base::RunLoop().RunUntilIdle(); RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), PairFailure::kPairingDeviceLost); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, PairSuccess_Initial) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -536,9 +616,13 @@ RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), absl::nullopt); EXPECT_TRUE(IsDevicePaired()); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, PairSuccess_Subsequent) { + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 0); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairSubsequent); SetGetDeviceFailure(); @@ -553,9 +637,13 @@ RunWritePasskeyCallback(kResponseBytes); EXPECT_EQ(GetPairFailure(), absl::nullopt); EXPECT_TRUE(IsDevicePaired()); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptTime, 1); + histogram_tester().ExpectTotalCount(kPasskeyCharacteristicDecryptResult, 1); } TEST_F(FastPairPairerTest, WriteAccountKey_Initial) { + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -574,9 +662,13 @@ EXPECT_CALL(pairing_procedure_complete_, Run); RunWriteAccountKeyCallback(); EXPECT_TRUE(IsAccountKeySavedToFootprints()); + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 1); } TEST_F(FastPairPairerTest, WriteAccountKey_Retroactive) { + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairRetroactive); SetGetDeviceFailure(); @@ -584,9 +676,13 @@ base::RunLoop().RunUntilIdle(); EXPECT_CALL(pairing_procedure_complete_, Run); RunWriteAccountKeyCallback(); + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 1); } TEST_F(FastPairPairerTest, WriteAccountKeyFailure_Initial) { + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairInitial); SetGetDeviceFailure(); @@ -605,6 +701,8 @@ RunWriteAccountKeyCallback( device::BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED); EXPECT_FALSE(IsAccountKeySavedToFootprints()); + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 1); } TEST_F(FastPairPairerTest, FastPairVersionOne) { @@ -615,6 +713,8 @@ } TEST_F(FastPairPairerTest, WriteAccountKeyFailure_Retroactive) { + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 0); SuccessfulDataEncryptorSetUp(/*fast_pair_v1=*/false, /*protocol=*/Protocol::kFastPairRetroactive); SetGetDeviceFailure(); @@ -623,6 +723,8 @@ EXPECT_CALL(account_key_failure_callback_, Run); RunWriteAccountKeyCallback( device::BluetoothGattService::GattErrorCode::GATT_ERROR_FAILED); + histogram_tester().ExpectTotalCount( + kWriteAccountKeyCharacteristicResultMetric, 1); } } // namespace quick_pair
diff --git a/ash/quick_pair/repository/BUILD.gn b/ash/quick_pair/repository/BUILD.gn index a5ceb9d..83da8b0 100644 --- a/ash/quick_pair/repository/BUILD.gn +++ b/ash/quick_pair/repository/BUILD.gn
@@ -9,6 +9,10 @@ source_set("repository") { sources = [ + "fast_pair/device_id_map.cc", + "fast_pair/device_id_map.h", + "fast_pair/device_image_store.cc", + "fast_pair/device_image_store.h", "fast_pair/device_metadata.cc", "fast_pair/device_metadata.h", "fast_pair/device_metadata_fetcher.cc", @@ -42,6 +46,7 @@ "//ash/quick_pair/proto:fastpair_proto", "//ash/services/quick_pair/public/cpp", "//base", + "//chromeos/services/bluetooth_config/public/cpp", "//components/image_fetcher/core", "//components/prefs", "//components/signin/public/identity_manager", @@ -52,6 +57,7 @@ "//services/network/public/cpp", "//services/network/public/mojom:url_loader_base", "//third_party/protobuf:protobuf_lite", + "//ui/base", ] } @@ -84,6 +90,8 @@ testonly = true sources = [ + "fast_pair/device_id_map_unittest.cc", + "fast_pair/device_image_store_unittest.cc", "fast_pair/device_metadata_fetcher_unittest.cc", "fast_pair/pending_write_store_unittest.cc", "fast_pair/saved_device_registry_unittest.cc", @@ -92,13 +100,17 @@ deps = [ ":repository", ":test_support", + "//ash:test_support", "//ash/quick_pair/common", "//ash/quick_pair/common:test_support", "//ash/quick_pair/proto:fastpair_proto", "//base", "//base/test:test_support", + "//chromeos/services/bluetooth_config/public/cpp", "//components/prefs:test_support", + "//device/bluetooth:mocks", "//services/data_decoder/public/cpp:test_support", "//testing/gtest", + "//ui/gfx:test_support", ] }
diff --git a/ash/quick_pair/repository/fast_pair/device_id_map.cc b/ash/quick_pair/repository/fast_pair/device_id_map.cc new file mode 100644 index 0000000..3d8c3a8 --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_id_map.cc
@@ -0,0 +1,199 @@ +// 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/quick_pair/repository/fast_pair/device_id_map.h" + +#include "ash/quick_pair/common/logging.h" +#include "ash/shell.h" +#include "base/values.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" + +namespace ash { +namespace quick_pair { + +// static +constexpr char DeviceIdMap::kDeviceIdMapPref[]; + +// static +void DeviceIdMap::RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + registry->RegisterDictionaryPref(kDeviceIdMapPref); +} + +DeviceIdMap::DeviceIdMap() { + device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce( + &DeviceIdMap::OnGetAdapter, weak_ptr_factory_.GetWeakPtr())); +} + +DeviceIdMap::~DeviceIdMap() = default; + +void DeviceIdMap::SaveModelIdForDevice(scoped_refptr<Device> device) { + // In some cases, BLE and classic address can map to different devices (with + // the same model ID) so we want to capture both device ID -> model ID + // records. + absl::optional<const std::string> ble_device_id = + GetDeviceIdForAddress(device->ble_address); + if (ble_device_id) { + device_id_to_model_id_[ble_device_id.value()] = device->metadata_id; + } + + absl::optional<const std::string> classic_address = device->classic_address(); + if (!classic_address) { + return; + } + + absl::optional<const std::string> classic_device_id = + GetDeviceIdForAddress(classic_address.value()); + if (classic_device_id) { + device_id_to_model_id_[classic_device_id.value()] = device->metadata_id; + } +} + +bool DeviceIdMap::PersistRecordsForDevice(scoped_refptr<Device> device) { + // In some cases, BLE and classic address can map to different devices (with + // the same model ID) so we want to capture both device ID -> model ID + // records. + bool did_persist = false; + absl::optional<const std::string> ble_device_id = + GetDeviceIdForAddress(device->ble_address); + if (ble_device_id) { + did_persist = PersistDeviceIdRecord(ble_device_id.value()); + } + + absl::optional<const std::string> classic_address = device->classic_address(); + if (!classic_address) { + return did_persist; + } + + absl::optional<const std::string> classic_device_id = + GetDeviceIdForAddress(classic_address.value()); + if (classic_device_id) { + did_persist |= PersistDeviceIdRecord(classic_device_id.value()); + } + return did_persist; +} + +bool DeviceIdMap::PersistDeviceIdRecord(const std::string& device_id) { + const std::string& model_id = device_id_to_model_id_[device_id]; + + if (model_id.empty()) { + QP_LOG(WARNING) + << __func__ + << ": Can't persist null device ID -> model ID record for device ID: " + + device_id; + return false; + } + + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return false; + } + + DictionaryPrefUpdate device_id_map_dict(local_state, kDeviceIdMapPref); + if (!device_id_map_dict->SetStringKey(device_id, model_id)) { + QP_LOG(WARNING) + << __func__ + << ": Failed to persist device ID -> model ID record for device ID: " + + device_id; + return false; + } + return true; +} + +bool DeviceIdMap::EvictDeviceIdRecord(const std::string& device_id) { + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return false; + } + + DictionaryPrefUpdate device_id_map_dict(local_state, kDeviceIdMapPref); + if (!device_id_map_dict->RemoveKey(device_id)) { + QP_LOG(WARNING) << __func__ + << ": Failed to evict device ID -> model ID record from " + "prefs for device ID: " + + device_id; + return false; + } + return true; +} + +absl::optional<const std::string> DeviceIdMap::GetModelIdForDeviceId( + const std::string& device_id) { + // Lazily load saved records from prefs the first time we get an ID. + if (!loaded_records_from_prefs_) { + loaded_records_from_prefs_ = true; + LoadPersistedRecordsFromPrefs(); + } + + std::string& saved_model_id = device_id_to_model_id_[device_id]; + if (saved_model_id.empty()) { + return absl::nullopt; + } + return saved_model_id; +} + +bool DeviceIdMap::HasPersistedRecordsForModelId(const std::string& model_id) { + QP_LOG(INFO) << __func__; + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return false; + } + + const base::Value* device_id_map_dict = + local_state->GetDictionary(kDeviceIdMapPref); + for (std::pair<const std::string&, const base::Value&> record : + device_id_map_dict->DictItems()) { + if (record.second.GetString() == model_id) + return true; + } + return false; +} + +void DeviceIdMap::LoadPersistedRecordsFromPrefs() { + QP_LOG(INFO) << __func__; + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return; + } + + const base::Value* device_id_map_dict = + local_state->GetDictionary(kDeviceIdMapPref); + for (std::pair<const std::string&, const base::Value&> record : + device_id_map_dict->DictItems()) { + device_id_to_model_id_[record.first] = record.second.GetString(); + } +} + +void DeviceIdMap::OnGetAdapter( + scoped_refptr<device::BluetoothAdapter> adapter) { + bluetooth_adapter_ = adapter; +} + +absl::optional<const std::string> DeviceIdMap::GetDeviceIdForAddress( + const std::string& address) { + if (!bluetooth_adapter_) { + QP_LOG(WARNING) << __func__ << ": Can't fetch device ID without adapter."; + return absl::nullopt; + } + + const device::BluetoothDevice* device = + bluetooth_adapter_->GetDevice(address); + if (!device) { + QP_LOG(WARNING) << __func__ + << ": Can't find matching bluetooth device for address: " + + address; + return absl::nullopt; + } + return device->GetIdentifier(); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/device_id_map.h b/ash/quick_pair/repository/fast_pair/device_id_map.h new file mode 100644 index 0000000..49386bd --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_id_map.h
@@ -0,0 +1,86 @@ +// 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_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_ID_MAP_H_ +#define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_ID_MAP_H_ + +#include <string> + +#include "ash/quick_pair/common/device.h" +#include "base/containers/flat_map.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace device { +class BluetoothAdapter; +} // namespace device + +class PrefRegistrySimple; + +namespace ash { +namespace quick_pair { + +// Saves a mapping from device ID to model ID. Provides methods to persist +// or evict device ID -> model ID records from local state prefs. Also +// provides convenience methods for adding to the mapping given a device. +class DeviceIdMap { + public: + static constexpr char kDeviceIdMapPref[] = "fast_pair.device_id_map"; + + // Registers preferences used by this class in the provided |registry|. + static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + + DeviceIdMap(); + DeviceIdMap(const DeviceIdMap&) = delete; + DeviceIdMap& operator=(const DeviceIdMap&) = delete; + ~DeviceIdMap(); + + // Saves device ID -> model ID records for the devices matching both + // the BLE and Classic address in memory, stored in device_id_to_model_id. + void SaveModelIdForDevice(scoped_refptr<Device> device); + + // Persists the device ID -> model ID records for |device| + // to local state prefs. Returns true if a record was persisted, false + // otherwise. + bool PersistRecordsForDevice(scoped_refptr<Device> device); + + // Evicts the |device_id| -> model ID record in device_id_to_model_id_ from + // local state prefs. Returns true if the record was + // evicted, false if there was no |device_id| record to evict. + bool EvictDeviceIdRecord(const std::string& device_id); + + // Returns the model ID for |device_id|, or absl::nullopt if a matching + // model ID isn't found. + absl::optional<const std::string> GetModelIdForDeviceId( + const std::string& device_id); + + // Returns true if there are device ID -> |model_id| records in + // local state prefs, false otherwise. + bool HasPersistedRecordsForModelId(const std::string& model_id); + + private: + // Returns the device ID that owns |address|, if found. + absl::optional<const std::string> GetDeviceIdForAddress( + const std::string& address); + // Persists the |device_id| -> model ID record in device_id_to_model_id_ + // to local state prefs. Returns true if the record was persisted, false + // if no record exists for |device_id| or there was an error when persisting. + bool PersistDeviceIdRecord(const std::string& device_id); + // Loads device ID -> model ID records persisted in prefs to + // device_id_to_model_id_. + void LoadPersistedRecordsFromPrefs(); + void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter); + + // Used to lazily load saved records from prefs. + bool loaded_records_from_prefs_ = false; + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; + base::flat_map<std::string, std::string> device_id_to_model_id_; + base::WeakPtrFactory<DeviceIdMap> weak_ptr_factory_{this}; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_ID_MAP_H_
diff --git a/ash/quick_pair/repository/fast_pair/device_id_map_unittest.cc b/ash/quick_pair/repository/fast_pair/device_id_map_unittest.cc new file mode 100644 index 0000000..fd6809f --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_id_map_unittest.cc
@@ -0,0 +1,300 @@ +// 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/quick_pair/repository/fast_pair/device_id_map.h" + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/common/protocol.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/memory/scoped_refptr.h" +#include "base/strings/string_number_conversions.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "device/bluetooth/test/mock_bluetooth_device.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace { + +constexpr char kTestModelId[] = "test_model_id"; +constexpr char kTestBLEAddress[] = "test_ble_address"; +constexpr char kTestBLEDeviceId[] = "test_ble_device_id"; +constexpr char kTestClassicAddress[] = "test_classic_address"; +constexpr char kTestClassicDeviceId[] = "test_classic_device_id"; + +} // namespace + +namespace ash { +namespace quick_pair { + +// For convenience. +using ::testing::Return; + +class DeviceIdMapTest : public AshTestBase { + public: + DeviceIdMapTest() + : adapter_(new testing::NiceMock<device::MockBluetoothAdapter>), + ble_bluetooth_device_(adapter_.get(), + 0, + "Test ble name", + kTestBLEAddress, + false, + true), + classic_bluetooth_device_(adapter_.get(), + 0, + "Test classic name", + kTestClassicAddress, + false, + true) { + ON_CALL(ble_bluetooth_device_, GetIdentifier) + .WillByDefault(Return(kTestBLEDeviceId)); + ON_CALL(classic_bluetooth_device_, GetIdentifier) + .WillByDefault(Return(kTestClassicDeviceId)); + ON_CALL(*adapter_, GetDevice(kTestBLEAddress)) + .WillByDefault(Return(&ble_bluetooth_device_)); + ON_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .WillByDefault(Return(&classic_bluetooth_device_)); + } + + void SetUp() override { + AshTestBase::SetUp(); + + device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); + device_ = base::MakeRefCounted<Device>(kTestModelId, kTestBLEAddress, + Protocol::kFastPairInitial); + device_->set_classic_address(kTestClassicAddress); + device_id_map_ = std::make_unique<DeviceIdMap>(); + } + + protected: + scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> adapter_; + testing::NiceMock<device::MockBluetoothDevice> ble_bluetooth_device_; + testing::NiceMock<device::MockBluetoothDevice> classic_bluetooth_device_; + scoped_refptr<Device> device_; + std::unique_ptr<DeviceIdMap> device_id_map_; +}; + +TEST_F(DeviceIdMapTest, SaveModelIdForDeviceValid) { + device_id_map_->SaveModelIdForDevice(device_); + absl::optional<const std::string> ble_model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_TRUE(ble_model_id); + EXPECT_EQ(ble_model_id.value(), kTestModelId); + absl::optional<const std::string> classic_model_id = + device_id_map_->GetModelIdForDeviceId(kTestClassicDeviceId); + EXPECT_TRUE(classic_model_id); + EXPECT_EQ(classic_model_id.value(), kTestModelId); +} + +TEST_F(DeviceIdMapTest, SaveModelIdForDeviceValidOnlyClassicAddress) { + // Pretend adapter can't find the device for the BLE address. + // A record should still be saved for the valid address. + EXPECT_CALL(*adapter_, GetDevice(kTestBLEAddress)).WillOnce(Return(nullptr)); + EXPECT_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .WillOnce(Return(&classic_bluetooth_device_)); + device_id_map_->SaveModelIdForDevice(device_); + absl::optional<const std::string> ble_model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_FALSE(ble_model_id); + absl::optional<const std::string> classic_model_id = + device_id_map_->GetModelIdForDeviceId(kTestClassicDeviceId); + EXPECT_TRUE(classic_model_id); + EXPECT_EQ(classic_model_id.value(), kTestModelId); +} + +TEST_F(DeviceIdMapTest, SaveModelIdForDeviceValidOnlyBLEAddress) { + // Pretend adapter can't find the device for the classic address. + // A record should still be saved for the valid address. + EXPECT_CALL(*adapter_, GetDevice(kTestBLEAddress)) + .WillOnce(Return(&ble_bluetooth_device_)); + EXPECT_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .WillOnce(Return(nullptr)); + device_id_map_->SaveModelIdForDevice(device_); + absl::optional<const std::string> ble_model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_TRUE(ble_model_id); + EXPECT_EQ(ble_model_id.value(), kTestModelId); + absl::optional<const std::string> classic_model_id = + device_id_map_->GetModelIdForDeviceId(kTestClassicDeviceId); + EXPECT_FALSE(classic_model_id); +} + +TEST_F(DeviceIdMapTest, SaveModelIdForDeviceInvalidDeviceNotFound) { + // Pretend adapter can't find the device. + EXPECT_CALL(*adapter_, GetDevice(kTestBLEAddress)).WillOnce(Return(nullptr)); + EXPECT_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .WillOnce(Return(nullptr)); + device_id_map_->SaveModelIdForDevice(device_); + absl::optional<const std::string> ble_model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_FALSE(ble_model_id); + absl::optional<const std::string> classic_model_id = + device_id_map_->GetModelIdForDeviceId(kTestClassicDeviceId); + EXPECT_FALSE(classic_model_id); +} + +TEST_F(DeviceIdMapTest, PersistRecordsForDeviceValid) { + // First, save the device ID records to memory. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + + // Validate that the ID records are persisted to prefs. + PrefService* local_state = Shell::Get()->local_state(); + const base::Value* device_id_map_dict = + local_state->GetDictionary(DeviceIdMap::kDeviceIdMapPref); + EXPECT_TRUE(device_id_map_dict); + const std::string* ble_model_id = + device_id_map_dict->FindStringKey(kTestBLEDeviceId); + EXPECT_TRUE(ble_model_id); + EXPECT_EQ(*ble_model_id, kTestModelId); + const std::string* classic_model_id = + device_id_map_dict->FindStringKey(kTestClassicDeviceId); + EXPECT_TRUE(classic_model_id); + EXPECT_EQ(*classic_model_id, kTestModelId); +} + +TEST_F(DeviceIdMapTest, PersistRecordsForDeviceValidOnlyClassicAddress) { + // Pretend adapter can't find the device for one of the addresses. + // A record should still be saved for the valid address. + EXPECT_CALL(*adapter_, GetDevice(kTestBLEAddress)) + .Times(2) + .WillRepeatedly(Return(nullptr)); + EXPECT_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .Times(2) + .WillRepeatedly(Return(&classic_bluetooth_device_)); + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); +} + +TEST_F(DeviceIdMapTest, PersistRecordsForDeviceValidOnlyBLEAddress) { + // Pretend adapter can't find the device for the BLE address. + // A record should still be saved for the valid address. + EXPECT_CALL(*adapter_, GetDevice(kTestBLEAddress)) + .Times(2) + .WillRepeatedly(Return(&ble_bluetooth_device_)); + EXPECT_CALL(*adapter_, GetDevice(kTestClassicAddress)) + .Times(2) + .WillRepeatedly(Return(nullptr)); + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); +} + +TEST_F(DeviceIdMapTest, PersistRecordsForDeviceValidDoublePersist) { + // First, save the device ID records to memory. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + + // When persisting a second time, should overwrite record and + // still return true. + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); +} + +TEST_F(DeviceIdMapTest, PersistRecordsForDeviceInvalidNotSaved) { + // Don't save the device ID record to memory. + EXPECT_FALSE(device_id_map_->PersistRecordsForDevice(device_)); +} + +TEST_F(DeviceIdMapTest, EvictDeviceIdRecordValid) { + // First, persist the device ID record to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + EXPECT_TRUE(device_id_map_->EvictDeviceIdRecord(kTestBLEDeviceId)); + + // Validate that the ID records are evicted from prefs. + PrefService* local_state = Shell::Get()->local_state(); + const base::Value* device_id_map_dict = + local_state->GetDictionary(DeviceIdMap::kDeviceIdMapPref); + EXPECT_TRUE(device_id_map_dict); + const std::string* model_id = + device_id_map_dict->FindStringKey(kTestBLEDeviceId); + EXPECT_FALSE(model_id); +} + +TEST_F(DeviceIdMapTest, EvictDeviceIdRecordInvalidDeviceId) { + // Don't save the device ID records to disk. + EXPECT_FALSE(device_id_map_->EvictDeviceIdRecord(kTestBLEDeviceId)); +} + +TEST_F(DeviceIdMapTest, EvictDeviceIdRecordInvalidDoubleFree) { + // First, persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + EXPECT_TRUE(device_id_map_->EvictDeviceIdRecord(kTestBLEDeviceId)); + + // The second evict should fail. + EXPECT_FALSE(device_id_map_->EvictDeviceIdRecord(kTestBLEDeviceId)); +} + +TEST_F(DeviceIdMapTest, GetModelIdForDeviceIdValid) { + device_id_map_->SaveModelIdForDevice(device_); + + absl::optional<const std::string> model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_TRUE(model_id); + EXPECT_EQ(model_id.value(), kTestModelId); +} + +TEST_F(DeviceIdMapTest, GetModelIdForDeviceIdInvalidUninitialized) { + // Don't initialize the dictionary with any results. + absl::optional<const std::string> model_id = + device_id_map_->GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_FALSE(model_id); +} + +TEST_F(DeviceIdMapTest, GetModelIdForDeviceIdInvalidNotAdded) { + device_id_map_->SaveModelIdForDevice(device_); + + absl::optional<const std::string> model_id = + device_id_map_->GetModelIdForDeviceId("not found id"); + EXPECT_FALSE(model_id); +} + +TEST_F(DeviceIdMapTest, HasPersistedRecordsForModelIdTrueAfterPersist) { + // First, persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + EXPECT_TRUE(device_id_map_->HasPersistedRecordsForModelId(kTestModelId)); +} + +TEST_F(DeviceIdMapTest, HasPersistedRecordsForModelIdTrueAfterOneEviction) { + // First, persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + // Evict one of the records that points to this model ID. + EXPECT_TRUE(device_id_map_->EvictDeviceIdRecord(kTestClassicDeviceId)); + EXPECT_TRUE(device_id_map_->HasPersistedRecordsForModelId(kTestModelId)); +} + +TEST_F(DeviceIdMapTest, HasPersistedRecordsForModelIdFalseAfterAllEvictions) { + // First, persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + // Evict all of the records that points to this model ID. + EXPECT_TRUE(device_id_map_->EvictDeviceIdRecord(kTestClassicDeviceId)); + EXPECT_TRUE(device_id_map_->EvictDeviceIdRecord(kTestBLEDeviceId)); + EXPECT_FALSE(device_id_map_->HasPersistedRecordsForModelId(kTestModelId)); +} + +TEST_F(DeviceIdMapTest, HasPersistedRecordsForModelIdFalseNoPersist) { + // Don't persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_FALSE(device_id_map_->HasPersistedRecordsForModelId(kTestModelId)); +} + +TEST_F(DeviceIdMapTest, LoadPersistedIdRecordFromPrefs) { + // First, persist the device ID records to disk. + device_id_map_->SaveModelIdForDevice(device_); + EXPECT_TRUE(device_id_map_->PersistRecordsForDevice(device_)); + + // A new/restarted DeviceIdMap instance should load persisted ID records + // from prefs. + DeviceIdMap new_device_id_map; + absl::optional<const std::string> model_id = + new_device_id_map.GetModelIdForDeviceId(kTestBLEDeviceId); + EXPECT_TRUE(model_id); + EXPECT_EQ(model_id.value(), kTestModelId); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store.cc b/ash/quick_pair/repository/fast_pair/device_image_store.cc new file mode 100644 index 0000000..34b3c7d --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_image_store.cc
@@ -0,0 +1,162 @@ +// 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/quick_pair/repository/fast_pair/device_image_store.h" + +#include "ash/quick_pair/common/logging.h" +#include "ash/shell.h" +#include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" +#include "ui/base/webui/web_ui_util.h" + +namespace ash { +namespace quick_pair { + +// Alias DeviceImageInfo for convenience. +using chromeos::bluetooth_config::DeviceImageInfo; + +// static +constexpr char DeviceImageStore::kDeviceImageStorePref[]; + +// static +void DeviceImageStore::RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + registry->RegisterDictionaryPref(kDeviceImageStorePref); +} + +DeviceImageStore::DeviceImageStore() = default; + +DeviceImageStore::~DeviceImageStore() = default; + +void DeviceImageStore::SaveDeviceImages( + const std::string& model_id, + DeviceMetadata* device_metadata, + SaveDeviceImagesCallback on_images_saved_callback) { + DCHECK(device_metadata); + DeviceImageInfo& images = model_id_to_images_[model_id]; + + if (images.default_image().empty() && !device_metadata->image().IsEmpty()) { + SaveImageAsBase64(model_id, DeviceImageType::kDefault, + std::move(on_images_saved_callback), + device_metadata->image()); + } else { + QP_LOG(WARNING) << __func__ << ": No default device image to save."; + std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kFailure); + } +} + +bool DeviceImageStore::PersistDeviceImages(const std::string& model_id) { + chromeos::bluetooth_config::DeviceImageInfo& images = + model_id_to_images_[model_id]; + + if (!DeviceImageInfoHasImages(images)) { + QP_LOG(WARNING) + << __func__ + << ": Attempted to persist non-existent images for model ID: " + + model_id; + return false; + } + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return false; + } + DictionaryPrefUpdate device_image_store(local_state, kDeviceImageStorePref); + // TODO(dclasson): Once we add TrueWireless support, need to modify this to + // merge new & persisted images objects. + if (!device_image_store->SetKey(model_id, images.ToDictionaryValue())) { + QP_LOG(WARNING) << __func__ + << ": Failed to persist images to prefs for model ID: " + + model_id; + return false; + } + return true; +} + +bool DeviceImageStore::EvictDeviceImages(const std::string& model_id) { + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return false; + } + DictionaryPrefUpdate device_image_store(local_state, kDeviceImageStorePref); + if (!device_image_store->RemoveKey(model_id)) { + QP_LOG(WARNING) << __func__ + << ": Failed to evict images from prefs for model ID: " + + model_id; + return false; + } + return true; +} + +absl::optional<const chromeos::bluetooth_config::DeviceImageInfo> +DeviceImageStore::GetImagesForDeviceModel(const std::string& model_id) { + // Lazily load saved images from prefs the first time we get an image. + if (!loaded_images_from_prefs_) { + loaded_images_from_prefs_ = true; + LoadPersistedImagesFromPrefs(); + } + + chromeos::bluetooth_config::DeviceImageInfo& images = + model_id_to_images_[model_id]; + + if (!DeviceImageInfoHasImages(images)) { + return absl::nullopt; + } + return images; +} + +void DeviceImageStore::LoadPersistedImagesFromPrefs() { + PrefService* local_state = Shell::Get()->local_state(); + if (!local_state) { + QP_LOG(WARNING) << __func__ << ": No shell local state available."; + return; + } + const base::Value* device_image_store = + local_state->GetDictionary(kDeviceImageStorePref); + for (std::pair<const std::string&, const base::Value&> record : + device_image_store->DictItems()) { + absl::optional<chromeos::bluetooth_config::DeviceImageInfo> images = + chromeos::bluetooth_config::DeviceImageInfo::FromDictionaryValue( + record.second); + if (!images) { + QP_LOG(WARNING) << __func__ + << ": Failed to load persisted images from prefs."; + continue; + } + model_id_to_images_[record.first] = images.value(); + } +} + +bool DeviceImageStore::DeviceImageInfoHasImages( + const DeviceImageInfo& images) const { + return !images.default_image_.empty() || !images.left_bud_image_.empty() || + !images.right_bud_image_.empty() || !images.case_image_.empty(); +} + +void DeviceImageStore::SaveImageAsBase64( + const std::string& model_id, + DeviceImageType image_type, + SaveDeviceImagesCallback on_images_saved_callback, + gfx::Image image) { + // Encode the image as a base64 data URL. + std::string encoded_image = webui::GetBitmapDataUrl(image.AsBitmap()); + + // Save the image in the correct path. + if (image_type == DeviceImageType::kDefault) { + model_id_to_images_[model_id].default_image_ = encoded_image; + } else { + QP_LOG(WARNING) << __func__ + << ": Can't save device image to invalid image field."; + std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kFailure); + return; + } + + // Once successfully saved, return success. + std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kSuccess); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store.h b/ash/quick_pair/repository/fast_pair/device_image_store.h new file mode 100644 index 0000000..0978f33 --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_image_store.h
@@ -0,0 +1,105 @@ +// 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_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_IMAGE_STORE_H_ +#define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_IMAGE_STORE_H_ + +#include <string> +#include <vector> + +#include "ash/quick_pair/repository/fast_pair/device_metadata.h" +#include "base/callback.h" +#include "base/values.h" +#include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/gfx/image/image.h" + +class PrefRegistrySimple; + +namespace ash { +namespace quick_pair { + +// Saves any discovered device images in a flat_map model_id_to_images_. +// Images are saved in DeviceImageInfo objects and are loaded from prefs on +// creation. Images can be persisted to prefs (i.e. on device pair) or +// evicted from prefs (i.e. on device unpair). Images can be retrieved +// given a model_id. +class DeviceImageStore { + public: + static constexpr char kDeviceImageStorePref[] = + "fast_pair.device_image_store"; + + // Corresponds to the types of device images that we currently support. Used + // to keep track of pending downloads. + // kNotSupportedType is an error state that signifies that the image is not a + // supported type. + enum class DeviceImageType { kNotSupportedType = 0, kDefault = 1 }; + + // Corresponds to the status of a SaveDeviceImages call. + enum class SaveDeviceImagesResult { kSuccess = 0, kFailure = 1 }; + + // Returns the type of image that was was saved, i.e. + // DeviceImageInfo::DeviceImageType::kDefault for default image, on success. + // If images already exist or there are any errors, return empty kNone. + using SaveDeviceImagesCallback = + base::OnceCallback<void(SaveDeviceImagesResult)>; + + // Registers preferences used by this class in the provided |registry|. + static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + + DeviceImageStore(); + DeviceImageStore(const DeviceImageStore&) = delete; + DeviceImageStore& operator=(const DeviceImageStore&) = delete; + ~DeviceImageStore(); + + // Saves the device images stored in |device_metadata| to model_id_to_images_, + // mapped to by |model_id|, if there are images. + void SaveDeviceImages(const std::string& model_id, + DeviceMetadata* device_metadata, + SaveDeviceImagesCallback on_images_saved_callback); + + // Persists the DeviceImageInfo for |model_id| in model_id_to_images_ + // to local state prefs. Returns true if images were persisted, false + // if |model_id| has no saved images or there was an error when persisting. + bool PersistDeviceImages(const std::string& model_id); + + // Evicts the DeviceImageInfo corresponding to |model_id| in + // model_id_to_images_ from local state prefs. Returns true if |model_id| is + // evicted from prefs, false otherwise. + bool EvictDeviceImages(const std::string& model_id); + + // Returns a DeviceImageInfo of device images belonging to |model_id|, if + // found. + absl::optional<const chromeos::bluetooth_config::DeviceImageInfo> + GetImagesForDeviceModel(const std::string& model_id); + + private: + // Loads device images stored in prefs to model_id_to_images_. + void LoadPersistedImagesFromPrefs(); + + // Returns true if |images| contains at least one image, false otherwise. + bool DeviceImageInfoHasImages( + const chromeos::bluetooth_config::DeviceImageInfo& images) const; + + // Callee ensures |image| is not empty. Encodes |image| as a base64 data URL + // and saves it to the DeviceImageInfo belonging to |model_id| in field + // |image_type|. Invokes |on_images_saved_callback| with the + // |image_type| where the image was saved on success, empty string + // otherwise. + void SaveImageAsBase64(const std::string& model_id, + DeviceImageType image_type, + SaveDeviceImagesCallback on_images_saved_callback, + gfx::Image image); + + // Maps from model IDs to images stored in DeviceImageInfo. + base::flat_map<std::string, chromeos::bluetooth_config::DeviceImageInfo> + model_id_to_images_; + // Used to lazily load images from prefs. + bool loaded_images_from_prefs_ = false; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_IMAGE_STORE_H_
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc b/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc new file mode 100644 index 0000000..14ca8042 --- /dev/null +++ b/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc
@@ -0,0 +1,180 @@ +// 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/quick_pair/repository/fast_pair/device_image_store.h" + +#include "ash/quick_pair/proto/fastpair.pb.h" +#include "ash/quick_pair/repository/fast_pair/device_metadata.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/callback_helpers.h" +#include "base/test/mock_callback.h" +#include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h" +#include "components/prefs/pref_service.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/base/webui/web_ui_util.h" +#include "ui/gfx/image/image_unittest_util.h" + +namespace { + +constexpr char kTestModelId[] = "ABC123"; + +} // namespace + +namespace ash { +namespace quick_pair { + +// Alias DeviceImageInfo for convenience. +using chromeos::bluetooth_config::DeviceImageInfo; + +class DeviceImageStoreTest : public AshTestBase { + public: + void SetUp() override { + AshTestBase::SetUp(); + + nearby::fastpair::GetObservedDeviceResponse response; + test_image_ = gfx::test::CreateImage(100, 100); + device_metadata_ = + std::make_unique<DeviceMetadata>(std::move(response), test_image_); + + device_image_store_ = std::make_unique<DeviceImageStore>(); + } + + protected: + std::unique_ptr<DeviceMetadata> device_metadata_; + gfx::Image test_image_; + std::unique_ptr<DeviceImageStore> device_image_store_; +}; + +TEST_F(DeviceImageStoreTest, SaveDeviceImagesValid) { + base::MockCallback< + base::OnceCallback<void(DeviceImageStore::SaveDeviceImagesResult)>> + callback; + EXPECT_CALL(callback, + Run(DeviceImageStore::SaveDeviceImagesResult::kSuccess)); + + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + callback.Get()); +} + +TEST_F(DeviceImageStoreTest, SaveDeviceImagesInvalidDeviceImage) { + base::MockCallback< + base::OnceCallback<void(DeviceImageStore::SaveDeviceImagesResult)>> + callback; + EXPECT_CALL(callback, + Run(DeviceImageStore::SaveDeviceImagesResult::kFailure)); + + nearby::fastpair::GetObservedDeviceResponse response; + DeviceMetadata empty_image_metadata = + DeviceMetadata(std::move(response), gfx::Image()); + + device_image_store_->SaveDeviceImages(kTestModelId, &empty_image_metadata, + callback.Get()); +} + +TEST_F(DeviceImageStoreTest, PersistDeviceImagesValid) { + // First, save the device images to memory. + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId)); + + // Validate that the images are persisted to prefs. + PrefService* local_state = Shell::Get()->local_state(); + const base::Value* device_image_store_dict = + local_state->GetDictionary(DeviceImageStore::kDeviceImageStorePref); + EXPECT_TRUE(device_image_store_dict); + const base::Value* images_dict = + device_image_store_dict->FindKey(kTestModelId); + EXPECT_TRUE(images_dict); + const std::string* persisted_image = images_dict->FindStringKey("Default"); + std::string expected_encoded_image = + webui::GetBitmapDataUrl(test_image_.AsBitmap()); + EXPECT_EQ(*persisted_image, expected_encoded_image); +} + +TEST_F(DeviceImageStoreTest, PersistDeviceImagesInvalidModelId) { + // Don't save the device images to memory. + EXPECT_FALSE(device_image_store_->PersistDeviceImages(kTestModelId)); +} + +TEST_F(DeviceImageStoreTest, EvictDeviceImagesValid) { + // First, persist the device images to disk. + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId)); + EXPECT_TRUE(device_image_store_->EvictDeviceImages(kTestModelId)); + + // Validate that the images are evicted from prefs. + PrefService* local_state = Shell::Get()->local_state(); + const base::Value* device_image_store_dict = + local_state->GetDictionary(DeviceImageStore::kDeviceImageStorePref); + EXPECT_TRUE(device_image_store_dict); + const base::Value* images_dict = + device_image_store_dict->FindKey(kTestModelId); + EXPECT_FALSE(images_dict); +} + +TEST_F(DeviceImageStoreTest, EvictDeviceImagesInvalidModelId) { + // Don't persist the device images to disk. + EXPECT_FALSE(device_image_store_->EvictDeviceImages(kTestModelId)); +} + +TEST_F(DeviceImageStoreTest, EvictDeviceImagesInvalidDoubleFree) { + // First, persist the device images to disk. + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId)); + EXPECT_TRUE(device_image_store_->EvictDeviceImages(kTestModelId)); + + // The second evict should fail. + EXPECT_FALSE(device_image_store_->EvictDeviceImages(kTestModelId)); +} + +TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelValid) { + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + + absl::optional<const DeviceImageInfo> images = + device_image_store_->GetImagesForDeviceModel(kTestModelId); + EXPECT_TRUE(images); + + const std::string default_image = images->default_image(); + EXPECT_FALSE(default_image.empty()); + + std::string expected_encoded_image = + webui::GetBitmapDataUrl(test_image_.AsBitmap()); + EXPECT_EQ(default_image, expected_encoded_image); +} + +TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelInvalidUninitialized) { + // Don't initialize the dictionary with any results. + absl::optional<const DeviceImageInfo> images = + device_image_store_->GetImagesForDeviceModel(kTestModelId); + EXPECT_FALSE(images); +} + +TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelInvalidNotAdded) { + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + // Look for a model ID that wasn't added. + absl::optional<const DeviceImageInfo> images = + device_image_store_->GetImagesForDeviceModel("DEF456"); + EXPECT_FALSE(images); +} + +TEST_F(DeviceImageStoreTest, LoadPersistedImagesFromPrefs) { + // First, persist the device images to disk. + device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(), + base::DoNothing()); + device_image_store_->PersistDeviceImages(kTestModelId); + + // A new/restarted DeviceImageStore instance should load persisted images + // from prefs. + DeviceImageStore new_device_image_store; + EXPECT_TRUE(new_device_image_store.GetImagesForDeviceModel(kTestModelId)); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.cc b/ash/quick_pair/repository/fast_pair_repository_impl.cc index c51105d..1b3eee03 100644 --- a/ash/quick_pair/repository/fast_pair_repository_impl.cc +++ b/ash/quick_pair/repository/fast_pair_repository_impl.cc
@@ -4,9 +4,12 @@ #include "ash/quick_pair/repository/fast_pair_repository_impl.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" #include "ash/quick_pair/common/logging.h" #include "ash/quick_pair/proto/fastpair.pb.h" #include "ash/quick_pair/proto/fastpair_data.pb.h" +#include "ash/quick_pair/repository/fast_pair/device_id_map.h" +#include "ash/quick_pair/repository/fast_pair/device_image_store.h" #include "ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h" #include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h" #include "ash/quick_pair/repository/fast_pair/footprints_fetcher.h" @@ -27,6 +30,8 @@ footprints_fetcher_(std::make_unique<FootprintsFetcher>()), image_decoder_(std::make_unique<FastPairImageDecoder>( std::unique_ptr<image_fetcher::ImageFetcher>())), + device_id_map_(std::make_unique<DeviceIdMap>()), + device_image_store_(std::make_unique<DeviceImageStore>()), saved_device_registry_(std::make_unique<SavedDeviceRegistry>()), footprints_last_updated_(base::Time::UnixEpoch()) { // TODO(crbug/1270534): Determine the best place to make this call. @@ -57,6 +62,8 @@ const std::string& normalized_model_id, DeviceMetadataCallback callback, absl::optional<nearby::fastpair::GetObservedDeviceResponse> response) { + RecordDeviceMetadataFetchResult(/*success=*/response.has_value()); + if (!response) { std::move(callback).Run(nullptr); return;
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.h b/ash/quick_pair/repository/fast_pair_repository_impl.h index 1630fbe3..b9a81470 100644 --- a/ash/quick_pair/repository/fast_pair_repository_impl.h +++ b/ash/quick_pair/repository/fast_pair_repository_impl.h
@@ -26,6 +26,8 @@ namespace ash { namespace quick_pair { +class DeviceIdMap; +class DeviceImageStore; class DeviceMetadataFetcher; class FastPairImageDecoder; class FootprintsFetcher; @@ -83,6 +85,8 @@ std::unique_ptr<DeviceMetadataFetcher> device_metadata_fetcher_; std::unique_ptr<FootprintsFetcher> footprints_fetcher_; std::unique_ptr<FastPairImageDecoder> image_decoder_; + std::unique_ptr<DeviceIdMap> device_id_map_; + std::unique_ptr<DeviceImageStore> device_image_store_; std::unique_ptr<SavedDeviceRegistry> saved_device_registry_; base::flat_map<std::string, std::unique_ptr<DeviceMetadata>> metadata_cache_;
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.cc index eab399fb..135be88 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.cc +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.cc
@@ -71,24 +71,31 @@ quick_pair_process::GetHexModelIdFromServiceData( *fast_pair_service_data, base::BindOnce(&FastPairDiscoverableScanner::OnModelIdRetrieved, - weak_pointer_factory_.GetWeakPtr(), device), + weak_pointer_factory_.GetWeakPtr(), device->GetAddress()), base::BindOnce(&FastPairDiscoverableScanner::OnUtilityProcessStopped, - weak_pointer_factory_.GetWeakPtr(), device)); + weak_pointer_factory_.GetWeakPtr(), device->GetAddress())); } void FastPairDiscoverableScanner::OnModelIdRetrieved( - device::BluetoothDevice* device, + const std::string& address, const absl::optional<std::string>& model_id) { - auto it = model_id_parse_attempts_.find(device->GetAddress()); + auto it = model_id_parse_attempts_.find(address); // If there's no entry in the map, the device was lost while parsing. - if (it == model_id_parse_attempts_.end()) + if (it == model_id_parse_attempts_.end()) { + QP_LOG(WARNING) + << __func__ + << ": Returning early because device as lost while parsing."; return; + } model_id_parse_attempts_.erase(it); - if (!model_id) + if (!model_id) { + QP_LOG(INFO) << __func__ + << ": Returning early because no model id was parsed."; return; + } // The Nearby Share feature advertises under the Fast Pair Service Data UUID // and uses a reserved model ID to enable their 'fast initiation' scenario. @@ -100,12 +107,12 @@ FastPairRepository::Get()->GetDeviceMetadata( *model_id, base::BindOnce(&FastPairDiscoverableScanner::OnDeviceMetadataRetrieved, - weak_pointer_factory_.GetWeakPtr(), device, + weak_pointer_factory_.GetWeakPtr(), address, model_id.value())); } void FastPairDiscoverableScanner::OnDeviceMetadataRetrieved( - device::BluetoothDevice* bluetooth_device, + const std::string& address, const std::string model_id, DeviceMetadata* device_metadata) { if (!device_metadata) { @@ -117,8 +124,8 @@ QP_LOG(VERBOSE) << __func__ << ": Id: " << model_id; - auto device = base::MakeRefCounted<Device>( - model_id, bluetooth_device->GetAddress(), Protocol::kFastPairInitial); + auto device = base::MakeRefCounted<Device>(model_id, address, + Protocol::kFastPairInitial); // Anti-spoofing keys were introduced in Fast Pair v2, so if this isn't // available then the device is v1. @@ -158,8 +165,8 @@ device::BluetoothDevice* ble_device = adapter_->GetDevice(device->ble_address); - bool is_already_paired = - (classic_device && classic_device->IsPaired()) || ble_device->IsPaired(); + bool is_already_paired = (classic_device && classic_device->IsPaired()) || + (ble_device && ble_device->IsPaired()); if (is_already_paired) { QP_LOG(INFO) << __func__ << ": Already paired with " << device; @@ -190,19 +197,27 @@ } void FastPairDiscoverableScanner::OnUtilityProcessStopped( - device::BluetoothDevice* device, + const std::string& address, QuickPairProcessManager::ShutdownReason shutdown_reason) { - int current_retry_count = model_id_parse_attempts_[device->GetAddress()]; + int current_retry_count = model_id_parse_attempts_[address]; if (current_retry_count > kMaxParseModelIdRetryCount) { QP_LOG(WARNING) << "Failed to parse model id from device more than " << kMaxParseModelIdRetryCount << " times."; // Clean up the state here which enables trying again in the future if this // device is re-discovered. - model_id_parse_attempts_.erase(device->GetAddress()); + model_id_parse_attempts_.erase(address); return; } - model_id_parse_attempts_[device->GetAddress()] = current_retry_count + 1; + // Don't try to parse the model ID again if the device was lost. + device::BluetoothDevice* device = adapter_->GetDevice(address); + if (!device) { + QP_LOG(WARNING) << __func__ << ": Lost device in between parse attempts."; + model_id_parse_attempts_.erase(address); + return; + } + + model_id_parse_attempts_[address] = current_retry_count + 1; const std::vector<uint8_t>* fast_pair_service_data = device->GetServiceDataForUUID(kFastPairBluetoothUuid); @@ -210,9 +225,9 @@ quick_pair_process::GetHexModelIdFromServiceData( *fast_pair_service_data, base::BindOnce(&FastPairDiscoverableScanner::OnModelIdRetrieved, - weak_pointer_factory_.GetWeakPtr(), device), + weak_pointer_factory_.GetWeakPtr(), address), base::BindOnce(&FastPairDiscoverableScanner::OnUtilityProcessStopped, - weak_pointer_factory_.GetWeakPtr(), device)); + weak_pointer_factory_.GetWeakPtr(), address)); } } // namespace quick_pair
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.h b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.h index 53ad1df..d7ef5ea7 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.h +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner.h
@@ -38,7 +38,7 @@ class FastPairDiscoverableScanner final : public FastPairScanner::Observer { public: FastPairDiscoverableScanner(scoped_refptr<FastPairScanner> scanner, - scoped_refptr<device::BluetoothAdapter> adatper, + scoped_refptr<device::BluetoothAdapter> adapter, DeviceCallback found_callback, DeviceCallback lost_callback); FastPairDiscoverableScanner(const FastPairDiscoverableScanner&) = delete; @@ -51,16 +51,16 @@ void OnDeviceLost(device::BluetoothDevice* device) override; private: - void OnModelIdRetrieved(device::BluetoothDevice* device, + void OnModelIdRetrieved(const std::string& address, const absl::optional<std::string>& model_id); - void OnDeviceMetadataRetrieved(device::BluetoothDevice* device, + void OnDeviceMetadataRetrieved(const std::string& address, const std::string model_id, DeviceMetadata* device_metadata); void OnHandshakeComplete(scoped_refptr<Device> device, absl::optional<PairFailure> failure); void NotifyDeviceFound(scoped_refptr<Device> device); void OnUtilityProcessStopped( - device::BluetoothDevice* device, + const std::string& address, QuickPairProcessManager::ShutdownReason shutdown_reason); scoped_refptr<FastPairScanner> scanner_;
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.cc index b2eec24..1cbd55ca 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.cc +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.cc
@@ -108,9 +108,9 @@ quick_pair_process::ParseNotDiscoverableAdvertisement( *fast_pair_service_data, base::BindOnce(&FastPairNotDiscoverableScanner::OnAdvertisementParsed, - weak_pointer_factory_.GetWeakPtr(), device), + weak_pointer_factory_.GetWeakPtr(), device->GetAddress()), base::BindOnce(&FastPairNotDiscoverableScanner::OnUtilityProcessStopped, - weak_pointer_factory_.GetWeakPtr(), device)); + weak_pointer_factory_.GetWeakPtr(), device->GetAddress())); } void FastPairNotDiscoverableScanner::OnDeviceLost( @@ -133,9 +133,9 @@ } void FastPairNotDiscoverableScanner::OnAdvertisementParsed( - device::BluetoothDevice* device, + const std::string& address, const absl::optional<NotDiscoverableAdvertisement>& advertisement) { - auto it = advertisement_parse_attempts_.find(device->GetAddress()); + auto it = advertisement_parse_attempts_.find(address); // If this check fails, the device was lost during parsing if (it == advertisement_parse_attempts_.end()) @@ -146,6 +146,13 @@ if (!advertisement) return; + // Don't continue if device was lost. + device::BluetoothDevice* device = adapter_->GetDevice(address); + if (!device) { + QP_LOG(WARNING) << __func__ << "Lost device after advertisement parsed."; + return; + } + // Set the battery notification if the advertisement contains battery // notification information if (advertisement->battery_notification) @@ -156,21 +163,20 @@ auto filter_iterator = account_key_filters_ - .insert_or_assign(device->GetAddress(), - AccountKeyFilter(advertisement.value())) + .insert_or_assign(address, AccountKeyFilter(advertisement.value())) .first; FastPairRepository::Get()->CheckAccountKeys( filter_iterator->second, base::BindOnce( &FastPairNotDiscoverableScanner::OnAccountKeyFilterCheckResult, - weak_pointer_factory_.GetWeakPtr(), device)); + weak_pointer_factory_.GetWeakPtr(), address)); } void FastPairNotDiscoverableScanner::OnAccountKeyFilterCheckResult( - device::BluetoothDevice* bluetooth_device, + const std::string& address, absl::optional<PairingMetadata> metadata) { - account_key_filters_.erase(bluetooth_device->GetAddress()); + account_key_filters_.erase(address); QP_LOG(VERBOSE) << __func__ << " Metadata: " << (metadata ? "yes" : "no"); @@ -185,8 +191,8 @@ std::string model_id = model_id_stream.str(); QP_LOG(VERBOSE) << __func__ << ": Id: " << model_id; - auto device = base::MakeRefCounted<Device>( - model_id, bluetooth_device->GetAddress(), Protocol::kFastPairSubsequent); + auto device = base::MakeRefCounted<Device>(model_id, address, + Protocol::kFastPairSubsequent); device->SetAdditionalData(Device::AdditionalDataType::kAccountKey, metadata->account_key); @@ -214,8 +220,8 @@ adapter_->GetDevice(device->ble_address); bool is_already_paired = - (classic_device != nullptr ? classic_device->IsPaired() : false) || - ble_device->IsPaired(); + (classic_device ? classic_device->IsPaired() : false) || + (ble_device && ble_device->IsPaired()); if (is_already_paired) { QP_LOG(INFO) << __func__ << ": Already paired with " << device; @@ -227,15 +233,23 @@ } void FastPairNotDiscoverableScanner::OnUtilityProcessStopped( - device::BluetoothDevice* device, + const std::string& address, QuickPairProcessManager::ShutdownReason shutdown_reason) { - int current_retry_count = advertisement_parse_attempts_[device->GetAddress()]; + int current_retry_count = advertisement_parse_attempts_[address]; if (current_retry_count > kMaxParseAdvertisementRetryCount) { QP_LOG(WARNING) << "Failed to parse advertisement from device more than " << kMaxParseAdvertisementRetryCount << " times."; // Clean up the state here which enables trying again in the future if // this device is re-discovered. - advertisement_parse_attempts_.erase(device->GetAddress()); + advertisement_parse_attempts_.erase(address); + return; + } + + // Don't try to parse the advertisement again if the device was lost. + device::BluetoothDevice* device = adapter_->GetDevice(address); + if (!device) { + QP_LOG(WARNING) << __func__ << ": Lost device in between parse attempts."; + advertisement_parse_attempts_.erase(address); return; } @@ -245,18 +259,18 @@ if (!fast_pair_service_data) { QP_LOG(WARNING) << "Failed to get service data for a device we previously " "did get it for."; - advertisement_parse_attempts_.erase(device->GetAddress()); + advertisement_parse_attempts_.erase(address); return; } - advertisement_parse_attempts_[device->GetAddress()] = current_retry_count + 1; + advertisement_parse_attempts_[address] = current_retry_count + 1; quick_pair_process::ParseNotDiscoverableAdvertisement( *fast_pair_service_data, base::BindOnce(&FastPairNotDiscoverableScanner::OnAdvertisementParsed, - weak_pointer_factory_.GetWeakPtr(), device), + weak_pointer_factory_.GetWeakPtr(), address), base::BindOnce(&FastPairNotDiscoverableScanner::OnUtilityProcessStopped, - weak_pointer_factory_.GetWeakPtr(), device)); + weak_pointer_factory_.GetWeakPtr(), address)); } } // namespace quick_pair
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.h b/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.h index 4a8dda3..302e370 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.h +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_not_discoverable_scanner.h
@@ -56,15 +56,15 @@ private: void OnAdvertisementParsed( - device::BluetoothDevice* device, + const std::string& address, const absl::optional<NotDiscoverableAdvertisement>& advertisement); - void OnAccountKeyFilterCheckResult(device::BluetoothDevice* device, + void OnAccountKeyFilterCheckResult(const std::string& address, absl::optional<PairingMetadata> metadata); void OnHandshakeComplete(scoped_refptr<Device> device, absl::optional<PairFailure> failure); void NotifyDeviceFound(scoped_refptr<Device> device); void OnUtilityProcessStopped( - device::BluetoothDevice* device, + const std::string& address, QuickPairProcessManager::ShutdownReason shutdown_reason); scoped_refptr<FastPairScanner> scanner_;
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_scanner_impl.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_scanner_impl.cc index 795e733..b57ede9d 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_scanner_impl.cc +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_scanner_impl.cc
@@ -111,6 +111,9 @@ const std::vector<uint8_t>* service_data = device->GetServiceDataForUUID(kFastPairBluetoothUuid); + if (!service_data || service_data->empty()) + return; + // If the advertisement data we have received does not pertain to a device // we have seen already from the scanner, or if the advertisement data for // a device we have already seen is not new, then early return and do not
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 135b02a..c0a2ae4 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -244,7 +244,7 @@ break; } // If |search_box_view_| is active, handle it as normal below - FALLTHROUGH; + [[fallthrough]]; default: // Handle all other events as normal Textfield::OnGestureEvent(event);
diff --git a/ash/session/fullscreen_controller.cc b/ash/session/fullscreen_controller.cc index a012772..9a2a57c 100644 --- a/ash/session/fullscreen_controller.cc +++ b/ash/session/fullscreen_controller.cc
@@ -99,8 +99,9 @@ void FullscreenController::RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(prefs::kFullscreenAlertEnabled, true, PrefRegistry::PUBLIC); - registry->RegisterListPref(prefs::kFullscreenNotificationUrlExemptList, - PrefRegistry::PUBLIC); + registry->RegisterListPref( + prefs::kKeepFullscreenWithoutNotificationUrlAllowList, + PrefRegistry::PUBLIC); } void FullscreenController::SuspendImminent(
diff --git a/ash/strings/ash_strings_af.xtb b/ash/strings/ash_strings_af.xtb index f2526fe..6d88305 100644 --- a/ash/strings/ash_strings_af.xtb +++ b/ash/strings/ash_strings_af.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Intydse onderskrifte is aan.</translation> <translation id="1720011244392820496">Skakel Wi-Fi-sinkronisering aan</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" is sigbaar vir Bluetooth-toestelle.</translation> <translation id="1743570585616704562">Nie herken nie</translation> <translation id="1746730358044914197">Invoermetodes word deur jou administrateur opgestel.</translation> <translation id="1747827819627189109">Opskerm-sleutelbord geaktiveer</translation> @@ -832,6 +833,7 @@ <translation id="6578407462441924264">Naamloos</translation> <translation id="6585808820553845416">Sessie eindig oor <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Jou verbinding het na 'n veiliger netwerk oorgeskakel</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, seinsterkte <ph name="SIGNAL_STRENGTH" />, deur jou administrateur bestuur</translation> <translation id="6612802754306526077">Skermopnamemodus gekies</translation> <translation id="6614169507485700968">Privaatheidskerm is aan</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb index 387f79a..047bbeb 100644 --- a/ash/strings/ash_strings_ar.xtb +++ b/ash/strings/ash_strings_ar.xtb
@@ -123,6 +123,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">ميزة "النسخ النصي التلقائي" مفعَّلة.</translation> <translation id="1720011244392820496">تفعيل ميزة "مزامنة Wi-Fi"</translation> +<translation id="1736898441010944794">سيظهر "<ph name="NAME" />" للأجهزة التي تتضمّن بلوتوث.</translation> <translation id="1743570585616704562">لم يتم التعرف عليها</translation> <translation id="1746730358044914197">يتم إعداد طرق الإدخال بواسطة المشرف.</translation> <translation id="1747827819627189109">تم تفعيل لوحة المفاتيح على الشاشة</translation> @@ -832,6 +833,7 @@ <translation id="6578407462441924264">بدون اسم</translation> <translation id="6585808820553845416">تنتهي الجلسة في <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />، <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">تم تبديل الاتصال إلى شبكة أكثر أمانًا.</translation> <translation id="661203523074512333">حالة الأمان <ph name="SECURITY_STATUS" />، قوة الإشارة <ph name="SIGNAL_STRENGTH" />، يديرها المشرف</translation> <translation id="6612802754306526077">تم اختيار وضع تسجيل الشاشة.</translation> <translation id="6614169507485700968">تم تفعيل شاشة الخصوصية.</translation>
diff --git a/ash/strings/ash_strings_az.xtb b/ash/strings/ash_strings_az.xtb index caa1daa..1d00c351 100644 --- a/ash/strings/ash_strings_az.xtb +++ b/ash/strings/ash_strings_az.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Canlı Altyazı aktivdir.</translation> <translation id="1720011244392820496">Wi-Fi Sinxronlaşdırmasını aktiv edin</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" Bluetooth cihazlarına görünür.</translation> <translation id="1743570585616704562">Tanınmır</translation> <translation id="1746730358044914197">Daxiletmə üsulları administrator tərəfindən konfiqurasiya edilir.</translation> <translation id="1747827819627189109">Ekrandakı klaviaturanı aktiv edin</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Adsız</translation> <translation id="6585808820553845416">Sessiya <ph name="SESSION_TIME_REMAINING" /> tarixində bitir.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Bağlantı daha təhlükəsiz şəbəkəyə keçdi</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, Siqnal Gücü <ph name="SIGNAL_STRENGTH" />, Administratorunuz tərəfindən idarə olunur</translation> <translation id="6612802754306526077">Ekranın yazılması rejimi seçilib</translation> <translation id="6614169507485700968">Məxfilik ekranı aktivdir</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb index 7cc48a4a..b246c44e 100644 --- a/ash/strings/ash_strings_bg.xtb +++ b/ash/strings/ash_strings_bg.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Функцията „Надписи на живо“ е включена.</translation> <translation id="1720011244392820496">Включване на функцията за синхронизиране на Wi-Fi</translation> +<translation id="1736898441010944794">Устройството <ph name="NAME" /> е видимо за устройства с Bluetooth.</translation> <translation id="1743570585616704562">Не е разпознато</translation> <translation id="1746730358044914197">Методите на въвеждане са конфигурирани от администратора ви.</translation> <translation id="1747827819627189109">Екранната клавиатура е активирана</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Без име</translation> <translation id="6585808820553845416">Сесията приключва след <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Връзката ви бе прехвърлена към по-сигурна мрежа</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, сила на сигнала <ph name="SIGNAL_STRENGTH" />, управлява се от администратора ви</translation> <translation id="6612802754306526077">Избран е режимът за записване на екрана</translation> <translation id="6614169507485700968">Екранът за поверителност е включен</translation>
diff --git a/ash/strings/ash_strings_eu.xtb b/ash/strings/ash_strings_eu.xtb index 8afc2adb..eeb546f 100644 --- a/ash/strings/ash_strings_eu.xtb +++ b/ash/strings/ash_strings_eu.xtb
@@ -622,7 +622,7 @@ <translation id="5071064518267176975">Aplikazio batek mikrofonoa erabili nahi du</translation> <translation id="5075554201838155866">Abiarazi azpitituluak</translation> <translation id="5078796286268621944">Okerra da PINa</translation> -<translation id="5083553833479578423">Lortu Laguntzailea zerbitzuaren aukera gehiago.</translation> +<translation id="5083553833479578423">Desblokeatu Laguntzailea zerbitzuaren eginbide gehiago.</translation> <translation id="5090752371472782287">Igorri <ph name="MANAGER" /> helbideko gailu batera</translation> <translation id="5106223312672646208">Pertsonalizatu</translation> <translation id="5117590920725113268">Erakutsi hurrengo hilabetea</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index f929ffbb..e9f9ef2 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">«زیرنویس ناشنوایان زنده» روشن است.</translation> <translation id="1720011244392820496">روشن کردن «همگامسازی Wi-Fi»</translation> +<translation id="1736898441010944794">«<ph name="NAME" />» برای دستگاههای بلوتوث قابلمشاهده است.</translation> <translation id="1743570585616704562">شناسایی نشد</translation> <translation id="1746730358044914197">روشهای ورودی توسط سرپرستتان پیکربندی میشوند.</translation> <translation id="1747827819627189109">صفحهکلید مجازی فعال شد</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">بدون نام</translation> <translation id="6585808820553845416">جلسه در <ph name="SESSION_TIME_REMAINING" /> به پایان میرسد.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />، <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">اتصال شما به شبکهای ایمنتر منتقل شد</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />، قدرت سیگنال <ph name="SIGNAL_STRENGTH" />، تحتمدیریت سرپرست</translation> <translation id="6612802754306526077">حالت ضبط صفحهنمایش انتخاب شد</translation> <translation id="6614169507485700968">صفحه حریمخصوصی روشن است</translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb index ee883e7..3ae45c5 100644 --- a/ash/strings/ash_strings_fr.xtb +++ b/ash/strings/ash_strings_fr.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Sous-titres instantanés activés.</translation> <translation id="1720011244392820496">Activer Sync Wi-Fi</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" est visible par les appareils Bluetooth.</translation> <translation id="1743570585616704562">Non reconnu</translation> <translation id="1746730358044914197">Les modes de saisie sont configurés par votre administrateur.</translation> <translation id="1747827819627189109">Clavier à l'écran activé</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Sans nom</translation> <translation id="6585808820553845416">Fin de la session dans <ph name="SESSION_TIME_REMAINING" /></translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">La connexion a été établie sur un réseau plus sûr</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, force du signal : <ph name="SIGNAL_STRENGTH" />, géré par votre administrateur</translation> <translation id="6612802754306526077">Mode d'enregistreur d'écran sélectionné</translation> <translation id="6614169507485700968">L'écran de confidentialité est activé</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index c18a15bb..5912eab 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">લાઇવ કૅપ્શનની સુવિધા ચાલુ છે.</translation> <translation id="1720011244392820496">વાઇ-ફાઇ સિંક ચાલુ કરો</translation> +<translation id="1736898441010944794">બ્લૂટૂથ ચાલુ હોય તેવા ડિવાઇસમાં "<ph name="NAME" />"ને જોઈ શકાય છે.</translation> <translation id="1743570585616704562">ઓળખાયેલ નથી</translation> <translation id="1746730358044914197">ઇનપુટ પદ્ધતિઓને તમારા વ્યવસ્થાપક દ્વારા ગોઠવવામાં આવી છે.</translation> <translation id="1747827819627189109">ઓન-સ્ક્રીન કીબોર્ડ સક્ષમ કર્યું</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">અનામાંકિત</translation> <translation id="6585808820553845416"><ph name="SESSION_TIME_REMAINING" /> માં સત્ર સમાપ્ત થાય છે.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">તમારું કનેક્શન વધુ સુરક્ષિત નેટવર્ક પર સ્વિચ કરવામાં આવ્યું</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, સિગ્નલની સશક્તતા <ph name="SIGNAL_STRENGTH" />, તમારા વ્યવસ્થાપક દ્વારા મેનેજ કરવામાં આવે છે</translation> <translation id="6612802754306526077">સ્ક્રીન રેકોર્ડિંગ મોડ પસંદ કર્યો</translation> <translation id="6614169507485700968">પ્રાઇવસી સ્ક્રીન ચાલુ છે</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb index 9743227..0fd7b1a 100644 --- a/ash/strings/ash_strings_id.xtb +++ b/ash/strings/ash_strings_id.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Teks Otomatis aktif.</translation> <translation id="1720011244392820496">Aktifkan Wi-Fi Sync</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" dapat dilihat oleh perangkat Bluetooth.</translation> <translation id="1743570585616704562">Tidak dikenali</translation> <translation id="1746730358044914197">Metode masukan dikonfigurasi oleh administrator.</translation> <translation id="1747827819627189109">Keyboard di layar diaktifkan</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Tanpa Nama</translation> <translation id="6585808820553845416">Sesi berakhir dalam <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Koneksi Anda dialihkan ke jaringan yang lebih aman</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, Kekuatan Sinyal <ph name="SIGNAL_STRENGTH" />, Dikelola oleh Administrator Anda</translation> <translation id="6612802754306526077">Mode perekaman layar dipilih</translation> <translation id="6614169507485700968">Layar privasi aktif</translation>
diff --git a/ash/strings/ash_strings_is.xtb b/ash/strings/ash_strings_is.xtb index f39ff57..8f5deb8 100644 --- a/ash/strings/ash_strings_is.xtb +++ b/ash/strings/ash_strings_is.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Kveikt er á skjátextum í rauntíma.</translation> <translation id="1720011244392820496">Kveikja á Wi-Fi-samstillingu</translation> +<translation id="1736898441010944794">„<ph name="NAME" />“ er sýnilegt Bluetooth-tækjum.</translation> <translation id="1743570585616704562">Þekktist ekki</translation> <translation id="1746730358044914197">Kerfisstjóri stillti innfærsluaðferðir.</translation> <translation id="1747827819627189109">Skjályklaborð virkt</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Án heitis</translation> <translation id="6585808820553845416">Lotunni lýkur eftir <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Skipt var yfir á öruggara netkerfi</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, sendistyrkur <ph name="SIGNAL_STRENGTH" />, stjórnað af kerfisstjóra</translation> <translation id="6612802754306526077">Skjáupptökustilling valin</translation> <translation id="6614169507485700968">Kveikt er á persónuverndarskjá</translation>
diff --git a/ash/strings/ash_strings_km.xtb b/ash/strings/ash_strings_km.xtb index 2d9682a..826054a5 100644 --- a/ash/strings/ash_strings_km.xtb +++ b/ash/strings/ash_strings_km.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">មុខងារអក្សររត់ក្នុងពេលជាក់ស្ដែងត្រូវបានបើក។</translation> <translation id="1720011244392820496">បើក Wi-Fi Sync</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" អាចមើលឃើញដោយឧបករណ៍ប៊្លូធូស។</translation> <translation id="1743570585616704562">មិនស្គាល់ទេ</translation> <translation id="1746730358044914197">វិធីសាស្ត្របញ្ចូលត្រូវបានកំណត់រចនាសម្ព័ន្ធដោយអ្នកគ្រប់គ្រងរបស់អ្នក។</translation> <translation id="1747827819627189109">ក្តារចុចលើអេក្រង់បានបើកដំណើរការ</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">គ្មានឈ្មោះ</translation> <translation id="6585808820553845416">វេនបញ្ចប់ក្នុង <ph name="SESSION_TIME_REMAINING" />។</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">ការតភ្ជាប់របស់អ្នកបានប្ដូរទៅបណ្តាញដែលមានសុវត្ថិភាពជាងមុន</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, កម្លាំងរលកសញ្ញា <ph name="SIGNAL_STRENGTH" />, គ្រប់គ្រងដោយអ្នកគ្រប់គ្រងរបស់អ្នក</translation> <translation id="6612802754306526077">បានជ្រើសរើសមុខងារថតវីដេអូអេក្រង់</translation> <translation id="6614169507485700968">អេក្រង់ឯកជនភាពត្រូវបានបើក</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb index 7276ff6c..ce7f1161 100644 --- a/ash/strings/ash_strings_ko.xtb +++ b/ash/strings/ash_strings_ko.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">실시간 자막이 켜져 있습니다.</translation> <translation id="1720011244392820496">Wi-Fi 동기화 사용 설정</translation> +<translation id="1736898441010944794">블루투스 기기에 "<ph name="NAME" />"이(가) 표시됩니다.</translation> <translation id="1743570585616704562">인식할 수 없음</translation> <translation id="1746730358044914197">입력 방법은 관리자가 설정합니다.</translation> <translation id="1747827819627189109">터치 키보드 사용 설정됨</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">이름 없음</translation> <translation id="6585808820553845416">세션이 <ph name="SESSION_TIME_REMAINING" /> 후에 종료됩니다.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">보다 안전한 네트워크로 연결이 전환되었습니다.</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, 신호 강도 <ph name="SIGNAL_STRENGTH" />, 관리자가 관리함</translation> <translation id="6612802754306526077">화면 녹화 모드 선택됨</translation> <translation id="6614169507485700968">개인정보 보호 화면이 켜져 있습니다</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb index a766e2c..fbb7d83 100644 --- a/ash/strings/ash_strings_lt.xtb +++ b/ash/strings/ash_strings_lt.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Subtitrai realiuoju laiku įjungti.</translation> <translation id="1720011244392820496">„Wi-Fi“ sinchronizavimo įjungimas</translation> +<translation id="1736898441010944794">„<ph name="NAME" />“ matomas „Bluetooth“ įrenginiams.</translation> <translation id="1743570585616704562">Neatpažinta</translation> <translation id="1746730358044914197">Įvesties metodus konfigūruoja jūsų administratorius.</translation> <translation id="1747827819627189109">Ekrano klaviatūra įgalinta</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Be pavadinimo</translation> <translation id="6585808820553845416">Sesija baigsis po <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Ryšys perjungtas į saugesnį tinklą</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, signalo stiprumas <ph name="SIGNAL_STRENGTH" />, tvarko administratorius</translation> <translation id="6612802754306526077">Pasirinktas ekrano vaizdo įrašymo režimas</translation> <translation id="6614169507485700968">Privatumo ekranas įjungtas</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb index 51b034e..81614ec7 100644 --- a/ash/strings/ash_strings_lv.xtb +++ b/ash/strings/ash_strings_lv.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Subtitri reāllaikā ir ieslēgti.</translation> <translation id="1720011244392820496">Wi-Fi sinhronizācijas ieslēgšana</translation> +<translation id="1736898441010944794">Bluetooth ierīces var uztvert šo ierīci: <ph name="NAME" />.</translation> <translation id="1743570585616704562">Nav atpazīts</translation> <translation id="1746730358044914197">Administrators konfigurē ievades metodes.</translation> <translation id="1747827819627189109">Ekrāna tastatūra iespējota</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Bez nosaukuma</translation> <translation id="6585808820553845416">Atlikušais laiks līdz šīs sesijas beigām: <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Savienojums tika mainīts uz drošāku tīklu</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, signāla stiprums: <ph name="SIGNAL_STRENGTH" />, pārvalda jūsu administrators</translation> <translation id="6612802754306526077">Atlasīts ekrāna ierakstīšanas režīms</translation> <translation id="6614169507485700968">Konfidencialitātes ekrāns ir ieslēgts</translation>
diff --git a/ash/strings/ash_strings_mk.xtb b/ash/strings/ash_strings_mk.xtb index 71e9aceb..e278d54 100644 --- a/ash/strings/ash_strings_mk.xtb +++ b/ash/strings/ash_strings_mk.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">„Автоматските титлови“ се вклучени.</translation> <translation id="1720011244392820496">Вклучете синхронизирање на Wi-Fi</translation> +<translation id="1736898441010944794">„<ph name="NAME" />“ е видлив за уреди со Bluetooth.</translation> <translation id="1743570585616704562">Не е препознаен</translation> <translation id="1746730358044914197">Методите на внесување ги конфигурира вашиот администратор.</translation> <translation id="1747827819627189109">Тастатурата на екранот е овозможена</translation> @@ -832,6 +833,7 @@ <translation id="6578407462441924264">Неименувана</translation> <translation id="6585808820553845416">Сесијата ќе заврши во <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Врската се префрли на побезбедна мрежа</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, јачина на сигналот: <ph name="SIGNAL_STRENGTH" />, управувана од администраторот</translation> <translation id="6612802754306526077">Избран е режимот на снимање на екранот</translation> <translation id="6614169507485700968">Вклучен е екранот за приватност</translation>
diff --git a/ash/strings/ash_strings_my.xtb b/ash/strings/ash_strings_my.xtb index 054d909..953e03f 100644 --- a/ash/strings/ash_strings_my.xtb +++ b/ash/strings/ash_strings_my.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">'တိုက်ရိုက်စာတန်း' ကို ဖွင့်ထားသည်။</translation> <translation id="1720011244392820496">'Wi-Fi စင့်ခ်' ဖွင့်ခြင်း</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" ကို ဘလူးတုသ်သုံးစက်များက မြင်နိုင်သည်။</translation> <translation id="1743570585616704562">မသိပါ</translation> <translation id="1746730358044914197">ထည့်သွင်းရန်နည်းလမ်းများကို သင်၏ စီမံခန့်ခွဲသူက စီစဉ်သတ်မှတ်ထားခြင်းဖြစ်သည်။</translation> <translation id="1747827819627189109">မျက်နှာပြင် ပေါ်က ကီးဘုတ် ဖွင့်ထား</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">အမည်ပေးမထား</translation> <translation id="6585808820553845416">ချိတ်ဆက်ချိန်<ph name="SESSION_TIME_REMAINING" /> မှာ ပြီးဆုံးမည်။</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />၊ <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">သင်၏ ချိတ်ဆက်မှုကို ပိုမိုလုံခြုံသည့် ကွန်ရက်သို့ ပြောင်းထားပါသည်</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />၊ လိုင်းဆွဲအား <ph name="SIGNAL_STRENGTH" />၊ သင့် 'စီမံခန့်ခွဲသူ' က ကြီးကြပ်ထားသည်</translation> <translation id="6612802754306526077">ဖန်သားပြင်ရိုက်ကူးခြင်းမုဒ် ရွေးထားသည်</translation> <translation id="6614169507485700968">ပုဂ္ဂိုလ်ရေးလုံခြုံမှု ဖန်သားပြင်ကို ဖွင့်ထားသည်</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb index beb4ebf..16c404d 100644 --- a/ash/strings/ash_strings_no.xtb +++ b/ash/strings/ash_strings_no.xtb
@@ -585,6 +585,7 @@ <translation id="4831034276697007977">Er du sikker på at du vil slå av automatiske klikk?</translation> <translation id="4849058404725798627">Fremhev objektet med tastaturfokus</translation> <translation id="485592688953820832">Ingen handling (pause)</translation> +<translation id="485634149294284819">Åpne skrivebordsmenyen</translation> <translation id="4860284199500934869">Kontroller nettverkstilkoblingen din for å laste ned <ph name="FILENAME" /></translation> <translation id="486056901304535126">Vi forsøker å laste ned filene senere. Tale blir sendt til Google for behandling frem til nedlastingen er fullført.</translation> <translation id="4868492592575313542">aktivert</translation> @@ -1095,6 +1096,7 @@ <translation id="8380784334203145311">God natt</translation> <translation id="8388750414311082622">Det siste skrivebordet kan ikke fjernes.</translation> <translation id="8394567579869570560">Forelderen din har låst denne enheten</translation> +<translation id="8401850874595457088">Åpne språkmenyen</translation> <translation id="8412677897383510995">Vis skjerminnstillinger</translation> <translation id="8413272770729657668">Opptaket starter om 3, 2, 1</translation> <translation id="8416730306157376817"><ph name="BATTERY_PERCENTAGE" /> % (etui)</translation>
diff --git a/ash/strings/ash_strings_or.xtb b/ash/strings/ash_strings_or.xtb index abc4681..d6623f7 100644 --- a/ash/strings/ash_strings_or.xtb +++ b/ash/strings/ash_strings_or.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">ଲାଇଭ୍ କ୍ୟାପ୍ସନ୍ ଚାଲୁ ଅଛି।</translation> <translation id="1720011244392820496">ୱାଇ-ଫାଇ ସିଙ୍କ୍ ଚାଲୁ କରନ୍ତୁ</translation> +<translation id="1736898441010944794">ବ୍ଲୁଟୁଥ ଡିଭାଇସଗୁଡ଼ିକରେ "<ph name="NAME" />" ଦେଖାଯାଏ।</translation> <translation id="1743570585616704562">ଚିହ୍ନଟ ହେଲାନାହିଁ</translation> <translation id="1746730358044914197">ଇନ୍ପୁଟ୍ ପଦ୍ଧତିକୁ ଆପଣଙ୍କ ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ଵାରା କନ୍ଫିଗର୍ କରାଯାଇଛି।</translation> <translation id="1747827819627189109">ଅନ୍ ସ୍କ୍ରିନ୍ କୀ'ବୋର୍ଡକୁ ସକ୍ଷମ କରାଯାଇଛି</translation> @@ -830,6 +831,7 @@ <translation id="6578407462441924264">ବେନାମୀ</translation> <translation id="6585808820553845416"><ph name="SESSION_TIME_REMAINING" />ରେ ସମୟ ଅବଧି ସମାପ୍ତ ହେବ</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">ଏକ ଅଧିକ ସୁରକ୍ଷିତ ନେଟୱାର୍କକୁ ଆପଣଙ୍କ ସଂଯୋଗ ସ୍ୱିଚ କରାଯାଇଛି</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, ସିଗ୍ନାଲ୍ର କ୍ଷମତା <ph name="SIGNAL_STRENGTH" />, ଆପଣଙ୍କର ଆଡ୍ମିନିଷ୍ଟ୍ରେଟର୍ଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ</translation> <translation id="6612802754306526077">ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ମୋଡକୁ ଚୟନ କରାଯାଇଛି</translation> <translation id="6614169507485700968">ଗୋପନୀୟତା ସ୍କ୍ରିନ୍ ଚାଲୁ ଅଛି</translation>
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb index 91ebe0c..5bdba8e 100644 --- a/ash/strings/ash_strings_si.xtb +++ b/ash/strings/ash_strings_si.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">සජීවී සිරස්තල ක්රියාත්මකයි.</translation> <translation id="1720011244392820496">Wi-Fi සමමුහුර්තකරණය ක්රියාත්මක කරන්න</translation> +<translation id="1736898441010944794">"<ph name="NAME" />" බ්ලූටූත් උපාංගවලට දෘශ්යමාන වේ.</translation> <translation id="1743570585616704562">හඳුනා නොගන්නා ලදී</translation> <translation id="1746730358044914197">ඔබේ පරිපාලක විසින් ආදාන ක්රම වින්යාස කරනු ලැබේ.</translation> <translation id="1747827819627189109">තිරය මත යතුරු පුවරුව සබල කර ඇත</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">නම් නොකළ</translation> <translation id="6585808820553845416"><ph name="SESSION_TIME_REMAINING" />කින් සැසිය අවසන්වේ.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">ඔබගේ සබැඳුම වඩාත් සුරක්ෂිත ජාලයකට මාරු වී ඇත</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, සංඥා ප්රබලතාව <ph name="SIGNAL_STRENGTH" />, ඔබේ පරිපාලකයා විසින් කළමනාකරණය කරයි</translation> <translation id="6612802754306526077">තිර පටිගත කිරීම් ප්රකාරය තෝරන ලදි</translation> <translation id="6614169507485700968">පෞද්ගලිකත්ව තිරය සක්රීයයි</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb index 80da7357..8a677fc 100644 --- a/ash/strings/ash_strings_sv.xtb +++ b/ash/strings/ash_strings_sv.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Live Caption är aktiverat.</translation> <translation id="1720011244392820496">Aktivera wifi-synkronisering</translation> +<translation id="1736898441010944794"><ph name="NAME" /> är synlig för Bluetooth-enheter.</translation> <translation id="1743570585616704562">Identifierades inte</translation> <translation id="1746730358044914197">Inmatningsmetoderna konfigureras av administratören.</translation> <translation id="1747827819627189109">Skärmen på tangentbordet har aktiverats</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Namnlös</translation> <translation id="6585808820553845416">Sessionen upphör om <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Anslutningen har flyttats till ett säkrare nätverk</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, signalstyrka <ph name="SIGNAL_STRENGTH" />, hanteras av administratören</translation> <translation id="6612802754306526077">Skärminspelningsläget har valts</translation> <translation id="6614169507485700968">Integritetsskärmen är aktiverad</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb index cdcf3d2c..47bfe47 100644 --- a/ash/strings/ash_strings_tr.xtb +++ b/ash/strings/ash_strings_tr.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Canlı Altyazı açık.</translation> <translation id="1720011244392820496">Wi-Fi Senkronizasyonu aç</translation> +<translation id="1736898441010944794">"<ph name="NAME" />", Bluetooth cihazlara görünür durumda.</translation> <translation id="1743570585616704562">Tanınmadı</translation> <translation id="1746730358044914197">Giriş yöntemleri, yöneticiniz tarafından yapılandırılır.</translation> <translation id="1747827819627189109">Dokunmatik klavye etkin</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Adsız</translation> <translation id="6585808820553845416">Oturumun süresi <ph name="SESSION_TIME_REMAINING" /> içinde bitiyor.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Bağlantınız daha güvenli bir ağa geçti</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, <ph name="SIGNAL_STRENGTH" /> Sinyal Gücü, Yöneticiniz tarafından yönetiliyor</translation> <translation id="6612802754306526077">Ekran kaydetme modu seçildi</translation> <translation id="6614169507485700968">Gizlilik ekranı açık</translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb index f62a574..cfb4111 100644 --- a/ash/strings/ash_strings_vi.xtb +++ b/ash/strings/ash_strings_vi.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Tính năng Phụ đề trực tiếp đang bật.</translation> <translation id="1720011244392820496">Bật tính năng Đồng bộ hóa Wi-Fi</translation> +<translation id="1736898441010944794">Cho phép các thiết bị Bluetooth tìm thấy "<ph name="NAME" />".</translation> <translation id="1743570585616704562">Không nhận dạng được</translation> <translation id="1746730358044914197">Các phương thức nhập do quản trị viên của bạn định cấu hình.</translation> <translation id="1747827819627189109">Đã bật bàn phím ảo</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Chưa đặt tên</translation> <translation id="6585808820553845416">Phiên sẽ kết thúc sau <ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Kết nối của bạn đã chuyển sang một mạng an toàn hơn</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />, Cường độ tín hiệu <ph name="SIGNAL_STRENGTH" />, Do quản trị viên của bạn quản lý</translation> <translation id="6612802754306526077">Đã chọn chế độ ghi màn hình</translation> <translation id="6614169507485700968">Màn hình bảo vệ quyền riêng tư đang bật</translation>
diff --git a/ash/strings/ash_strings_zh-HK.xtb b/ash/strings/ash_strings_zh-HK.xtb index 203573d..bc2e2fc 100644 --- a/ash/strings/ash_strings_zh-HK.xtb +++ b/ash/strings/ash_strings_zh-HK.xtb
@@ -830,7 +830,7 @@ <translation id="6578407462441924264">未命名</translation> <translation id="6585808820553845416">這個工作階段將在 <ph name="SESSION_TIME_REMAINING" />後結束。</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />,<ph name="SECONDARY_TEXT" /></translation> -<translation id="6602800870584047641">已切換至更安全的網路連線</translation> +<translation id="6602800870584047641">連線已切換至更安全的網絡</translation> <translation id="661203523074512333"><ph name="SECURITY_STATUS" />,訊號強度係 <ph name="SIGNAL_STRENGTH" />,由管理員管理</translation> <translation id="6612802754306526077">揀咗螢幕錄影模式</translation> <translation id="6614169507485700968">已啟用私隱保護畫面</translation>
diff --git a/ash/strings/ash_strings_zu.xtb b/ash/strings/ash_strings_zu.xtb index 83458c5..1957e4b 100644 --- a/ash/strings/ash_strings_zu.xtb +++ b/ash/strings/ash_strings_zu.xtb
@@ -122,6 +122,7 @@ <translation id="1715874602234207">F</translation> <translation id="1719094688023114093">Okushuthwe Bukhoma kuvuliwe.</translation> <translation id="1720011244392820496">Vula Ukuxhumana ne-Wi-Fi</translation> +<translation id="1736898441010944794">I-"<ph name="NAME" />" ibonakala kumadivayisi we-Bluetooth.</translation> <translation id="1743570585616704562">Akubonwa</translation> <translation id="1746730358044914197">Izindlela zokufaka zilungiselwe ngomlawuli.</translation> <translation id="1747827819627189109">Ikhibhodi ekuskrini inikwe amandla</translation> @@ -831,6 +832,7 @@ <translation id="6578407462441924264">Akunagama</translation> <translation id="6585808820553845416">Iseshini izophela ngo-<ph name="SESSION_TIME_REMAINING" />.</translation> <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation> +<translation id="6602800870584047641">Ukuxhumeka kwakho kushintshelwe kunethiwekhi evikeleke kakhudlwana</translation> <translation id="661203523074512333">I-<ph name="SECURITY_STATUS" />, Amandla esignali angu-<ph name="SIGNAL_STRENGTH" />, iphethwe umlawuli wakho</translation> <translation id="6612802754306526077">Imodi yokurekhoda isikrini ikhethiwe</translation> <translation id="6614169507485700968">Isikrini sobumfihlo sivuliwe</translation>
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc index d05902ec..6d8685a 100644 --- a/ash/style/ash_color_provider.cc +++ b/ash/style/ash_color_provider.cc
@@ -438,6 +438,9 @@ SkColor AshColorProvider::GetBackgroundThemedColorImpl( SkColor default_color, bool use_dark_color) const { + // May be null in unit tests. + if (!Shell::HasInstance()) + return default_color; WallpaperControllerImpl* wallpaper_controller = Shell::Get()->wallpaper_controller(); if (!wallpaper_controller)
diff --git a/ash/system/accessibility/dictation_button_tray.cc b/ash/system/accessibility/dictation_button_tray.cc index 87784af..da45fd76 100644 --- a/ash/system/accessibility/dictation_button_tray.cc +++ b/ash/system/accessibility/dictation_button_tray.cc
@@ -180,7 +180,7 @@ // A progress indicator that is only visible when a SODA download is // in-progress. progress_indicator_ = std::make_unique<DictationProgressIndicator>(this); - layer()->Add(progress_indicator_->layer()); + layer()->Add(progress_indicator_->CreateLayer()); } progress_indicator_->InvalidateLayer(); }
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc index c29efe13..75ba701 100644 --- a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc +++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
@@ -21,7 +21,6 @@ using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr; const char kBluetoothToastIdPrefix[] = "cros_bluetooth_device_toast_id-"; -constexpr int kToastDurationMs = 6000; } // namespace @@ -43,10 +42,7 @@ /*text=*/ l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_OR_CONNECTED_TOAST, - GetPairedDeviceName(device.get())), - /*timeout_ms=*/kToastDurationMs, - /*dismiss_text=*/absl::nullopt, - /*visible_on_lock_screen=*/false); + GetPairedDeviceName(device.get()))); ShowToast(toast_data); device::RecordUiSurfaceDisplayed(device::BluetoothUiSurface::kPairedToast); @@ -59,10 +55,7 @@ /*text=*/ l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCONNECTED_TOAST, - GetPairedDeviceName(device.get())), - /*timeout_ms=*/kToastDurationMs, - /*dismiss_text=*/absl::nullopt, - /*visible_on_lock_screen=*/false); + GetPairedDeviceName(device.get()))); ShowToast(toast_data); device::RecordUiSurfaceDisplayed( device::BluetoothUiSurface::kConnectionToast); @@ -75,10 +68,7 @@ /*text=*/ l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_OR_CONNECTED_TOAST, - GetPairedDeviceName(device.get())), - /*timeout_ms=*/kToastDurationMs, - /*dismiss_text=*/absl::nullopt, - /*visible_on_lock_screen=*/false); + GetPairedDeviceName(device.get()))); ShowToast(toast_data); device::RecordUiSurfaceDisplayed( device::BluetoothUiSurface::kDisconnectedToast);
diff --git a/ash/system/bluetooth/bluetooth_notification_controller.cc b/ash/system/bluetooth/bluetooth_notification_controller.cc index 1f0e0c0..5d16fcd 100644 --- a/ash/system/bluetooth/bluetooth_notification_controller.cc +++ b/ash/system/bluetooth/bluetooth_notification_controller.cc
@@ -129,13 +129,8 @@ false /* by_user */); } -// TODO(crbug.com/1270549): Use value from central location. -constexpr int kToastDurationMs = 2500; - void ShowToast(const std::string& id, const std::u16string& text) { - ash::ToastManager::Get()->Show( - ash::ToastData(id, text, kToastDurationMs, - /*dismiss_text=*/absl::nullopt)); + ash::ToastManager::Get()->Show(ash::ToastData(id, text)); } } // namespace
diff --git a/ash/system/holding_space/holding_space_item_chip_view.cc b/ash/system/holding_space/holding_space_item_chip_view.cc index acc4f74..442a550 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.cc +++ b/ash/system/holding_space/holding_space_item_chip_view.cc
@@ -167,7 +167,7 @@ SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - layer()->Add(progress_indicator_->layer()); + layer()->Add(progress_indicator_->CreateLayer()); } private:
diff --git a/ash/system/holding_space/holding_space_item_chip_view.h b/ash/system/holding_space/holding_space_item_chip_view.h index a4a919ae..f28e46b 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.h +++ b/ash/system/holding_space/holding_space_item_chip_view.h
@@ -72,8 +72,7 @@ HoldingSpaceProgressIndicator* progress_indicator_ = nullptr; base::CallbackListSubscription image_skia_changed_subscription_; - HoldingSpaceAnimationRegistry::ProgressRingAnimationChangedCallbackList:: - Subscription progress_ring_animation_changed_subscription_; + base::CallbackListSubscription progress_ring_animation_changed_subscription_; }; BEGIN_VIEW_BUILDER(/* no export */,
diff --git a/ash/system/holding_space/holding_space_progress_indicator.cc b/ash/system/holding_space/holding_space_progress_indicator.cc index 9f6d37e..dd78604 100644 --- a/ash/system/holding_space/holding_space_progress_indicator.cc +++ b/ash/system/holding_space/holding_space_progress_indicator.cc
@@ -294,17 +294,13 @@ // HoldingSpaceProgressIndicator ----------------------------------------------- +// static constexpr char HoldingSpaceProgressIndicator::kClassName[]; constexpr float HoldingSpaceProgressIndicator::kProgressComplete; HoldingSpaceProgressIndicator::HoldingSpaceProgressIndicator( const void* animation_key) - : ui::LayerOwner(std::make_unique<ui::Layer>(ui::LAYER_TEXTURED)), - animation_key_(animation_key) { - layer()->set_delegate(this); - layer()->SetFillsBoundsOpaquely(false); - layer()->SetName(kClassName); - + : animation_key_(animation_key) { HoldingSpaceAnimationRegistry* animation_registry = HoldingSpaceAnimationRegistry::GetInstance(); @@ -340,14 +336,32 @@ return std::make_unique<HoldingSpaceItemProgressIndicator>(item); } -base::RepeatingClosureList::Subscription +base::CallbackListSubscription HoldingSpaceProgressIndicator::AddProgressChangedCallback( base::RepeatingClosureList::CallbackType callback) { return progress_changed_callback_list_.Add(std::move(callback)); } +ui::Layer* HoldingSpaceProgressIndicator::CreateLayer() { + DCHECK(!layer()); + + auto layer = std::make_unique<ui::Layer>(ui::LAYER_TEXTURED); + layer->set_delegate(this); + layer->SetFillsBoundsOpaquely(false); + layer->SetName(kClassName); + Reset(std::move(layer)); + + return this->layer(); +} + +void HoldingSpaceProgressIndicator::DestroyLayer() { + if (layer()) + ReleaseLayer(); +} + void HoldingSpaceProgressIndicator::InvalidateLayer() { - layer()->SchedulePaint(gfx::Rect(layer()->size())); + if (layer()) + layer()->SchedulePaint(gfx::Rect(layer()->size())); } void HoldingSpaceProgressIndicator::SetInnerIconVisible(bool visible) {
diff --git a/ash/system/holding_space/holding_space_progress_indicator.h b/ash/system/holding_space/holding_space_progress_indicator.h index 3cecfb56..3a57b91 100644 --- a/ash/system/holding_space/holding_space_progress_indicator.h +++ b/ash/system/holding_space/holding_space_progress_indicator.h
@@ -47,9 +47,17 @@ // Adds the specified `callback` to be notified of `progress_` changes. The // `callback` will continue to receive events so long as both `this` and the // returned subscription exist. - base::RepeatingClosureList::Subscription AddProgressChangedCallback( + base::CallbackListSubscription AddProgressChangedCallback( base::RepeatingClosureList::CallbackType callback); + // Creates and returns the `layer()` which is owned by this progress + // indicator. Note that this may only be called if `layer()` does not exist. + ui::Layer* CreateLayer(); + + // Destroys the `layer()` which is owned by this progress indicator. Note that + // this will no-op if `layer()` does not exist. + void DestroyLayer(); + // Invoke to schedule repaint of the entire `layer()`. void InvalidateLayer();
diff --git a/ash/system/holding_space/holding_space_tray.cc b/ash/system/holding_space/holding_space_tray.cc index 67299f86..6c02bcf 100644 --- a/ash/system/holding_space/holding_space_tray.cc +++ b/ash/system/holding_space/holding_space_tray.cc
@@ -243,7 +243,7 @@ // * previews are hidden. progress_indicator_ = HoldingSpaceProgressIndicator::CreateForController( HoldingSpaceController::Get()); - layer()->Add(progress_indicator_->layer()); + layer()->Add(progress_indicator_->CreateLayer()); // Subscribe to receive notification of changes to the `progress_indicator_`'s // underlying progress. When progress changes, the `default_tray_icon_` may
diff --git a/ash/system/holding_space/holding_space_tray_icon_preview.cc b/ash/system/holding_space/holding_space_tray_icon_preview.cc index 26b04d7..40cdff4 100644 --- a/ash/system/holding_space/holding_space_tray_icon_preview.cc +++ b/ash/system/holding_space/holding_space_tray_icon_preview.cc
@@ -10,6 +10,8 @@ #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_image.h" #include "ash/public/cpp/holding_space/holding_space_item.h" +#include "ash/public/cpp/holding_space/holding_space_model.h" +#include "ash/public/cpp/holding_space/holding_space_model_observer.h" #include "ash/public/cpp/shelf_config.h" #include "ash/shelf/shelf.h" #include "ash/style/ash_color_provider.h" @@ -23,6 +25,7 @@ #include "ui/compositor/paint_recorder.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/transform_util.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_source.h" @@ -36,6 +39,11 @@ // Appearance. constexpr int kElevation = 1; +// In-progress animation. +constexpr base::TimeDelta kInProgressAnimationDuration = + base::Milliseconds(150); +constexpr float kInProgressAnimationScaleFactor = 0.7f; + // The duration of each of the preview icon bounce animation. constexpr base::TimeDelta kBounceAnimationSegmentDuration = base::Milliseconds(250); @@ -49,6 +57,13 @@ // Helpers --------------------------------------------------------------------- +// Convenience helper to allow a `closure` to be used in a context which is +// expecting a callback with arguments. +template <typename... T> +base::RepeatingCallback<void(T...)> IgnoreArgs(base::RepeatingClosure closure) { + return base::BindRepeating([](T...) {}).Then(std::move(closure)); +} + // Returns true if small previews should be used given the current shelf // configuration, false otherwise. bool ShouldUseSmallPreviews() { @@ -117,63 +132,234 @@ animation_settings->SetTweenType(gfx::Tween::EASE_OUT); } -// ContentsImageSource --------------------------------------------------------- - -class ContentsImageSource : public gfx::ImageSkiaSource { - public: - explicit ContentsImageSource(gfx::ImageSkia item_image) - : item_image_(item_image) {} - ContentsImageSource(const ContentsImageSource&) = delete; - ContentsImageSource& operator=(const ContentsImageSource&) = delete; - ~ContentsImageSource() override = default; - - private: - // gfx::ImageSkiaSource: - gfx::ImageSkiaRep GetImageForScale(float scale) override { - gfx::ImageSkia image = item_image_; - - // The `image` should already be sized appropriately. - DCHECK_EQ(image.size(), GetPreviewSize()); - - // Clip to circle. - // NOTE: Since `image` is a square, the center x-coordinate, center - // y-coordinate, and radius all equal the same value. - const int radius = image.width() / 2; - gfx::Canvas canvas(image.size(), scale, /*is_opaque=*/false); - canvas.ClipPath(SkPath::Circle(/*cx=*/radius, /*cy=*/radius, radius), - /*anti_alias=*/true); - canvas.DrawImageInt(image, /*x=*/0, /*y=*/0); - return gfx::ImageSkiaRep(canvas.GetBitmap(), scale); - } - - const gfx::ImageSkia item_image_; -}; - } // namespace +// HoldingSpaceTrayIconPreview::ImageLayerOwner -------------------------------- + +// Class which owns the `layer()` to which the image representation for the +// associated holding space `item_` is painted. +class HoldingSpaceTrayIconPreview::ImageLayerOwner + : public ui::LayerOwner, + public ui::LayerDelegate, + public HoldingSpaceModelObserver { + public: + explicit ImageLayerOwner(const HoldingSpaceItem* item) : item_(item) { + item_deletion_subscription_ = item->AddDeletionCallback(base::BindRepeating( + &ImageLayerOwner::OnHoldingSpaceItemDeleted, base::Unretained(this))); + + item_image_skia_subscription_ = + item->image().AddImageSkiaChangedCallback(base::BindRepeating( + &ImageLayerOwner::OnHoldingSpaceItemImageSkiaChanged, + base::Unretained(this))); + + progress_ring_animation_changed_subscription_ = + HoldingSpaceAnimationRegistry::GetInstance() + ->AddProgressRingAnimationChangedCallbackForKey( + /*animation_key=*/item_, + IgnoreArgs<HoldingSpaceProgressRingAnimation*>( + base::BindRepeating(&ImageLayerOwner::UpdateTransform, + base::Unretained(this)))); + + model_observer_.Observe(HoldingSpaceController::Get()->model()); + } + + ImageLayerOwner(const ImageLayerOwner&) = delete; + ImageLayerOwner& operator=(const ImageLayerOwner&) = delete; + ~ImageLayerOwner() override = default; + + // Creates and returns the `layer()` owned by this class. Note that this may + // only be called if `layer()` does not already exist. + ui::Layer* CreateLayer() { + DCHECK(!layer()); + + auto layer = std::make_unique<ui::Layer>(ui::LAYER_TEXTURED); + layer->set_delegate(this); + layer->SetFillsBoundsOpaquely(false); + layer->SetName(HoldingSpaceTrayIconPreview::kImageLayerName); + Reset(std::move(layer)); + + UpdateOpacity(); + UpdateTransform(); + + return this->layer(); + } + + // Destroys the `layer()` which is owned by this class. Note that this will + // no-op if `layer()` does not exist. + void DestroyLayer() { + if (layer()) + ReleaseLayer(); + } + + // Invoke to schedule repaint of the entire `layer()`. + void InvalidateLayer() { + // Clear cache. + image_skia_ = gfx::ImageSkia(); + + // Schedule repaint. + if (layer()) + layer()->SchedulePaint(gfx::Rect(layer()->size())); + } + + private: + // ui::LayerDelegate: + void OnPaintLayer(const ui::PaintContext& context) override { + if (image_skia_.isNull()) + return; + + // Copy `image_skia_` since retrieving a representation at the appropriate + // scale may result in a series of events in which `image_skia_` is deleted. + // Note that `gfx::ImageSkia`'s shared storage makes this a cheap copy. + gfx::ImageSkia image_skia(image_skia_); + + // Paint `image_skia`. + ui::PaintRecorder recorder(context, layer()->size()); + gfx::Canvas* canvas = recorder.canvas(); + canvas->DrawImageInt(image_skia, 0, 0); + } + + void OnDeviceScaleFactorChanged(float old_device_scale_factor, + float new_device_scale_factor) override { + // Clear cache and schedule repaint. + InvalidateLayer(); + } + + void OnLayerBoundsChanged(const gfx::Rect& old_bounds, + ui::PropertyChangeReason reason) override { + // Corner radius. + const gfx::Size& size = layer()->size(); + const float corner_radius = std::min(size.width(), size.height()) / 2.f; + layer()->SetRoundedCornerRadius(gfx::RoundedCornersF(corner_radius)); + + // Transform. + UpdateTransform(); + + // Clear cache and schedule repaint. + InvalidateLayer(); + } + + void UpdateVisualState() override { + if (item_ && image_skia_.isNull()) { + image_skia_ = item_->image().GetImageSkia( + layer()->size(), AshColorProvider::Get()->IsDarkModeEnabled()); + } + } + + // HoldingSpaceModelObserver: + void OnHoldingSpaceItemUpdated(const HoldingSpaceItem* item, + uint32_t updated_fields) override { + if (item_ != item) + return; + + if (updated_fields & HoldingSpaceModelObserver::UpdatedField::kProgress) { + UpdateOpacity(); + UpdateTransform(); + } + } + + void OnHoldingSpaceItemDeleted() { item_ = nullptr; } + + void OnHoldingSpaceItemImageSkiaChanged() { InvalidateLayer(); } + + void UpdateOpacity() { + // Opacity need not be updated if: + // * `item_` is destroyed and is being animated out, + // * `layer()` does not exist, or + // * in-progress animations v2 is disabled since in that case there is no + // progress indicator inner icon which would otherwise result in overlap. + if (!item_ || !layer() || + !features::IsHoldingSpaceInProgressAnimationV2Enabled()) { + return; + } + + const bool is_item_visibly_in_progress = + !item_->progress().IsHidden() && !item_->progress().IsComplete(); + + const float target_opacity = is_item_visibly_in_progress ? 0.f : 1.f; + if (layer()->GetTargetOpacity() == target_opacity) + return; + + // If `layer()` should be hidden, do so immediately without animation so as + // to avoid clashing with other UI elements. + if (target_opacity == 0.f) { + layer()->SetOpacity(0.f); + return; + } + + // If `layer()` should be visible, animate the transition. + ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); + settings.SetTransitionDuration(kInProgressAnimationDuration); + settings.SetTweenType(gfx::Tween::Type::LINEAR_OUT_SLOW_IN); + layer()->SetOpacity(1.f); + } + + void UpdateTransform() { + // Transform need not be updated if: + // * `item_` is destroyed and is being animated out, + // * `layer()` does not exist, or + // * in-progress animations v2 is disabled since in that case there is no + // progress indicator inner icon which would otherwise result in overlap. + if (!item_ || !layer() || + !features::IsHoldingSpaceInProgressAnimationV2Enabled()) { + return; + } + + const bool is_item_visibly_in_progress = + !item_->progress().IsHidden() && !item_->progress().IsComplete(); + const bool is_item_animating_progress_ring = + HoldingSpaceAnimationRegistry::GetInstance() + ->GetProgressRingAnimationForKey(item_); + + const gfx::Transform target_transform = + is_item_visibly_in_progress || is_item_animating_progress_ring + ? gfx::GetScaleTransform(gfx::Rect(layer()->size()).CenterPoint(), + kInProgressAnimationScaleFactor) + : gfx::Transform(); + if (layer()->GetTargetTransform() == target_transform) + return; + + // If `layer()` should be scaled, do so immediately without animation so as + // to avoid clashing with other UI elements. + if (!target_transform.IsIdentity()) { + layer()->SetTransform(target_transform); + return; + } + + // If `layer()` should not be scaled, animate the transition. + ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); + settings.SetTransitionDuration(kInProgressAnimationDuration); + settings.SetTweenType(gfx::Tween::Type::LINEAR_OUT_SLOW_IN); + layer()->SetTransform(target_transform); + } + + const HoldingSpaceItem* item_ = nullptr; + base::CallbackListSubscription item_deletion_subscription_; + base::CallbackListSubscription item_image_skia_subscription_; + base::CallbackListSubscription progress_ring_animation_changed_subscription_; + + // Cached image representation of the associated holding space `item_` that is + // painted to the `layer()` owned by this class. + gfx::ImageSkia image_skia_; + + base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver> + model_observer_{this}; +}; + // HoldingSpaceTrayIconPreview ------------------------------------------------- +// static +constexpr char HoldingSpaceTrayIconPreview::kClassName[]; +constexpr char HoldingSpaceTrayIconPreview::kImageLayerName[]; + HoldingSpaceTrayIconPreview::HoldingSpaceTrayIconPreview( Shelf* shelf, views::View* container, const HoldingSpaceItem* item) : shelf_(shelf), container_(container), - item_(item), - progress_indicator_(HoldingSpaceProgressIndicator::CreateForItem(item_)), + image_layer_owner_(std::make_unique<ImageLayerOwner>(item)), + progress_indicator_(HoldingSpaceProgressIndicator::CreateForItem(item)), use_small_previews_(ShouldUseSmallPreviews()) { - // Initialize the `contents_image_`. - OnHoldingSpaceItemImageChanged(); - - item_deletion_subscription_ = item->AddDeletionCallback(base::BindRepeating( - &HoldingSpaceTrayIconPreview::OnHoldingSpaceItemDeleted, - base::Unretained(this))); - - image_subscription_ = - item->image().AddImageSkiaChangedCallback(base::BindRepeating( - &HoldingSpaceTrayIconPreview::OnHoldingSpaceItemImageChanged, - base::Unretained(this))); - container_observer_.Observe(container_); } @@ -405,20 +591,11 @@ UpdateLayerBounds(); layer()->SetTransform(transform_); } - - // Invalidate `contents_image_` so it is resized. - OnHoldingSpaceItemImageChanged(); } void HoldingSpaceTrayIconPreview::OnThemeChanged() { - // Invalidate `contents_image_` so that file type icons will use the correct - // foreground color to contrast the preview's background. Note that this will - // trigger `layer()` invalidation at which time the background will be painted - // in the appropriate color for the current theme. - OnHoldingSpaceItemImageChanged(); - - // Invalidate the `progress_indicator_` layer so that it gets repainted with - // colors that are appropriately themed. + InvalidateLayer(); + image_layer_owner_->InvalidateLayer(); progress_indicator_->InvalidateLayer(); } @@ -434,8 +611,8 @@ // Background. // NOTE: The background radius is shrunk by a single pixel to avoid being - // painted outside `contents_image_` bounds as might otherwise occur due to - // pixel rounding. Failure to do so could result in paint artifacts. + // painted outside `image_layer_owner_` layer bounds as might otherwise occur + // due to pixel rounding. Failure to do so could result in paint artifacts. cc::PaintFlags flags; flags.setAntiAlias(true); flags.setColor(AshColorProvider::Get()->GetBaseLayerColor( @@ -445,14 +622,6 @@ gfx::PointF(contents_bounds.CenterPoint()), std::min(contents_bounds.width(), contents_bounds.height()) / 2.f - 0.5f, flags); - - // Contents. - // NOTE: The `contents_image_` should already be resized. - if (!contents_image_.isNull()) { - DCHECK_EQ(contents_image_.size(), contents_bounds.size()); - canvas->DrawImageInt(contents_image_, contents_bounds.x(), - contents_bounds.y()); - } } void HoldingSpaceTrayIconPreview::OnDeviceScaleFactorChanged( @@ -481,23 +650,6 @@ container_observer_.Reset(); } -void HoldingSpaceTrayIconPreview::OnHoldingSpaceItemImageChanged() { - if (item_) { - const gfx::Size size(GetPreviewSize()); - contents_image_ = gfx::ImageSkia( - std::make_unique<ContentsImageSource>(item_->image().GetImageSkia( - size, AshColorProvider::Get()->IsDarkModeEnabled())), - size); - } else { - contents_image_ = gfx::ImageSkia(); - } - InvalidateLayer(); -} - -void HoldingSpaceTrayIconPreview::OnHoldingSpaceItemDeleted() { - item_ = nullptr; -} - void HoldingSpaceTrayIconPreview::CreateLayer( const gfx::Transform& initial_transform) { DCHECK(!layer()); @@ -506,8 +658,10 @@ auto new_layer = std::make_unique<ui::Layer>(ui::LAYER_TEXTURED); new_layer->set_delegate(this); new_layer->SetFillsBoundsOpaquely(false); + new_layer->SetName(kClassName); new_layer->SetTransform(initial_transform); - new_layer->Add(progress_indicator_->layer()); + new_layer->Add(image_layer_owner_->CreateLayer()); + new_layer->Add(progress_indicator_->CreateLayer()); layer_owner_.Reset(std::move(new_layer)); UpdateLayerBounds(); @@ -517,6 +671,8 @@ void HoldingSpaceTrayIconPreview::DestroyLayer() { if (layer()) layer_owner_.ReleaseLayer(); + image_layer_owner_->DestroyLayer(); + progress_indicator_->DestroyLayer(); } bool HoldingSpaceTrayIconPreview::NeedsLayer() const { @@ -569,11 +725,12 @@ layer()->SetBounds(bounds); // The `layer()` was enlarged so that the shadow would be painted outside of - // desired preview bounds. Progress indicator bounds are clamped to preview - // size. - gfx::Rect progress_indicator_bounds(layer()->size()); - progress_indicator_bounds.ClampToCenteredSize(GetPreviewSize()); - progress_indicator_->layer()->SetBounds(progress_indicator_bounds); + // desired preview bounds. The image layer and progress indicator bounds are + // clamped to preview size. + bounds = gfx::Rect(layer()->size()); + bounds.ClampToCenteredSize(GetPreviewSize()); + image_layer_owner_->layer()->SetBounds(bounds); + progress_indicator_->layer()->SetBounds(bounds); } } // namespace ash
diff --git a/ash/system/holding_space/holding_space_tray_icon_preview.h b/ash/system/holding_space/holding_space_tray_icon_preview.h index 86dad50..ceb3347b 100644 --- a/ash/system/holding_space/holding_space_tray_icon_preview.h +++ b/ash/system/holding_space/holding_space_tray_icon_preview.h
@@ -15,10 +15,6 @@ #include "ui/views/view.h" #include "ui/views/view_observer.h" -namespace gfx { -class ImageSkia; -} // namespace gfx - namespace ui { class Layer; } // namespace ui @@ -38,6 +34,10 @@ public ui::ImplicitAnimationObserver, public views::ViewObserver { public: + static constexpr char kClassName[] = "HoldingSpaceTrayIconPreview"; + static constexpr char kImageLayerName[] = + "HoldingSpaceTrayIconPreview::Image"; + HoldingSpaceTrayIconPreview(Shelf* shelf, views::View* container, const HoldingSpaceItem* item); @@ -75,9 +75,6 @@ // Invoked when the theme of the parent `container_` has changed. void OnThemeChanged(); - // Returns the holding space `item_` visually represented by this preview. - const HoldingSpaceItem* item() const { return item_; } - ui::Layer* layer() { return layer_owner_.layer(); } const absl::optional<size_t>& index() const { return index_; } @@ -86,6 +83,8 @@ void set_pending_index(size_t index) { pending_index_ = index; } private: + class ImageLayerOwner; + // ui::LayerDelegate: void OnPaintLayer(const ui::PaintContext& context) override; void OnDeviceScaleFactorChanged(float old_device_scale_factor, @@ -98,13 +97,6 @@ void OnViewBoundsChanged(views::View* observed_view) override; void OnViewIsDeleting(views::View* observed_view) override; - // Subscription callback for `item_` image changes. Called when the icon - // representation gets updated. - void OnHoldingSpaceItemImageChanged(); - - // Subscription callback for `item_` deletion. - void OnHoldingSpaceItemDeleted(); - // Creates a layer for this preview. The layer will be owned by // `layer_owner_`. Note that a layer may be created multiple times throughout // this preview's lifetime as the preview will only have a layer while in the @@ -139,24 +131,19 @@ // icon. views::View* const container_; - // The holding space item this preview represents - may be null if the item - // gets deleted before the preview. - const HoldingSpaceItem* item_; + // Owns the `ui::Layer` which paints the image representation of the + // associated holding space item. + std::unique_ptr<ImageLayerOwner> image_layer_owner_; // Owns the `ui::Layer` which paints indicate of progress for the associated - // holding space `item_`. NOTE: The `ui::Layer` is *not* painted if the - // holding space `item` is not in-progress. + // holding space item. NOTE: The `ui::Layer` is *not* painted if the holding + // space item is not in-progress. std::unique_ptr<HoldingSpaceProgressIndicator> progress_indicator_; // Whether or not this preview is currently using small dimensions. This is // done when in tablet mode and an app is in use. bool use_small_previews_ = false; - // A cached representation of the associated holding space `item_`'s image - // which has been cropped, resized, and clipped to a circle to be painted at - // `layer()`'s contents bounds. - gfx::ImageSkia contents_image_; - // This is a proxy for `layer()`'s transform and represents the target // position of this preview. Because `layer()` only exists while in // `container_`'s viewport, we need to manage transform ourselves and continue @@ -164,9 +151,8 @@ gfx::Transform transform_; // The layer serving as the visual representation of the associated holding - // space `item_` in the holding space icon in the shelf. This only exists - // while in the `container_`s viewport as determined by the current - // `transform_`. + // space item in the holding space icon in the shelf. This only exists while + // in the `container_`s viewport as determined by the current `transform_`. ui::LayerOwner layer_owner_; // Closure to invoke on completion of `AnimateOut()`. It is expected that this @@ -181,13 +167,6 @@ // is about to move. Set while the holding space tray icon is updating. absl::optional<size_t> pending_index_; - // Subscription for changes to the holding space image backing - // `contents_image_`. - base::CallbackListSubscription image_subscription_; - - // Subscription for the associated holding space item deletion. - base::CallbackListSubscription item_deletion_subscription_; - // The `layer()` for this preview is parented by `container_`'s layer. It is // necessary to observe and react to bounds changes in `container_` to keep // `layer()`'s bounds in sync.
diff --git a/ash/system/holding_space/holding_space_tray_unittest.cc b/ash/system/holding_space/holding_space_tray_unittest.cc index f0bfda9d..c2b4d5d 100644 --- a/ash/system/holding_space/holding_space_tray_unittest.cc +++ b/ash/system/holding_space/holding_space_tray_unittest.cc
@@ -26,6 +26,7 @@ #include "ash/shell.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "ash/system/holding_space/holding_space_progress_indicator.h" +#include "ash/system/holding_space/holding_space_tray_icon_preview.h" #include "ash/system/tray/tray_constants.h" #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" @@ -45,6 +46,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "ui/compositor/layer.h" #include "ui/events/base_event_utils.h" +#include "ui/gfx/geometry/transform_util.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/controls/menu/menu_controller.h" #include "ui/views/controls/menu/menu_item_view.h" @@ -1244,6 +1246,7 @@ EXPECT_EQ(item_3->id(), HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); } + // Tests how opacity and transform for holding space tray's default tray icon is // adjusted to avoid overlap with the holding space tray's progress indicator. TEST_P(HoldingSpaceTrayDownloadsSectionTest, @@ -1263,9 +1266,8 @@ ->owner()); ASSERT_TRUE(progress_indicator); - // Wait until the `progress_indicator` is synced with the model. Note that - // this happens asynchronously since the `progress_indicator` does so in - // response to compositor scheduling. + // Wait until the `progress_indicator` is synced with the model, which happens + // asynchronously in response to compositor scheduling. PredicateWaiter().WaitUntil(base::BindLambdaForTesting([&]() { return progress_indicator->progress() == HoldingSpaceProgressIndicator::kProgressComplete; @@ -1296,9 +1298,8 @@ // Complete the in-progress `item`. model()->UpdateItem(item->id())->SetProgress(HoldingSpaceProgress(100, 100)); - // Wait until the `progress_indicator` is synced with the model. Note that - // this happens asynchronously since the `progress_indicator` does so in - // response to compositor scheduling. + // Wait until the `progress_indicator` is synced with the model, which happens + // asynchronously in response to compositor scheduling. PredicateWaiter().WaitUntil(base::BindLambdaForTesting([&]() { return progress_indicator->progress() == HoldingSpaceProgressIndicator::kProgressComplete; @@ -1309,6 +1310,68 @@ EXPECT_EQ(default_tray_icon->layer()->GetTargetTransform(), gfx::Transform()); } +// Tests how opacity and transform for holding space tray icon preview images +// are adjusted to avoid overlay with progress indicators. +TEST_P(HoldingSpaceTrayDownloadsSectionTest, + TrayIconPreviewOpacityAndTransform) { + StartSession(); + + // Add an in-progress `item` to the model. + HoldingSpaceItem* const item = AddItem( + GetType(), base::FilePath("/tmp/fake_1"), HoldingSpaceProgress(0, 100)); + ASSERT_TRUE(item); + + // Force immediate update of previews. + GetTray()->FirePreviewsUpdateTimerIfRunningForTesting(); + + // Cache `preview`. + ui::Layer* const preview = + FindLayerWithName(GetTray(), HoldingSpaceTrayIconPreview::kClassName); + ASSERT_TRUE(preview); + + // Cache `image`. + ui::Layer* const image = + FindLayerWithName(preview, HoldingSpaceTrayIconPreview::kImageLayerName); + ASSERT_TRUE(image); + + // Cache `progress_indicator`. + HoldingSpaceProgressIndicator* const progress_indicator = + static_cast<HoldingSpaceProgressIndicator*>( + FindLayerWithName(preview, HoldingSpaceProgressIndicator::kClassName) + ->owner()); + ASSERT_TRUE(progress_indicator); + + // Wait until the `progress_indicator` is synced with the model, which happens + // asynchronously in response to compositor scheduling. + PredicateWaiter().WaitUntil(base::BindLambdaForTesting( + [&]() { return progress_indicator->progress() == 0.f; })); + + // Verify image opacity/transform. + if (!IsInProgressAnimationV2Enabled()) { + EXPECT_EQ(image->GetTargetOpacity(), 1.f); + EXPECT_EQ(image->GetTargetTransform(), gfx::Transform()); + } else { + EXPECT_EQ(image->GetTargetOpacity(), 0.f); + EXPECT_EQ( + image->GetTargetTransform(), + gfx::GetScaleTransform(gfx::Rect(image->size()).CenterPoint(), 0.7f)); + } + + // Complete the in-progress `item`. + model()->UpdateItem(item->id())->SetProgress(HoldingSpaceProgress(100, 100)); + + // Wait until the `progress_indicator` is synced with the model, which happens + // asynchronously in response to compositor scheduling. + PredicateWaiter().WaitUntil(base::BindLambdaForTesting([&]() { + return progress_indicator->progress() == + HoldingSpaceProgressIndicator::kProgressComplete; + })); + + // Verify image opacity. + EXPECT_EQ(image->GetTargetOpacity(), 1.f); + EXPECT_EQ(image->GetTargetTransform(), gfx::Transform()); +} + // Tests how screen captures section is updated during item addition, removal // and initialization. TEST_F(HoldingSpaceTrayTest, ScreenCapturesSection) {
diff --git a/ash/system/message_center/ash_message_center_lock_screen_controller.cc b/ash/system/message_center/ash_message_center_lock_screen_controller.cc index fbcae76..93523ba8b 100644 --- a/ash/system/message_center/ash_message_center_lock_screen_controller.cc +++ b/ash/system/message_center/ash_message_center_lock_screen_controller.cc
@@ -142,7 +142,7 @@ // TODO(yoshiki): Update UI after the UX finalizes. Shell::Get()->toast_manager()->Show( - ToastData(kToastId, message, ToastData::kInfiniteDuration, absl::nullopt, + ToastData(kToastId, message, ToastData::kInfiniteDuration, /*visible_on_lock_screen=*/true)); }
diff --git a/ash/system/message_center/unified_message_center_view.cc b/ash/system/message_center/unified_message_center_view.cc index 4dae636..f4c8984 100644 --- a/ash/system/message_center/unified_message_center_view.cc +++ b/ash/system/message_center/unified_message_center_view.cc
@@ -461,7 +461,7 @@ scroll_bar_->GetMaxPosition() - last_scroll_position_from_bottom_; break; case UnifiedSystemTrayModel::NotificationTargetMode::NOTIFICATION_ID: - FALLTHROUGH; + [[fallthrough]]; case UnifiedSystemTrayModel::NotificationTargetMode::LAST_NOTIFICATION: { const gfx::Rect& target_rect = (model_->notification_target_mode() ==
diff --git a/ash/system/message_center/unified_message_list_view.cc b/ash/system/message_center/unified_message_list_view.cc index 35c824c7..aabf421 100644 --- a/ash/system/message_center/unified_message_list_view.cc +++ b/ash/system/message_center/unified_message_list_view.cc
@@ -743,7 +743,7 @@ case State::IDLE: case State::EXPAND_OR_COLLAPSE: expand_or_collapsing_container_ = nullptr; - FALLTHROUGH; + [[fallthrough]]; case State::MOVE_DOWN: state_ = State::IDLE; break;
diff --git a/ash/system/network/auto_connect_notifier.cc b/ash/system/network/auto_connect_notifier.cc index ccb80413..4e11ba4 100644 --- a/ash/system/network/auto_connect_notifier.cc +++ b/ash/system/network/auto_connect_notifier.cc
@@ -32,11 +32,8 @@ // a notification. constexpr const base::TimeDelta kNetworkConnectionTimeout = base::Seconds(3); -constexpr int kToastDurationMs = 2500; - void ShowToast(std::string id, const std::u16string& text) { - ash::ToastManager::Get()->Show(ToastData(id, text, kToastDurationMs, - /*dismiss_text=*/absl::nullopt)); + ash::ToastManager::Get()->Show(ToastData(id, text)); } } // namespace
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index 934c02c..e87d5a8 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -30,7 +30,6 @@ namespace { const char kToastId[] = "palette_metalayer_mode"; -const int kToastDurationMs = 2500; // If the last stroke happened within this amount of time, // assume writing/sketching usage. @@ -137,11 +136,9 @@ if (loading()) { // Repetitive presses will create toasts with the same id which will be // ignored. - ToastData toast( - kToastId, - l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING), - kToastDurationMs, absl::optional<std::u16string>()); - Shell::Get()->toast_manager()->Show(toast); + Shell::Get()->toast_manager()->Show( + ToastData(kToastId, l10n_util::GetStringUTF16( + IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING))); } else { delegate()->RecordPaletteOptionsUsage( PaletteToolIdToPaletteTrayOptions(GetToolId()),
diff --git a/ash/system/phonehub/phone_hub_metrics.cc b/ash/system/phonehub/phone_hub_metrics.cc index 4d44464..9fbabe07 100644 --- a/ash/system/phonehub/phone_hub_metrics.cc +++ b/ash/system/phonehub/phone_hub_metrics.cc
@@ -97,6 +97,10 @@ interaction); } +void LogNotificationMessageLength(int length) { + base::UmaHistogramCounts10000("PhoneHub.NotificationMessageLength", length); +} + std::string GetCameraRollMediaTypeSubcategoryName( CameraRollMediaType mediaType) { switch (mediaType) {
diff --git a/ash/system/phonehub/phone_hub_metrics.h b/ash/system/phonehub/phone_hub_metrics.h index 446d59f..e8d65f4 100644 --- a/ash/system/phonehub/phone_hub_metrics.h +++ b/ash/system/phonehub/phone_hub_metrics.h
@@ -117,6 +117,9 @@ // Logs a given |interaction| with a PhoneHub notification. void LogNotificationInteraction(NotificationInteraction interaction); +// Logs the message length of a PhoneHub notification. +void LogNotificationMessageLength(int length); + // Logs the display of a Camera Roll item at |index|. void LogCameraRollContentShown(int index, CameraRollMediaType mediaType);
diff --git a/ash/system/phonehub/phone_hub_notification_controller.cc b/ash/system/phonehub/phone_hub_notification_controller.cc index 35e6bf7..93c4805 100644 --- a/ash/system/phonehub/phone_hub_notification_controller.cc +++ b/ash/system/phonehub/phone_hub_notification_controller.cc
@@ -766,6 +766,9 @@ shown_notification_ids_.insert(phone_hub_id); + phone_hub_metrics::LogNotificationMessageLength( + cros_notification->message().length()); + auto* message_center = message_center::MessageCenter::Get(); if (notification_already_exists) message_center->UpdateNotification(cros_id, std::move(cros_notification));
diff --git a/ash/system/time/calendar_month_view.cc b/ash/system/time/calendar_month_view.cc index 9abb9bdb..2c5a3bc 100644 --- a/ash/system/time/calendar_month_view.cc +++ b/ash/system/time/calendar_month_view.cc
@@ -11,6 +11,7 @@ #include "ash/system/time/calendar_view_controller.h" #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/check.h" #include "base/i18n/time_formatting.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" @@ -45,9 +46,13 @@ void MoveToNextDay(int& column, base::Time& current_date, base::Time::Exploded& current_date_exploded) { - current_date += base::Days(1); + // Using 30 hours to make sure the date is moved to the next day, since there + // are daylight saving days which have more than 24 hours in a day. + // `base::Days(1)` cannot be used, because it is 24 hours. + current_date = current_date.LocalMidnight() + base::Hours(30); current_date.LocalExplode(¤t_date_exploded); column = (column + 1) % calendar_utils::kDateInOneWeek; + DCHECK_EQ(column, current_date_exploded.day_of_week); } } // namespace
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc index 41dfaf4..75172c4 100644 --- a/ash/system/toast/toast_manager_unittest.cc +++ b/ash/system/toast/toast_manager_unittest.cc
@@ -100,7 +100,7 @@ bool visible_on_lock_screen = false) { std::string id = "TOAST_ID_" + base::NumberToString(serial_++); manager()->Show(ToastData(id, base::ASCIIToUTF16(text), duration, - std::u16string(), visible_on_lock_screen)); + visible_on_lock_screen)); return id; } @@ -113,8 +113,9 @@ localized_dismiss = base::ASCIIToUTF16(dismiss_text.value()); std::string id = "TOAST_ID_" + base::NumberToString(serial_++); - manager()->Show( - ToastData(id, base::ASCIIToUTF16(text), duration, localized_dismiss)); + manager()->Show(ToastData(id, base::ASCIIToUTF16(text), duration, + /*visible_on_lock_screen=*/false, + localized_dismiss)); return id; } @@ -142,7 +143,7 @@ } TEST_F(ToastManagerImplTest, ShowAndCloseManually) { - ShowToast("DUMMY", ToastData::kInfiniteDuration); + ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, "Dismiss"); EXPECT_EQ(1, GetToastSerial()); @@ -158,7 +159,7 @@ ui::ScopedAnimationDurationScaleMode slow_animation_duration( ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); - ShowToast("DUMMY", ToastData::kInfiniteDuration); + ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, "Dismiss"); EXPECT_TRUE(GetCurrentWidget()->GetLayer()->GetAnimator()->is_animating()); base::RunLoop().RunUntilIdle();
diff --git a/ash/wallpaper/test_wallpaper_controller_client.cc b/ash/wallpaper/test_wallpaper_controller_client.cc index d487aa5a..32c0331 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.cc +++ b/ash/wallpaper/test_wallpaper_controller_client.cc
@@ -91,11 +91,12 @@ } } -bool TestWallpaperControllerClient::SaveWallpaperToDriveFs( +void TestWallpaperControllerClient::SaveWallpaperToDriveFs( const AccountId& account_id, - const base::FilePath& origin) { + const base::FilePath& origin, + base::OnceCallback<void(bool)> wallpaper_saved_callback) { save_wallpaper_to_drive_fs_account_id_ = account_id; - return true; + std::move(wallpaper_saved_callback).Run(true); } base::FilePath TestWallpaperControllerClient::GetWallpaperPathFromDriveFs(
diff --git a/ash/wallpaper/test_wallpaper_controller_client.h b/ash/wallpaper/test_wallpaper_controller_client.h index 12e2afe..5312188 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.h +++ b/ash/wallpaper/test_wallpaper_controller_client.h
@@ -68,8 +68,10 @@ void FetchImagesForCollection( const std::string& collection_id, FetchImagesForCollectionCallback callback) override; - bool SaveWallpaperToDriveFs(const AccountId& account_id, - const base::FilePath& origin) override; + void SaveWallpaperToDriveFs( + const AccountId& account_id, + const base::FilePath& origin, + base::OnceCallback<void(bool)> wallpaper_saved_callback) override; base::FilePath GetWallpaperPathFromDriveFs( const AccountId& account_id) override; void GetFilesId(const AccountId& account_id,
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 50dc23ca..fae47ef 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1140,8 +1140,9 @@ SaveAndSetWallpaperWithCompletion( account_id, file_name, WallpaperType::kCustomized, layout, /*show_wallpaper=*/is_active_user, image, - base::BindOnce(&WallpaperControllerImpl::SaveWallpaperToDriveFs, - weak_factory_.GetWeakPtr(), account_id)); + base::BindOnce( + &WallpaperControllerImpl::SaveWallpaperToDriveFsAndSyncInfo, + weak_factory_.GetWeakPtr(), account_id)); } } @@ -1765,7 +1766,7 @@ if (local_info.type == WallpaperType::kCustomized) { base::FilePath source = GetCustomWallpaperDir(kOriginalWallpaperSubDir) .Append(local_info.location); - SaveWallpaperToDriveFs(account_id, source); + SaveWallpaperToDriveFsAndSyncInfo(account_id, source); } else { SetSyncedWallpaperInfo(account_id, local_info); wallpaper_controller_client_->MigrateCollectionIdFromChromeApp( @@ -2746,7 +2747,7 @@ // which may not be available at the time of setting the local_info. base::FilePath source = GetCustomWallpaperDir(kOriginalWallpaperSubDir) .Append(local_info.location); - SaveWallpaperToDriveFs(account_id, source); + SaveWallpaperToDriveFsAndSyncInfo(account_id, source); } } @@ -2857,7 +2858,7 @@ base::Time::Now().ToDeltaSinceWindowsEpoch() + base::Days(1); } -void WallpaperControllerImpl::SaveWallpaperToDriveFs( +void WallpaperControllerImpl::SaveWallpaperToDriveFsAndSyncInfo( const AccountId& account_id, const base::FilePath& origin_path) { if (!features::IsWallpaperWebUIEnabled()) @@ -2866,10 +2867,17 @@ return; if (!wallpaper_controller_client_->IsWallpaperSyncEnabled(account_id)) return; - if (!wallpaper_controller_client_->SaveWallpaperToDriveFs(account_id, - origin_path)) { + wallpaper_controller_client_->SaveWallpaperToDriveFs( + account_id, origin_path, + base::BindOnce(&WallpaperControllerImpl::WallpaperSavedToDriveFS, + weak_factory_.GetWeakPtr(), account_id)); +} + +void WallpaperControllerImpl::WallpaperSavedToDriveFS( + const AccountId& account_id, + bool success) { + if (!success) return; - } WallpaperInfo local_info; CHECK(GetLocalWallpaperInfo(account_id, &local_info)); SetSyncedWallpaperInfo(account_id, local_info);
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index 5f1abc1b..ba24171c 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -665,8 +665,10 @@ // wallpaper set. base::TimeDelta GetTimeToNextDailyRefreshUpdate() const; - void SaveWallpaperToDriveFs(const AccountId& account_id, - const base::FilePath& origin_path); + void SaveWallpaperToDriveFsAndSyncInfo(const AccountId& account_id, + const base::FilePath& origin_path); + + void WallpaperSavedToDriveFS(const AccountId& account_id, bool success); void HandleCustomWallpaperInfoSyncedIn(const AccountId& account_id, WallpaperInfo info);
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 0f4f287..0be0e06 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -3358,6 +3358,16 @@ } TEST_F(WallpaperControllerWallpaperWebUiTest, MigrateWallpaperInfo) { + WallpaperInfo expected_info = InfoWithType(WallpaperType::kOnline); + PutWallpaperInfoInPrefs(account_id_1, expected_info, GetLocalPrefService(), + prefs::kUserWallpaperInfo); + SimulateUserLogin(account_id_1); + AssertWallpaperInfoInPrefs(GetProfilePrefService(account_id_1), + prefs::kSyncableWallpaperInfo, account_id_1, + expected_info); +} + +TEST_F(WallpaperControllerWallpaperWebUiTest, MigrateWallpaperInfoCustomized) { WallpaperInfo expected_info = InfoWithType(WallpaperType::kCustomized); PutWallpaperInfoInPrefs(account_id_1, expected_info, GetLocalPrefService(), prefs::kUserWallpaperInfo);
diff --git a/ash/webui/camera_app_ui/resources/js/js.gni b/ash/webui/camera_app_ui/resources/js/js.gni index 5254751..80546e96 100644 --- a/ash/webui/camera_app_ui/resources/js/js.gni +++ b/ash/webui/camera_app_ui/resources/js/js.gni
@@ -72,11 +72,11 @@ "views/camera.ts", "views/camera/layout.js", "views/camera/mode/index.ts", - "views/camera/mode/mode_base.js", + "views/camera/mode/mode_base.ts", "views/camera/mode/photo.js", "views/camera/mode/portrait.js", "views/camera/mode/record_time.js", - "views/camera/mode/scan.js", + "views/camera/mode/scan.ts", "views/camera/mode/square.js", "views/camera/mode/video.js", "views/camera/document_corner_overlay.js",
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.js deleted file mode 100644 index 72866e05..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.js +++ /dev/null
@@ -1,201 +0,0 @@ -// Copyright (c) 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assertInstanceof, assertNotReached} from '../../../assert.js'; -// eslint-disable-next-line no-unused-vars -import {StreamConstraints} from '../../../device/stream_constraints.js'; -import * as error from '../../../error.js'; -import { - CanceledError, - ErrorLevel, - ErrorType, - Facing, // eslint-disable-line no-unused-vars - Resolution, // eslint-disable-line no-unused-vars -} from '../../../type.js'; - -/** - * Base class for controlling capture sequence in different camera modes. - * @abstract - */ -export class ModeBase { - /** - * @param {!MediaStream} stream - * @param {!Facing} facing - */ - constructor(stream, facing) { - /** - * Stream of current mode. - * @type {!MediaStream} - * @protected - */ - this.stream_ = stream; - - /** - * Camera facing of current mode. - * @type {!Facing} - * @protected - */ - this.facing_ = facing; - - /** - * Promise for ongoing capture operation. - * @type {?Promise<function(): Promise<void>>} - * @private - */ - this.capture_ = null; - } - - /** - * Initiates video/photo capture operation. - * @return {!Promise<function(): Promise<void>>} Promise for ongoing capture - * operation and resolved to handler function which should be run after - * capture finished. - */ - startCapture() { - if (this.capture_ === null) { - this.capture_ = (async () => { - try { - return await this.start_(); - } finally { - this.capture_ = null; - } - })(); - } - return this.capture_; - } - - /** - * Stops the ongoing capture operation. - * @return {!Promise} Promise for ongoing capture operation. - */ - async stopCapture() { - this.stop_(); - try { - await this.capture_; - } catch (e) { - if (e instanceof CanceledError) { - return; - } - error.reportError( - ErrorType.STOP_CAPTURE_FAILURE, ErrorLevel.ERROR, - assertInstanceof(e, Error)); - } - } - - /** - * Adds an observer to save image metadata. - * @return {!Promise} Promise for the operation. - */ - async addMetadataObserver() {} - - /** - * Removes the observer that saves metadata. - * @return {!Promise} Promise for the operation. - */ - async removeMetadataObserver() {} - - /** - * Clears everything when mode is not needed anymore. - * @return {!Promise} - */ - async clear() { - await this.stopCapture(); - } - - /** - * Updates preview stream currently in used. - * @param {!MediaStream} stream - * @abstract - */ - updatePreview(stream) {} - - /** - * Initiates video/photo capture operation under this mode. - * @return {!Promise<function(): !Promise<void>>} Promise for ongoing capture - * operation and resolved to handler function which should be run after - * capture finished. - * @protected - * @abstract - */ - async start_() { - assertNotReached(); - } - - /** - * Stops the ongoing capture operation under this mode. - * @protected - */ - stop_() {} -} - -/** - * @abstract - */ -export class ModeFactory { - /** - * @param {!StreamConstraints} constraints Constraints for preview - * stream. - * @param {!Resolution} captureResolution - */ - constructor(constraints, captureResolution) { - /** - * Preview stream. - * @type {?MediaStream} - * @protected - */ - this.stream_ = null; - - /** - * Camera facing of current mode. - * @type {!Facing} - * @protected - */ - this.facing_ = Facing.NOT_SET; - - /** - * Preview constraints. - * @type {!StreamConstraints} - * @protected - */ - this.constraints_ = constraints; - - /** - * Capture resolution. - * @type {!Resolution} - * @protected - */ - this.captureResolution_ = captureResolution; - } - - /** - * @return {!MediaStream} - * @protected - */ - get previewStream_() { - return assertInstanceof(this.stream_, MediaStream); - } - - /** - * @param {!Facing} facing - */ - setFacing(facing) { - this.facing_ = facing; - } - - /** - * @param {!MediaStream} stream - */ - setPreviewStream(stream) { - this.stream_ = stream; - } - - /** - * Produces the mode capture object. - * @return {!ModeBase} - * @abstract - */ - produce() { - assertNotReached(); - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.ts b/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.ts new file mode 100644 index 0000000..d3c5cf77 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/mode_base.ts
@@ -0,0 +1,145 @@ +// Copyright (c) 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assertInstanceof} from '../../../assert.js'; +import {StreamConstraints} from '../../../device/stream_constraints.js'; +import * as error from '../../../error.js'; +import { + CanceledError, + ErrorLevel, + ErrorType, + Facing, + Resolution, +} from '../../../type.js'; + +/** + * Base class for controlling capture sequence in different camera modes. + */ +export abstract class ModeBase { + /** + * Promise for ongoing capture operation. + */ + private capture: Promise<() => Promise<void>>|null = null; + + /** + * @param stream Stream of current mode. + * @param facing Camera facing of current mode. + */ + constructor( + protected readonly stream: MediaStream, + protected readonly facing: Facing) {} + + /** + * Initiates video/photo capture operation. + * @return Promise for ongoing capture operation and resolved to handler + * function which should be run after capture finished. + */ + startCapture(): Promise<() => Promise<void>> { + if (this.capture === null) { + this.capture = (async () => { + try { + return await this.start(); + } finally { + this.capture = null; + } + })(); + } + return this.capture; + } + + /** + * Stops the ongoing capture operation. + * @return Promise for ongoing capture operation. + */ + async stopCapture(): Promise<void> { + this.stop(); + try { + await this.capture; + } catch (e) { + if (e instanceof CanceledError) { + return; + } + error.reportError( + ErrorType.STOP_CAPTURE_FAILURE, ErrorLevel.ERROR, + assertInstanceof(e, Error)); + } + } + + /** + * Adds an observer to save image metadata. + * @return Promise for the operation. + */ + async addMetadataObserver(): Promise<void> { + // To be overridden by subclass. + } + + /** + * Removes the observer that saves metadata. + * @return Promise for the operation. + */ + async removeMetadataObserver(): Promise<void> { + // To be overridden by subclass. + } + + /** + * Clears everything when mode is not needed anymore. + */ + async clear(): Promise<void> { + await this.stopCapture(); + } + + /** + * Updates preview stream currently in used. + */ + abstract updatePreview(stream: MediaStream): void; + + /** + * Initiates video/photo capture operation under this mode. + */ + protected abstract start(): Promise<() => Promise<void>>; + + /** + * Stops the ongoing capture operation under this mode. + */ + protected stop(): void { + // To be overridden by subclass. + } +} + +export abstract class ModeFactory { + /** + * Preview stream. + */ + protected stream: MediaStream|null = null; + + /** + * Camera facing of current mode. + */ + protected facing = Facing.NOT_SET; + + /** + * @param constraints Constraints for preview stream. + * @param captureResolution Capture resolution. + */ + constructor( + protected readonly constraints: StreamConstraints, + protected readonly captureResolution: Resolution) {} + + protected get previewStream(): MediaStream { + return assertInstanceof(this.stream, MediaStream); + } + + setFacing(facing: Facing): void { + this.facing = facing; + } + + setPreviewStream(stream: MediaStream): void { + this.stream = stream; + } + + /** + * Produces the mode capture object. + */ + abstract produce(): ModeBase; +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/photo.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/photo.js index e06c46c..b0603d3 100644 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/photo.js +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/photo.js
@@ -138,7 +138,7 @@ /** * @override */ - async start_() { + async start() { const timestamp = Date.now(); state.set(PerfEvent.PHOTO_CAPTURE_SHUTTER, true); const {blob, pendingMetadata} = await (async () => { @@ -152,7 +152,7 @@ } finally { state.set( PerfEvent.PHOTO_CAPTURE_SHUTTER, false, - hasError ? {hasError} : {facing: this.facing_}); + hasError ? {hasError} : {facing: this.facing}); } })(); @@ -294,7 +294,6 @@ */ produce() { return new Photo( - this.previewStream_, this.facing_, this.captureResolution_, - this.handler_); + this.previewStream, this.facing, this.captureResolution, this.handler_); } }
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/portrait.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/portrait.js index 90c4baad..bbd10a3 100644 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/portrait.js +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/portrait.js
@@ -74,7 +74,7 @@ /** * @override */ - async start_() { + async start() { const timestamp = Date.now(); if (this.crosImageCapture_ === null) { this.crosImageCapture_ = @@ -167,7 +167,7 @@ */ produce() { return new Portrait( - this.previewStream_, this.facing_, this.captureResolution_, + this.previewStream, this.facing, this.captureResolution, this.portraitHandler_); } }
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.js deleted file mode 100644 index 4d40bf4..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.js +++ /dev/null
@@ -1,146 +0,0 @@ -// 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. - -// eslint-disable-next-line no-unused-vars -import {StreamConstraints} from '../../../device/stream_constraints.js'; -import {Point} from '../../../geometry.js'; -import { - Facing, // eslint-disable-line no-unused-vars - ImageBlob, // eslint-disable-line no-unused-vars - Resolution, // eslint-disable-line no-unused-vars -} from '../../../type.js'; - -import {ModeFactory} from './mode_base.js'; -import { - Photo, - PhotoHandler, // eslint-disable-line no-unused-vars - PhotoResult, // eslint-disable-line no-unused-vars -} from './photo.js'; - -/** - * @param {!Resolution} size Size of image to be cropped document from. - * @return {!Array<!Point>} - */ -export function getDefaultScanCorners(size) { - // No initial guess from scan API, position corners in box of portrait A4 - // size occupied with 80% center area. - const WIDTH_A4 = 210; - const HEIGHT_A4 = 297; - const {width: w, height: h} = size; - const [width, height] = size.aspectRatio > WIDTH_A4 / HEIGHT_A4 ? - [h / w * WIDTH_A4 / HEIGHT_A4 * 0.8, 0.8] : - [0.8, w / h * HEIGHT_A4 / WIDTH_A4 * 0.8]; - return [ - new Point(0.5 - width / 2, 0.5 - height / 2), - new Point(0.5 - width / 2, 0.5 + height / 2), - new Point(0.5 + width / 2, 0.5 + height / 2), - new Point(0.5 + width / 2, 0.5 - height / 2), - ]; -} - -/** - * Provides external dependency functions used by photo mode and handles the - * captured result photo. - * @interface - */ -export class ScanHandler extends PhotoHandler { - /** - * @param {!Promise<!PhotoResult>} pendingPhotoResult - * @return {!Promise} - * @abstract - */ - async onDocumentCaptureDone(pendingPhotoResult) {} -} - -/** - * @implements {PhotoHandler} - */ -class DocumentPhotoHandler { - /** - * @param {!ScanHandler} handler - */ - constructor(handler) { - /** - * @const {!ScanHandler} - * @private - */ - this.handler_ = handler; - } - - /** - * @override - */ - playShutterEffect() { - this.handler_.playShutterEffect(); - } - - /** - * @override - */ - waitPreviewReady() { - return this.handler_.waitPreviewReady(); - } - - /** - * @override - */ - onPhotoError() { - this.handler_.onPhotoError(); - } - - /** - * @override - */ - onPhotoCaptureDone(pendingPhotoResult) { - return this.handler_.onDocumentCaptureDone(pendingPhotoResult); - } -} - -/** - * Photo mode capture controller. - */ -export class Scan extends Photo { - /** - * @param {!MediaStream} stream - * @param {!Facing} facing - * @param {!Resolution} captureResolution - * @param {!ScanHandler} handler - */ - constructor(stream, facing, captureResolution, handler) { - super(stream, facing, captureResolution, new DocumentPhotoHandler(handler)); - } -} - -/** - * Factory for creating photo mode capture object. - */ -export class ScanFactory extends ModeFactory { - /** - * @param {!StreamConstraints} constraints Constraints for preview - * stream. - * @param {!Resolution} captureResolution - * @param {!ScanHandler} handler - */ - constructor(constraints, captureResolution, handler) { - super(constraints, captureResolution); - - /** - * @const {!ScanHandler} - * @protected - */ - this.handler_ = handler; - } - - /** - * @override - */ - produce() { - return new Scan( - this.previewStream_, - this.facing_, - this.captureResolution_, - this.handler_, - ); - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.ts b/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.ts new file mode 100644 index 0000000..4359ee43 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/scan.ts
@@ -0,0 +1,102 @@ +// 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 {StreamConstraints} from '../../../device/stream_constraints.js'; +import {Point} from '../../../geometry.js'; +import { + Facing, + Resolution, +} from '../../../type.js'; + +import {ModeBase, ModeFactory} from './mode_base.js'; +import { + Photo, + PhotoHandler, + PhotoResult, +} from './photo.js'; + +/** + * @param size Size of image to be cropped document from. + */ +export function getDefaultScanCorners(size: Resolution): Point[] { + // No initial guess from scan API, position corners in box of portrait A4 + // size occupied with 80% center area. + const WIDTH_A4 = 210; + const HEIGHT_A4 = 297; + const {width: w, height: h} = size; + const [width, height] = size.aspectRatio > WIDTH_A4 / HEIGHT_A4 ? + [h / w * WIDTH_A4 / HEIGHT_A4 * 0.8, 0.8] : + [0.8, w / h * HEIGHT_A4 / WIDTH_A4 * 0.8]; + return [ + new Point(0.5 - width / 2, 0.5 - height / 2), + new Point(0.5 - width / 2, 0.5 + height / 2), + new Point(0.5 + width / 2, 0.5 + height / 2), + new Point(0.5 + width / 2, 0.5 - height / 2), + ]; +} + +/** + * Provides external dependency functions used by photo mode and handles the + * captured result photo. + */ +export interface ScanHandler extends PhotoHandler { + onDocumentCaptureDone(pendingPhotoResult: Promise<PhotoResult>): + Promise<void>; +} + +class DocumentPhotoHandler implements PhotoHandler { + constructor(private readonly handler: ScanHandler) {} + + playShutterEffect(): void { + this.handler.playShutterEffect(); + } + + waitPreviewReady(): Promise<void> { + return this.handler.waitPreviewReady(); + } + + onPhotoError(): void { + this.handler.onPhotoError(); + } + + onPhotoCaptureDone(pendingPhotoResult: Promise<PhotoResult>): Promise<void> { + return this.handler.onDocumentCaptureDone(pendingPhotoResult); + } +} + +/** + * Photo mode capture controller. + */ +export class Scan extends Photo { + constructor( + stream: MediaStream, facing: Facing, captureResolution: Resolution, + scanHandler: ScanHandler) { + super( + stream, facing, captureResolution, + new DocumentPhotoHandler(scanHandler)); + } +} + +/** + * Factory for creating photo mode capture object. + */ +export class ScanFactory extends ModeFactory { + /** + * @param constraints Constraints for preview stream. + */ + constructor( + constraints: StreamConstraints, captureResolution: Resolution, + protected readonly handler: ScanHandler) { + super(constraints, captureResolution); + } + + produce(): ModeBase { + return new Scan( + this.previewStream, + this.facing, + this.captureResolution, + this.handler, + ); + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/square.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/square.js index a7046cc5..a4b6d47 100644 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/square.js +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/square.js
@@ -114,7 +114,6 @@ */ produce() { return new Square( - this.previewStream_, this.facing_, this.captureResolution_, - this.handler_); + this.previewStream, this.facing, this.captureResolution, this.handler_); } }
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/mode/video.js b/ash/webui/camera_app_ui/resources/js/views/camera/mode/video.js index b5442fe..fbf2ada 100644 --- a/ash/webui/camera_app_ui/resources/js/views/camera/mode/video.js +++ b/ash/webui/camera_app_ui/resources/js/views/camera/mode/video.js
@@ -288,7 +288,7 @@ * @private */ this.gifRecordTime_ = new GifRecordTime( - {maxTime: MAX_GIF_DURATION_MS, onMaxTimeout: () => this.stop_()}); + {maxTime: MAX_GIF_DURATION_MS, onMaxTimeout: () => this.stop()}); /** * Record type of ongoing recording. @@ -336,7 +336,7 @@ */ updatePreview(stream) { assert(!state.get(state.State.RECORDING)); - this.stream_ = stream; + this.stream = stream; this.crosImageCapture_ = new CrosImageCapture(this.getVideoTrack_()); } @@ -358,7 +358,7 @@ */ async isBlobVideoSnapshotEnabled() { const deviceOperator = await DeviceOperator.getInstance(); - const deviceId = this.stream_.getVideoTracks()[0].getSettings().deviceId; + const deviceId = this.stream.getVideoTracks()[0].getSettings().deviceId; return deviceOperator !== null && (await deviceOperator.isBlobVideoSnapshotEnabled(deviceId)); } @@ -480,7 +480,7 @@ if (this.captureStream_ !== null) { return this.captureStream_; } - return this.stream_; + return this.stream; } /** @@ -494,7 +494,7 @@ /** * @override */ - async start_() { + async start() { assert(this.snapshotting_ === null); this.togglePaused_ = null; this.everPaused_ = false; @@ -514,7 +514,7 @@ // Blob stream is configured on the original device rather than the // virtual one when multi-stream is enabled. this.crosImageCapture_ = - new CrosImageCapture(this.stream_.getVideoTracks()[0]); + new CrosImageCapture(this.stream.getVideoTracks()[0]); } else { this.crosImageCapture_ = new CrosImageCapture(this.getVideoTrack_()); } @@ -608,7 +608,7 @@ /** * @override */ - stop_() { + stop() { if (this.recordingType_ === RecordType.GIF) { state.set(state.State.RECORDING, false); } else { @@ -759,19 +759,19 @@ let captureConstraints = null; if (state.get(state.State.ENABLE_MULTISTREAM_RECORDING)) { const {width, height} = - assertInstanceof(this.captureResolution_, Resolution); + assertInstanceof(this.captureResolution, Resolution); captureConstraints = { - deviceId: this.constraints_.deviceId, - audio: this.constraints_.audio, + deviceId: this.constraints.deviceId, + audio: this.constraints.audio, video: { - frameRate: this.constraints_.video.frameRate, + frameRate: this.constraints.video.frameRate, width, height, }, }; } return new Video( - this.previewStream_, captureConstraints, this.captureResolution_, - this.snapshotResolution_, this.facing_, this.handler_); + this.previewStream, captureConstraints, this.captureResolution, + this.snapshotResolution_, this.facing, this.handler_); } }
diff --git a/ash/webui/common/resources/keyboard_icons.html b/ash/webui/common/resources/keyboard_icons.html index 9724acc..1bd41ed 100644 --- a/ash/webui/common/resources/keyboard_icons.html +++ b/ash/webui/common/resources/keyboard_icons.html
@@ -7,10 +7,10 @@ <g id="arrow-right"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></g> <g id="arrow-up"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></g> <g id="assistant"> - <path d="m 8.36364,4.72725 c 2.41018,0 4.36366,1.95418 4.36366,4.36364 0,2.40945 -1.95348,4.36366 -4.36366,4.36366 C 5.95345,13.45455 4,11.50034 4,9.09089 4,6.68143 5.95345,4.72725 8.36364,4.72725 Z"> - <path d="m 20,8.72722 c 0,0.60218 -0.4887,1.09091 -1.0909,1.09091 -0.6022,0 -1.0909,-0.48873 -1.0909,-1.09091 0,-0.60219 0.4887,-1.09091 1.0909,-1.09091 0.6022,0 1.0909,0.48872 1.0909,1.09091 z"> - <path d="m 17.8182,11.27272 c 0,1.20513 -0.9768,2.18183 -2.1819,2.18183 -1.205,0 -2.1818,-0.9767 -2.1818,-2.18183 0,-1.2051 0.9768,-2.18182 2.1818,-2.18182 1.2051,0 2.1819,0.97672 2.1819,2.18182 z"> - <path d="m 15.6363,19.27275 c 1.4059,0 2.5455,-1.1396 2.5455,-2.5455 0,-1.4058 -1.1396,-2.5454 -2.5455,-2.5454 -1.4058,0 -2.5454,1.1396 -2.5454,2.5454 0,1.4059 1.1396,2.5455 2.5454,2.5455 z"> + <path d="m 8.36364,4.72725 c 2.41018,0 4.36366,1.95418 4.36366,4.36364 0,2.40945 -1.95348,4.36366 -4.36366,4.36366 C 5.95345,13.45455 4,11.50034 4,9.09089 4,6.68143 5.95345,4.72725 8.36364,4.72725 Z"></path> + <path d="m 20,8.72722 c 0,0.60218 -0.4887,1.09091 -1.0909,1.09091 -0.6022,0 -1.0909,-0.48873 -1.0909,-1.09091 0,-0.60219 0.4887,-1.09091 1.0909,-1.09091 0.6022,0 1.0909,0.48872 1.0909,1.09091 z"></path> + <path d="m 17.8182,11.27272 c 0,1.20513 -0.9768,2.18183 -2.1819,2.18183 -1.205,0 -2.1818,-0.9767 -2.1818,-2.18183 0,-1.2051 0.9768,-2.18182 2.1818,-2.18182 1.2051,0 2.1819,0.97672 2.1819,2.18182 z"></path> + <path d="m 15.6363,19.27275 c 1.4059,0 2.5455,-1.1396 2.5455,-2.5455 0,-1.4058 -1.1396,-2.5454 -2.5455,-2.5454 -1.4058,0 -2.5454,1.1396 -2.5454,2.5454 0,1.4059 1.1396,2.5455 2.5454,2.5455 z"></path> </g> <g id="back"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"></g> <g id="display-brightness-down" viewbox="0 0 20 20"><path fill-rule="evenodd" d="M9.99982 4.13281L11.7889 5.87499H14.1285V8.15322L15.7799 9.76139L14.1285 11.5036V13.7818H11.7889L9.99982 15.39L8.34836 13.7818H6.00878V11.5036L4.21973 9.76139L6.00878 8.15322V5.87499H8.34836L9.99982 4.13281ZM9.99982 6.41105L8.89883 7.48315H7.66025V8.68928L6.5593 9.76139L7.66025 10.9675V12.0396H8.89883L9.99982 13.2457L11.2384 12.0396H12.3394V10.9675L13.5779 9.76139L12.3394 8.68928V7.48315H11.2384L9.99982 6.41105Z"></g>
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.cc b/ash/webui/diagnostics_ui/backend/session_log_handler.cc index a805a94..3209771 100644 --- a/ash/webui/diagnostics_ui/backend/session_log_handler.cc +++ b/ash/webui/diagnostics_ui/backend/session_log_handler.cc
@@ -64,31 +64,39 @@ telemetry_log_(std::move(telemetry_log)), routine_log_(std::move(routine_log)), networking_log_(std::move(networking_log)), - holding_space_client_(holding_space_client) { + holding_space_client_(holding_space_client), + task_runner_( + base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})) { DCHECK(holding_space_client_); + weak_ptr_ = weak_factory_.GetWeakPtr(); } -SessionLogHandler::~SessionLogHandler() = default; +SessionLogHandler::~SessionLogHandler() { + if (select_file_dialog_) { + /* Lifecycle for SelectFileDialog is responsibility of calling code. */ + select_file_dialog_->ListenerDestroyed(); + } +} void SessionLogHandler::RegisterMessages() { web_ui()->RegisterDeprecatedMessageCallback( - "initialize", base::BindRepeating(&SessionLogHandler::HandleInitialize, - base::Unretained(this))); + "initialize", + base::BindRepeating(&SessionLogHandler::HandleInitialize, weak_ptr_)); web_ui()->RegisterDeprecatedMessageCallback( "saveSessionLog", base::BindRepeating(&SessionLogHandler::HandleSaveSessionLogRequest, - base::Unretained(this))); + weak_ptr_)); } void SessionLogHandler::FileSelected(const base::FilePath& path, int index, void* params) { - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&SessionLogHandler::CreateSessionLog, base::Unretained(this), path), - base::BindOnce(&SessionLogHandler::OnSessionLogCreated, - weak_factory_.GetWeakPtr(), path)); + base::BindOnce(&SessionLogHandler::OnSessionLogCreated, weak_ptr_, path)); + select_file_dialog_.reset(); } void SessionLogHandler::OnSessionLogCreated(const base::FilePath& file_path, @@ -109,6 +117,7 @@ RejectJavascriptCallback(base::Value(save_session_log_callback_id_), /*success=*/base::Value(false)); save_session_log_callback_id_ = ""; + select_file_dialog_.reset(); } TelemetryLog* SessionLogHandler::GetTelemetryLog() const { @@ -123,6 +132,11 @@ return networking_log_.get(); } +void SessionLogHandler::SetTaskRunnerForTesting( + const scoped_refptr<base::SequencedTaskRunner>& task_runner) { + task_runner_ = std::move(task_runner.get()); +} + void SessionLogHandler::SetWebUIForTest(content::WebUI* web_ui) { set_web_ui(web_ui); }
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.h b/ash/webui/diagnostics_ui/backend/session_log_handler.h index 60264ca..49ef591 100644 --- a/ash/webui/diagnostics_ui/backend/session_log_handler.h +++ b/ash/webui/diagnostics_ui/backend/session_log_handler.h
@@ -72,6 +72,9 @@ RoutineLog* GetRoutineLog() const; NetworkingLog* GetNetworkingLog() const; + // Sets the task runner to use for testing. + void SetTaskRunnerForTesting( + const scoped_refptr<base::SequencedTaskRunner>& task_runner); void SetWebUIForTest(content::WebUI* web_ui); void SetLogCreatedClosureForTest(base::OnceClosure closure); @@ -95,7 +98,12 @@ std::string save_session_log_callback_id_; scoped_refptr<ui::SelectFileDialog> select_file_dialog_; base::OnceClosure log_created_closure_; + // Task runner for tasks posted by save session log handler. Used to ensure + // posted tasks are handled while SessionLogHandler is in scope to stop + // heap-use-after-free error. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::WeakPtr<SessionLogHandler> weak_ptr_; base::WeakPtrFactory<SessionLogHandler> weak_factory_{this}; };
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc index 75c868555..7dcacf2 100644 --- a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc +++ b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
@@ -22,6 +22,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/test/task_environment.h" +#include "base/test/test_simple_task_runner.h" #include "base/values.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_web_ui.h" @@ -149,7 +150,10 @@ class SessionLogHandlerTest : public testing::Test { public: SessionLogHandlerTest() - : task_environment_(), web_ui_(), session_log_handler_() { + : task_environment_(), + task_runner_(new base::TestSimpleTaskRunner()), + web_ui_(), + session_log_handler_() { EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); base::FilePath routine_log_path = temp_dir_.GetPath().AppendASCII(kRoutineLogFileName); @@ -165,15 +169,20 @@ std::move(networking_log), &holding_space_client_); session_log_handler_->SetWebUIForTest(&web_ui_); session_log_handler_->RegisterMessages(); + session_log_handler_->SetTaskRunnerForTesting(task_runner_); base::ListValue args; web_ui_.HandleReceivedMessage("initialize", &args); } ~SessionLogHandlerTest() override { + task_runner_.reset(); + task_environment_.RunUntilIdle(); ui::SelectFileDialog::SetFactory(nullptr); } + void RunTasks() { task_runner_->RunPendingTasks(); } + const content::TestWebUI::CallData& CallDataAtIndex(size_t index) { return *web_ui_.call_data()[index]; } @@ -185,6 +194,8 @@ protected: base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + // Task runner for tasks posted by save session log handler. + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; content::TestWebUI web_ui_; std::unique_ptr<diagnostics::SessionLogHandler> session_log_handler_; @@ -226,10 +237,11 @@ args.Append(kHandlerFunctionName); session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure()); web_ui_.HandleReceivedMessage("saveSessionLog", &args); - run_loop.Run(); + run_loop.RunUntilIdle(); const std::string expected_system_log_header = "=== System ==="; const std::string expected_system_info_section_name = "--- System Info ---"; const std::string expected_snapshot_time_prefix = "Snapshot Time: "; + RunTasks(); const std::vector<std::string> log_lines = GetCombinedLogContents(log_path); ASSERT_EQ(18u, log_lines.size()); EXPECT_EQ(expected_system_log_header, log_lines[0]); @@ -282,7 +294,8 @@ base::RunLoop run_loop; session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure()); web_ui_.HandleReceivedMessage("saveSessionLog", &args); - run_loop.Run(); + RunTasks(); + run_loop.RunUntilIdle(); EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size()); const content::TestWebUI::CallData& call_data = @@ -302,6 +315,7 @@ base::ListValue args; args.Append(kHandlerFunctionName); web_ui_.HandleReceivedMessage("saveSessionLog", &args); + RunTasks(); EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size()); const content::TestWebUI::CallData& call_data = @@ -323,7 +337,24 @@ base::RunLoop run_loop; session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure()); web_ui_.HandleReceivedMessage("saveSessionLog", &args); - run_loop.Run(); + RunTasks(); + run_loop.RunUntilIdle(); +} + +// Validates that the lifecycle clean up tasks are completed if the select file +// dialog is open when session_log_handler is destroyed. +TEST_F(SessionLogHandlerTest, CleanUpDialogOnDeconstruct) { + base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path"); + ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path)); + base::ListValue args; + args.Append(kHandlerFunctionName); + base::RunLoop run_loop; + + session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure()); + web_ui_.HandleReceivedMessage("saveSessionLog", &args); + EXPECT_NO_FATAL_FAILURE(session_log_handler_.reset()); + EXPECT_NO_FATAL_FAILURE(task_runner_.reset()); + EXPECT_NO_FATAL_FAILURE(run_loop.RunUntilIdle()); } } // namespace diagnostics
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.html b/ash/webui/diagnostics_ui/resources/diagnostics_app.html index a526814..66d97d3b 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
@@ -12,20 +12,26 @@ } #download-icon { - --iron-icon-fill-color: var(--cros-icon-color-prominent); - color: var(--cros-text-color-prominent); + --iron-icon-fill-color: currentColor; height: 20px; margin-inline-end: 8px; width: 20px; } .session-log-button { - color: var(--cros-text-color-prominent); border-radius: 16px; height: 32px; margin-inline: 16px; } + .session-log-button:not([disabled]) { + color: var(--cros-text-color-prominent); + } + + .session-log-button[disabled] { + color: var(--cros-text-color-disabled); + } + #toast { bottom: 0; left: 0; @@ -41,14 +47,14 @@ </diagnostics-sticky-banner> <div slot="bottom-nav-content-panel" class="session-log-container"> <cr-button on-click="onSessionLogClick_" class="session-log-button" - hidden="[[!isLoggedIn_]]"> + disabled="[[!saveSessionLogEnabled_]]" hidden="[[!isLoggedIn_]]"> <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon> <span>[[i18n('sessionLog')]]</span> </cr-button> </div> <div slot="bottom-nav-content-drawer" class="session-log-container"> <cr-button on-click="onSessionLogClick_" class="session-log-button" - hidden="[[!isLoggedIn_]]"> + disabled="[[!saveSessionLogEnabled_]]" hidden="[[!isLoggedIn_]]"> <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon> <span>[[i18n('sessionLog')]]</span> </cr-button>
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.js b/ash/webui/diagnostics_ui/resources/diagnostics_app.js index c7da3963..2f59b1c 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.js +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.js
@@ -46,6 +46,12 @@ value: '', }, + /** @protected {boolean} */ + saveSessionLogEnabled_: { + type: Boolean, + value: true, + }, + /** @private {boolean} */ showNavPanel_: { type: Boolean, @@ -118,6 +124,12 @@ /** @protected */ onSessionLogClick_() { + // Click already handled then leave early. + if (!this.saveSessionLogEnabled_) { + return; + } + + this.saveSessionLogEnabled_ = false; this.browserProxy_.saveSessionLog() .then( /* @type {boolean} */ (success) => { @@ -126,6 +138,9 @@ loadTimeData.getString(`sessionLogToastText${result}`); this.$.toast.show(); }) - .catch(() => {/* File selection cancelled */}); + .catch(() => {/* File selection cancelled */}) + .finally(() => { + this.saveSessionLogEnabled_ = true; + }); }, });
diff --git a/ash/webui/diagnostics_ui/resources/system_page.html b/ash/webui/diagnostics_ui/resources/system_page.html index 2b0196d2..46f9ff23 100644 --- a/ash/webui/diagnostics_ui/resources/system_page.html +++ b/ash/webui/diagnostics_ui/resources/system_page.html
@@ -32,9 +32,9 @@ } #download-icon { + --iron-icon-fill-color: currentColor; --iron-icon-height: 20px; --iron-icon-width: 20px; - color: var(--cros-icon-color-prominent); right: 4px; } @@ -100,7 +100,7 @@ <template is="dom-if" if="[[!isNetworkingEnabled]]"> <div class="session-log-container"> <cr-button on-click="onSessionLogClick_" class="session-log-button" - hidden="[[!isLoggedIn_]]"> + disabled="[[!saveSessionLogEnabled_]]" hidden="[[!isLoggedIn_]]"> <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon> <span>[[i18n('sessionLog')]]</span> </cr-button>
diff --git a/ash/webui/diagnostics_ui/resources/system_page.js b/ash/webui/diagnostics_ui/resources/system_page.js index 8616f22..8f7854b 100644 --- a/ash/webui/diagnostics_ui/resources/system_page.js +++ b/ash/webui/diagnostics_ui/resources/system_page.js
@@ -47,6 +47,12 @@ browserProxy_: null, properties: { + /** @protected {boolean} */ + saveSessionLogEnabled_: { + type: Boolean, + value: true, + }, + /** @private {boolean} */ showBatteryStatusCard_: { type: Boolean, @@ -149,6 +155,12 @@ /** @protected */ onSessionLogClick_() { + // Click already handled then leave early. + if (!this.saveSessionLogEnabled_) { + return; + } + + this.saveSessionLogEnabled_ = false; this.browserProxy_.saveSessionLog() .then( /* @type {boolean} */ (success) => { @@ -157,7 +169,10 @@ loadTimeData.getString(`sessionLogToastText${result}`); this.$.toast.show(); }) - .catch(() => {/* File selection cancelled */}); + .catch(() => {/* File selection cancelled */}) + .finally(() => { + this.saveSessionLogEnabled_ = true; + }); }, /** @private */
diff --git a/ash/webui/eche_app_ui/fake_apps_access_manager.cc b/ash/webui/eche_app_ui/fake_apps_access_manager.cc index df5c5f0..94924ff 100644 --- a/ash/webui/eche_app_ui/fake_apps_access_manager.cc +++ b/ash/webui/eche_app_ui/fake_apps_access_manager.cc
@@ -24,5 +24,19 @@ void FakeAppsAccessManager::OnSetupRequested() {} +void FakeAppsAccessManager::SetAppsSetupOperationStatus( + AppsAccessSetupOperation::Status new_status) { + switch (new_status) { + case AppsAccessSetupOperation::Status::kCompletedSuccessfully: + SetAccessStatusInternal(AccessStatus::kAccessGranted); + break; + default: + // Do not update access status based on other operation status values. + break; + } + + AppsAccessManager::SetAppsSetupOperationStatus(new_status); +} + } // namespace eche_app } // namespace ash
diff --git a/ash/webui/eche_app_ui/fake_apps_access_manager.h b/ash/webui/eche_app_ui/fake_apps_access_manager.h index a17fc38..107e26b7 100644 --- a/ash/webui/eche_app_ui/fake_apps_access_manager.h +++ b/ash/webui/eche_app_ui/fake_apps_access_manager.h
@@ -7,6 +7,12 @@ #include "ash/webui/eche_app_ui/apps_access_manager.h" +namespace chromeos { +namespace settings { +class MultideviceHandlerTest; +} // namespace settings +} // namespace chromeos + namespace ash { namespace eche_app { @@ -16,12 +22,19 @@ AccessStatus access_status = AccessStatus::kAvailableButNotGranted); ~FakeAppsAccessManager() override; + void SetAppsSetupOperationStatus(AppsAccessSetupOperation::Status new_status); + + using AppsAccessManager::IsSetupOperationInProgress; + // AppsAccessManager: AccessStatus GetAccessStatus() const override; - void SetAccessStatusInternal(AccessStatus access_status) override; void OnSetupRequested() override; private: + friend class chromeos::settings::MultideviceHandlerTest; + // AppsAccessManager: + void SetAccessStatusInternal(AccessStatus access_status) override; + AccessStatus access_status_; };
diff --git a/ash/webui/file_manager/untrusted_resources/files_browsable_content.js b/ash/webui/file_manager/untrusted_resources/files_browsable_content.js index ee2acf10..1de04aae 100644 --- a/ash/webui/file_manager/untrusted_resources/files_browsable_content.js +++ b/ash/webui/file_manager/untrusted_resources/files_browsable_content.js
@@ -72,12 +72,14 @@ contentUrl = URL.createObjectURL(sourceContent.data); break; default: - contentUrl = ''; + contentUrl = 'about:blank'; } if (browsable && subtype === 'PDF') { contentUrl += '#view=FitH'; } type = subtype; + contentUrl = contentUrl || 'about:blank'; + console.log('Setting iframe.src to: ' + contentUrl); contentsIframe.src = contentUrl; });
diff --git a/ash/webui/personalization_app/BUILD.gn b/ash/webui/personalization_app/BUILD.gn index 6ee8d75..f116736a 100644 --- a/ash/webui/personalization_app/BUILD.gn +++ b/ash/webui/personalization_app/BUILD.gn
@@ -11,9 +11,9 @@ sources = [ "personalization_app_ui.cc", "personalization_app_ui.h", - "personalization_app_ui_delegate.h", "personalization_app_url_constants.cc", "personalization_app_url_constants.h", + "personalization_app_wallpaper_provider.h", "untrusted_personalization_app_ui_config.cc", "untrusted_personalization_app_ui_config.h", ] @@ -46,8 +46,8 @@ source_set("browser_test_support") { testonly = true sources = [ - "test/fake_personalization_app_ui_delegate.cc", - "test/fake_personalization_app_ui_delegate.h", + "test/fake_personalization_app_wallpaper_provider.cc", + "test/fake_personalization_app_wallpaper_provider.h", "test/personalization_app_browsertest_fixture.cc", "test/personalization_app_browsertest_fixture.h", ]
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc index fc3f22f6..46f5336 100644 --- a/ash/webui/personalization_app/personalization_app_ui.cc +++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -7,8 +7,8 @@ #include "ash/constants/ash_features.h" #include "ash/grit/ash_personalization_app_resources.h" #include "ash/grit/ash_personalization_app_resources_map.h" -#include "ash/webui/personalization_app/personalization_app_ui_delegate.h" #include "ash/webui/personalization_app/personalization_app_url_constants.h" +#include "ash/webui/personalization_app/personalization_app_wallpaper_provider.h" #include "base/strings/strcat.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "content/public/browser/web_contents.h" @@ -113,9 +113,10 @@ PersonalizationAppUI::PersonalizationAppUI( content::WebUI* web_ui, - std::unique_ptr<PersonalizationAppUiDelegate> delegate) - : ui::MojoWebUIController(web_ui), delegate_(std::move(delegate)) { - DCHECK(delegate_); + std::unique_ptr<PersonalizationAppWallpaperProvider> wallpaper_provider) + : ui::MojoWebUIController(web_ui), + wallpaper_provider_(std::move(wallpaper_provider)) { + DCHECK(wallpaper_provider_); std::unique_ptr<content::WebUIDataSource> source = base::WrapUnique( content::WebUIDataSource::Create(kChromeUIPersonalizationAppHost)); @@ -149,7 +150,7 @@ void PersonalizationAppUI::BindInterface( mojo::PendingReceiver<personalization_app::mojom::WallpaperProvider> receiver) { - delegate_->BindInterface(std::move(receiver)); + wallpaper_provider_->BindInterface(std::move(receiver)); } WEB_UI_CONTROLLER_TYPE_IMPL(PersonalizationAppUI)
diff --git a/ash/webui/personalization_app/personalization_app_ui.h b/ash/webui/personalization_app/personalization_app_ui.h index 908c087..7ba53dff 100644 --- a/ash/webui/personalization_app/personalization_app_ui.h +++ b/ash/webui/personalization_app/personalization_app_ui.h
@@ -13,12 +13,13 @@ namespace ash { -class PersonalizationAppUiDelegate; +class PersonalizationAppWallpaperProvider; class PersonalizationAppUI : public ui::MojoWebUIController { public: - PersonalizationAppUI(content::WebUI* web_ui, - std::unique_ptr<PersonalizationAppUiDelegate> delegate); + PersonalizationAppUI( + content::WebUI* web_ui, + std::unique_ptr<PersonalizationAppWallpaperProvider> wallpaper_provider); PersonalizationAppUI(const PersonalizationAppUI&) = delete; PersonalizationAppUI& operator=(const PersonalizationAppUI&) = delete; @@ -30,7 +31,7 @@ receiver); private: - std::unique_ptr<PersonalizationAppUiDelegate> delegate_; + std::unique_ptr<PersonalizationAppWallpaperProvider> wallpaper_provider_; WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/ash/webui/personalization_app/personalization_app_url_constants.cc b/ash/webui/personalization_app/personalization_app_url_constants.cc index fec2e23..5eb030e 100644 --- a/ash/webui/personalization_app/personalization_app_url_constants.cc +++ b/ash/webui/personalization_app/personalization_app_url_constants.cc
@@ -8,6 +8,10 @@ const char kChromeUIPersonalizationAppHost[] = "personalization"; const char kChromeUIPersonalizationAppURL[] = "chrome://personalization/"; +const char kChromeUIPersonalizationAppAmbientModeSubpageURL[] = + "chrome://personalization/ambient"; +const char kChromeUIPersonalizationAppUserSubpageURL[] = + "chrome://personalization/user"; const char kChromeUIPersonalizationAppWallpaperSubpageURL[] = "chrome://personalization/wallpaper"; const char kChromeUIUntrustedPersonalizationAppURL[] =
diff --git a/ash/webui/personalization_app/personalization_app_url_constants.h b/ash/webui/personalization_app/personalization_app_url_constants.h index 61b994b..b5ee39e 100644 --- a/ash/webui/personalization_app/personalization_app_url_constants.h +++ b/ash/webui/personalization_app/personalization_app_url_constants.h
@@ -9,6 +9,8 @@ extern const char kChromeUIPersonalizationAppHost[]; extern const char kChromeUIPersonalizationAppURL[]; +extern const char kChromeUIPersonalizationAppAmbientModeSubpageURL[]; +extern const char kChromeUIPersonalizationAppUserSubpageURL[]; extern const char kChromeUIPersonalizationAppWallpaperSubpageURL[]; extern const char kChromeUIUntrustedPersonalizationAppURL[];
diff --git a/ash/webui/personalization_app/personalization_app_ui_delegate.h b/ash/webui/personalization_app/personalization_app_wallpaper_provider.h similarity index 69% rename from ash/webui/personalization_app/personalization_app_ui_delegate.h rename to ash/webui/personalization_app/personalization_app_wallpaper_provider.h index a40c785..2ff179ef 100644 --- a/ash/webui/personalization_app/personalization_app_ui_delegate.h +++ b/ash/webui/personalization_app/personalization_app_wallpaper_provider.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_UI_DELEGATE_H_ -#define ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_UI_DELEGATE_H_ +#ifndef ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ +#define ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -12,7 +12,7 @@ // Handles calling |backdrop_wallpaper_handler| code in //chrome to pass to the // Personalization App SWA. -class PersonalizationAppUiDelegate +class PersonalizationAppWallpaperProvider : public personalization_app::mojom::WallpaperProvider { public: virtual void BindInterface( @@ -22,4 +22,4 @@ } // namespace ash -#endif // ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_UI_DELEGATE_H_ +#endif // ASH_WEBUI_PERSONALIZATION_APP_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn index f529ea59..fa11e78 100644 --- a/ash/webui/personalization_app/resources/BUILD.gn +++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -33,6 +33,7 @@ "trusted/wallpaper/untrusted_message_handler.ts", "trusted/wallpaper/wallpaper_controller.ts", "trusted/wallpaper/wallpaper_interface_provider.ts", + "trusted/wallpaper/wallpaper_observer.ts", "trusted/wallpaper/wallpaper_reducers.ts", "trusted/wallpaper/wallpaper_state.ts", "trusted/wallpaper/wallpaper_subpage.ts", @@ -45,10 +46,12 @@ "common/icons.js", "common/styles.js", + "trusted/ambient/ambient_subpage_element.ts", "trusted/personalization_main_element.ts", "trusted/personalization_router_element.ts", "trusted/personalization_toast_element.ts", "trusted/personalization_breadcrumb_element.ts", + "trusted/user/user_subpage_element.ts", "trusted/wallpaper/google_photos_albums_element.ts", "trusted/wallpaper/google_photos_collection_element.ts", "trusted/wallpaper/google_photos_photos_by_album_id_element.ts", @@ -61,6 +64,7 @@ "trusted/wallpaper/wallpaper_fullscreen_element.ts", "trusted/wallpaper/wallpaper_grid_item_element.ts", "trusted/wallpaper/wallpaper_images_element.ts", + "trusted/wallpaper/wallpaper_preview_element.ts", "trusted/wallpaper/wallpaper_selected_element.ts", "untrusted/collections_grid.ts",
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.html b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.html new file mode 100644 index 0000000..c836502 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.html
@@ -0,0 +1,4 @@ +<style></style> +<div id="container"> + <h2>Ambient</h2> +</div>
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts new file mode 100644 index 0000000..aa34707 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts
@@ -0,0 +1,27 @@ +// 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 The ambient-main component displays the main content of + * the ambient mode settings. + */ + +import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {WithPersonalizationStore} from '../personalization_store.js'; + +export class AmbientSubpage extends WithPersonalizationStore { + static get is() { + return 'ambient-subpage'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return {}; + } +} + +customElements.define(AmbientSubpage.is, AmbientSubpage);
diff --git a/ash/webui/personalization_app/resources/trusted/iframe_api.ts b/ash/webui/personalization_app/resources/trusted/iframe_api.ts index c8decc6..cb04c24 100644 --- a/ash/webui/personalization_app/resources/trusted/iframe_api.ts +++ b/ash/webui/personalization_app/resources/trusted/iframe_api.ts
@@ -107,7 +107,7 @@ * Sends image data keyed by stringified image id. */ export function sendLocalImageData( - target: Window, data: {[key: string]: string}) { + target: Window, data: Record<string, string>) { const event: constants.SendLocalImageDataEvent = { type: constants.EventType.SEND_LOCAL_IMAGE_DATA, data
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_app.ts b/ash/webui/personalization_app/resources/trusted/personalization_app.ts index 9659e54..bda9b01 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_app.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_app.ts
@@ -9,11 +9,13 @@ */ import '/strings.m.js'; +import './ambient/ambient_subpage_element.js'; import './personalization_router_element.js'; import './personalization_test_api.js'; import './personalization_toast_element.js'; import './personalization_breadcrumb_element.js'; import './personalization_main_element.js'; +import './user/user_subpage_element.js'; import './wallpaper/wallpaper_subpage.js'; import {emptyState} from './personalization_state.js'; import {PersonalizationStore} from './personalization_store.js';
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_main_element.html b/ash/webui/personalization_app/resources/trusted/personalization_main_element.html index dcde252..a5102cee 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_main_element.html +++ b/ash/webui/personalization_app/resources/trusted/personalization_main_element.html
@@ -1,4 +1,5 @@ <style></style> <div id="container"> <h1>Personalization</h1> + <wallpaper-preview></wallpaper-preview> </div> \ No newline at end of file
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_router_element.html b/ash/webui/personalization_app/resources/trusted/personalization_router_element.html index eb72253f..521be958 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_router_element.html +++ b/ash/webui/personalization_app/resources/trusted/personalization_router_element.html
@@ -62,6 +62,12 @@ <template is="dom-if" if="[[shouldShowRootPage_(path_)]]"> <personalization-main></personalization-main> </template> + <template is="dom-if" if="[[shouldShowAmbientSubpage_(path_)]]"> + <ambient-subpage></ambient-subpage> + </template> + <template is="dom-if" if="[[shouldShowUserSubpage_(path_)]]"> + <user-subpage></user-subpage> + </template> <template is="dom-if" if="[[shouldShowWallpaperSubpage_(path_)]]"> <div id="wallpaperContainer"> <!-- Prevent left margin from collapsing on narrow window in RTL -->
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_router_element.ts b/ash/webui/personalization_app/resources/trusted/personalization_router_element.ts index ed21737..a6c9110e 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_router_element.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_router_element.ts
@@ -15,6 +15,8 @@ import {WallpaperCollection} from './personalization_app.mojom-webui.js'; export enum Paths { + Ambient = '/ambient', + User = '/user', CollectionImages = '/wallpaper/collection', Collections = '/wallpaper', GooglePhotosCollection = '/wallpaper/google-photos', @@ -141,6 +143,14 @@ path === Paths.Root; } + private shouldShowAmbientSubpage_(path: string|null): boolean { + return !!path?.startsWith(Paths.Ambient); + } + + private shouldShowUserSubpage_(path: string|null): boolean { + return !!path?.startsWith(Paths.User); + } + private shouldShowWallpaperSubpage_(path: string|null): boolean { return !!path?.startsWith(Paths.Collections); }
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_toast_element.html b/ash/webui/personalization_app/resources/trusted/personalization_toast_element.html index 95f1e11..c7ce1b6 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_toast_element.html +++ b/ash/webui/personalization_app/resources/trusted/personalization_toast_element.html
@@ -10,8 +10,8 @@ /* Invert cr-button colors. These are normally dark mode colors. */ cr-button { - --ink-color: var(--google-blue-refresh-300); - --text-color: var(--google-blue-refresh-300); + --ink-color: var(--google-blue-300); + --text-color: var(--google-blue-300); } /* Override some cr-button variables. */
diff --git a/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.html b/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.html new file mode 100644 index 0000000..1c70bf0 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.html
@@ -0,0 +1,4 @@ +<style></style> +<div id="container"> + <h2>User</h2> +</div>
diff --git a/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.ts b/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.ts new file mode 100644 index 0000000..c320c2b --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/user/user_subpage_element.ts
@@ -0,0 +1,27 @@ +// 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 The avatar-main component displays the main content of + * the user info. + */ + +import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {WithPersonalizationStore} from '../personalization_store.js'; + +export class UserSubpage extends WithPersonalizationStore { + static get is() { + return 'user-subpage'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return {}; + } +} + +customElements.define(UserSubpage.is, UserSubpage);
diff --git a/ash/webui/personalization_app/resources/trusted/utils.ts b/ash/webui/personalization_app/resources/trusted/utils.ts index 3bd26ac..16d41568 100644 --- a/ash/webui/personalization_app/resources/trusted/utils.ts +++ b/ash/webui/personalization_app/resources/trusted/utils.ts
@@ -37,3 +37,21 @@ export function isNonEmptyString(maybeString: unknown): maybeString is string { return typeof maybeString === 'string' && maybeString.length > 0; } + +/** + * Wallpaper images sometimes have a resolution suffix appended to the end of + * the image. This is typically to fetch a high resolution image to show as the + * user's wallpaper. We do not want the full resolution here, so remove the + * suffix to get a 512x512 preview. + * TODO(b/186807814) support different resolution parameters here. + */ +export function removeHighResolutionSuffix(url: string): string { + return url.replace(/=w\d+$/, ''); +} + +/** + * Returns whether the given URL starts with http:// or https://. + */ +export function hasHttpScheme(url: string): boolean { + return url.startsWith('http://') || url.startsWith('https://'); +}
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_observer.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_observer.ts new file mode 100644 index 0000000..d923738 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_observer.ts
@@ -0,0 +1,74 @@ +// 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 {CurrentWallpaper, WallpaperObserverInterface, WallpaperObserverReceiver, WallpaperProviderInterface} from '../personalization_app.mojom-webui.js'; +import {PersonalizationStore} from '../personalization_store.js'; + +import {setSelectedImageAction} from './wallpaper_actions.js'; +import {getDailyRefreshCollectionId} from './wallpaper_controller.js'; +import {getWallpaperProvider} from './wallpaper_interface_provider.js'; + +let instance: WallpaperObserver|null = null; +let initialLoadTimeout: number|null = null; +const setTimeout = window.setTimeout; +const clearTimeout = window.clearTimeout; + +/** + * Set up the observer to listen for wallpaper changes. + */ +function initWallpaperObserver( + wallpaperProvider: WallpaperProviderInterface, + target: WallpaperObserverInterface): WallpaperObserverReceiver { + const receiver = new WallpaperObserverReceiver(target); + wallpaperProvider.setWallpaperObserver(receiver.$.bindNewPipeAndPassRemote()); + return receiver; +} + +export class WallpaperObserver implements WallpaperObserverInterface { + /** + * Create a new wallpaper observer instance if no instance currently running. + */ + static initWallpaperObserverIfNeeded(): void { + if (!instance) { + instance = new WallpaperObserver(); + initialLoadTimeout = setTimeout(() => { + const store = PersonalizationStore.getInstance(); + // If still loading the initial currently selected wallpaper image after + // 120 seconds, consider this an error and update the store. + store.dispatch(setSelectedImageAction(null)); + initialLoadTimeout = null; + }, 120 * 1000); + } + } + + receiver_: WallpaperObserverReceiver = + initWallpaperObserver(getWallpaperProvider(), this); + + onWallpaperChanged(currentWallpaper: CurrentWallpaper) { + // Ignore updates while in fullscreen preview mode. The attribution + // information is for the old (non-preview) wallpaper. This is because + // setting an image in preview mode updates the image but not the stored + // WallpaperInfo. The wallpaper app should treat the duration of preview + // mode as loading. Another onWallpaperChanged will fire when preview mode + // is canceled or confirmed. + const store = PersonalizationStore.getInstance(); + if (store.data.wallpaper.fullscreen) { + return; + } + if (initialLoadTimeout) { + clearTimeout(initialLoadTimeout); + initialLoadTimeout = null; + } + store.dispatch(setSelectedImageAction(currentWallpaper)); + // Daily Refresh state should also get updated when wallpaper changes. + getDailyRefreshCollectionId(getWallpaperProvider(), store); + } + + static shutdown() { + if (instance) { + instance.receiver_.$.close(); + instance = null; + } + } +}
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html new file mode 100644 index 0000000..f09f7be --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html
@@ -0,0 +1,23 @@ +<style> + #wallpaperLabel { + background: none; + border: none; + } + + iron-icon { + height: 20px; + width: 20px; + } +</style> +<cr-button id="wallpaperLabel" on-click="onClickWallpaper_"> + <div class="text">[[i18n('title')]]</div> + <iron-icon icon="cr:chevron-right" aria-hidden="true"></iron-icon> +</cr-button> +<template is="dom-if" if="[[showPlaceholders_(isLoading_, showImage_)]]"> + <div id="imagePlaceholder"></div> +</template> +<template is="dom-if" if="[[showImage_]]"> + <div id="imageContainer"> + <img src="[[getImageSrc_(image_)]]" aria-hidden="true"> + </div> +</template>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts new file mode 100644 index 0000000..4a692cae --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts
@@ -0,0 +1,110 @@ +// 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 A polymer component that previews the current selected + * wallpaper. + */ + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; +import '/common/icons.js'; +import './styles.js'; + +import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {CurrentWallpaper, WallpaperProviderInterface} from '../personalization_app.mojom-webui.js'; +import {PersonalizationRouter} from '../personalization_router_element.js'; +import {WithPersonalizationStore} from '../personalization_store.js'; +import {hasHttpScheme, removeHighResolutionSuffix} from '../utils.js'; + +import {getWallpaperProvider} from './wallpaper_interface_provider.js'; + +/** + * @polymer + * @implements WallpaperObserverInterface + */ +export class WallpaperPreview extends WithPersonalizationStore { + static get is() { + return 'wallpaper-preview'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + image_: { + type: Object, + }, + imageLoading_: { + type: Boolean, + }, + showImage_: { + type: Boolean, + computed: 'computeShowImage_(image_, imageLoading_)', + } + }; + } + + private image_: CurrentWallpaper|null; + private imageLoading_: boolean; + private showImage_: boolean; + private wallpaperProvider_: WallpaperProviderInterface; + + constructor() { + super(); + /** @private */ + this.wallpaperProvider_ = getWallpaperProvider(); + } + + /** @override */ + connectedCallback() { + super.connectedCallback(); + this.watch('image_', state => state.wallpaper.currentSelected); + this.watch( + 'imageLoading_', + state => state.wallpaper.loading.setImage > 0 || + state.wallpaper.loading.selected || + state.wallpaper.loading.refreshWallpaper); + this.updateFromStore(); + } + + /** + * Reload at the wallpaper collections page. + */ + onClickWallpaper_() { + PersonalizationRouter.reloadAtWallpaper(); + } + + /** + * Return a chrome://image or data:// url to load the image safely. Returns + * empty string in case |image| is null or invalid. + */ + getImageSrc_(image: CurrentWallpaper|null): string { + if (image && image.url) { + if (hasHttpScheme(image.url.url)) { + return `chrome://image?${removeHighResolutionSuffix(image.url.url)}`; + } + return image.url.url; + } + return ''; + } + + computeShowImage_(image: CurrentWallpaper|null, loading: boolean): boolean { + // Specifically check === false to avoid undefined case while component is + // initializing. + return loading === false && !!image; + } + + /** + * Returns hidden state of loading placeholder. + */ + private showPlaceholders_(loading: boolean, showImage: boolean): boolean { + return loading || !showImage; + } +} +customElements.define(WallpaperPreview.is, WallpaperPreview);
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts index 4f56324..c6f8af7 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts
@@ -17,55 +17,14 @@ import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {isNonEmptyArray} from '../../common/utils.js'; -import {CurrentWallpaper, WallpaperLayout, WallpaperObserverInterface, WallpaperObserverReceiver, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js'; +import {CurrentWallpaper, WallpaperLayout, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js'; import {Paths} from '../personalization_router_element.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {getWallpaperLayoutEnum} from '../utils.js'; +import {getWallpaperLayoutEnum, hasHttpScheme, removeHighResolutionSuffix} from '../utils.js'; -import {beginLoadSelectedImageAction, setSelectedImageAction} from './wallpaper_actions.js'; import {getDailyRefreshCollectionId, setCustomWallpaperLayout, setDailyRefreshCollectionId, updateDailyRefreshWallpaper} from './wallpaper_controller.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; -let setTimeout = window.setTimeout; -let clearTimeout = window.clearTimeout; - -export function mockTimeoutForTesting(mock: { - setTimeout: typeof window.setTimeout, - clearTimeout: typeof window.clearTimeout, -}) { - setTimeout = mock.setTimeout; - clearTimeout = mock.clearTimeout; -} - -/** - * Set up the observer to listen for wallpaper changes. - */ -function initWallpaperObserver( - wallpaperProvider: WallpaperProviderInterface, - target: WallpaperObserverInterface): WallpaperObserverReceiver { - const receiver = new WallpaperObserverReceiver(target); - wallpaperProvider.setWallpaperObserver(receiver.$.bindNewPipeAndPassRemote()); - return receiver; -} - -/** - * Wallpaper images sometimes have a resolution suffix appended to the end of - * the image. This is typically to fetch a high resolution image to show as the - * user's wallpaper. We do not want the full resolution here, so remove the - * suffix to get a 512x512 preview. - * TODO(b/186807814) support different resolution parameters here. - */ -function removeHighResolutionSuffix(url: string): string { - return url.replace(/=w\d+$/, ''); -} - -/** - * Returns whether the given URL starts with http:// or https://. - */ -function hasHttpScheme(url: string): boolean { - return url.startsWith('http://') || url.startsWith('https://'); -} - export class WallpaperSelected extends WithPersonalizationStore { static get is() { return 'wallpaper-selected'; @@ -187,20 +146,14 @@ private showPreviewButton_: boolean; private wallpaperProvider_: WallpaperProviderInterface; - private wallpaperObserver_: WallpaperObserverReceiver|null; - private initialLoadTimeout_: number|null; constructor() { super(); this.wallpaperProvider_ = getWallpaperProvider(); - this.wallpaperObserver_ = null; } connectedCallback() { super.connectedCallback(); - this.dispatch(beginLoadSelectedImageAction()); - this.wallpaperObserver_ = - initWallpaperObserver(this.wallpaperProvider_, this); this.watch('error_', state => state.error); this.watch('image_', state => state.wallpaper.currentSelected); this.watch( @@ -213,49 +166,8 @@ state => state.wallpaper.dailyRefresh.collectionId); this.updateFromStore(); getDailyRefreshCollectionId(this.wallpaperProvider_, this.getStore()); - /** - * Set a 2 minute timer. If no wallpaper information has been received by - * then, dispatch a failure state. - * @type {?number} - */ - this.initialLoadTimeout_ = setTimeout(() => { - // If still loading the initial currently selected wallpaper image after - // 120 seconds, consider this an error and update the store. - this.dispatch(setSelectedImageAction(null)); - this.initialLoadTimeout_ = null; - }, 120 * 1000); } - disconnectedCallback() { - if (this.wallpaperObserver_) { - this.wallpaperObserver_.$.close(); - } - } - - /** - * Called when the wallpaper changes. - */ - onWallpaperChanged(currentWallpaper: CurrentWallpaper|null) { - // Ignore updates while in fullscreen preview mode. The attribution - // information is for the old (non-preview) wallpaper. This is because - // setting an image in preview mode updates the image but not the stored - // WallpaperInfo. The wallpaper app should treat the duration of preview - // mode as loading. Another onWallpaperChanged will fire when preview mode - // is canceled or confirmed. - if (this.getState().wallpaper.fullscreen) { - return; - } - - // Clear the initial load timer if wallpaper information is received. - if (this.initialLoadTimeout_) { - clearTimeout(this.initialLoadTimeout_); - this.initialLoadTimeout_ = null; - } - this.dispatch(setSelectedImageAction(currentWallpaper)); - - // Daily Refresh state should also get updated when wallpaper changes. - getDailyRefreshCollectionId(this.wallpaperProvider_, this.getStore()); - } /** * Return a chrome://image or data:// url to load the image safely. Returns
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage.ts index c7517d43..1ba3a917 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage.ts
@@ -13,9 +13,14 @@ import './wallpaper_error_element.js'; import './wallpaper_fullscreen_element.js'; import './wallpaper_images_element.js'; +import './wallpaper_preview_element.js'; import './wallpaper_selected_element.js'; import './styles.js'; + import {onMessageReceived} from './untrusted_message_handler.js'; +import {WallpaperObserver} from './wallpaper_observer.js'; + +WallpaperObserver.initWallpaperObserverIfNeeded(); window.addEventListener('message', onMessageReceived);
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.cc b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc similarity index 69% rename from ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.cc rename to ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc index f8238c4..9afc5a24 100644 --- a/ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.cc +++ b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.h" +#include "ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h" #include <stdint.h> #include <vector> @@ -20,19 +20,20 @@ const char kFakeCollectionId[] = "fake_collection_id"; } // namespace -FakePersonalizationAppUiDelegate::FakePersonalizationAppUiDelegate( - content::WebUI* web_ui) {} +FakePersonalizationAppWallpaperProvider:: + FakePersonalizationAppWallpaperProvider(content::WebUI* web_ui) {} -FakePersonalizationAppUiDelegate::~FakePersonalizationAppUiDelegate() = default; +FakePersonalizationAppWallpaperProvider:: + ~FakePersonalizationAppWallpaperProvider() = default; -void FakePersonalizationAppUiDelegate::BindInterface( +void FakePersonalizationAppWallpaperProvider::BindInterface( mojo::PendingReceiver<ash::personalization_app::mojom::WallpaperProvider> receiver) { wallpaper_receiver_.reset(); wallpaper_receiver_.Bind(std::move(receiver)); } -void FakePersonalizationAppUiDelegate::FetchCollections( +void FakePersonalizationAppWallpaperProvider::FetchCollections( FetchCollectionsCallback callback) { std::vector<backdrop::Collection> collections; backdrop::Collection collection; @@ -45,7 +46,7 @@ std::move(callback).Run(std::move(collections)); } -void FakePersonalizationAppUiDelegate::FetchImagesForCollection( +void FakePersonalizationAppWallpaperProvider::FetchImagesForCollection( const std::string& collection_id, FetchImagesForCollectionCallback callback) { DCHECK_EQ(collection_id, kFakeCollectionId); @@ -60,34 +61,34 @@ std::move(callback).Run(std::move(images)); } -void FakePersonalizationAppUiDelegate::FetchGooglePhotosCount( +void FakePersonalizationAppWallpaperProvider::FetchGooglePhotosCount( FetchGooglePhotosCountCallback callback) { std::move(callback).Run(0); } -void FakePersonalizationAppUiDelegate::GetLocalImages( +void FakePersonalizationAppWallpaperProvider::GetLocalImages( GetLocalImagesCallback callback) { std::move(callback).Run({}); } -void FakePersonalizationAppUiDelegate::GetLocalImageThumbnail( +void FakePersonalizationAppWallpaperProvider::GetLocalImageThumbnail( const base::FilePath& path, GetLocalImageThumbnailCallback callback) { std::move(callback).Run(std::string()); } -void FakePersonalizationAppUiDelegate::SetWallpaperObserver( +void FakePersonalizationAppWallpaperProvider::SetWallpaperObserver( mojo::PendingRemote<ash::personalization_app::mojom::WallpaperObserver> observer) {} -void FakePersonalizationAppUiDelegate::SelectWallpaper( +void FakePersonalizationAppWallpaperProvider::SelectWallpaper( uint64_t image_asset_id, bool preview_mode, SelectWallpaperCallback callback) { std::move(callback).Run(/*success=*/true); } -void FakePersonalizationAppUiDelegate::SelectLocalImage( +void FakePersonalizationAppWallpaperProvider::SelectLocalImage( const base::FilePath& path, ash::WallpaperLayout layout, bool preview_mode, @@ -95,35 +96,35 @@ std::move(callback).Run(/*success=*/true); } -void FakePersonalizationAppUiDelegate::SetCustomWallpaperLayout( +void FakePersonalizationAppWallpaperProvider::SetCustomWallpaperLayout( ash::WallpaperLayout layout) { return; } -void FakePersonalizationAppUiDelegate::SetDailyRefreshCollectionId( +void FakePersonalizationAppWallpaperProvider::SetDailyRefreshCollectionId( const std::string& collection_id) { return; } -void FakePersonalizationAppUiDelegate::GetDailyRefreshCollectionId( +void FakePersonalizationAppWallpaperProvider::GetDailyRefreshCollectionId( GetDailyRefreshCollectionIdCallback callback) { std::move(callback).Run(kFakeCollectionId); } -void FakePersonalizationAppUiDelegate::UpdateDailyRefreshWallpaper( +void FakePersonalizationAppWallpaperProvider::UpdateDailyRefreshWallpaper( UpdateDailyRefreshWallpaperCallback callback) { std::move(callback).Run(/*success=*/true); } -void FakePersonalizationAppUiDelegate::IsInTabletMode( +void FakePersonalizationAppWallpaperProvider::IsInTabletMode( IsInTabletModeCallback callback) { std::move(callback).Run(/*tablet_mode=*/false); } -void FakePersonalizationAppUiDelegate::ConfirmPreviewWallpaper() { +void FakePersonalizationAppWallpaperProvider::ConfirmPreviewWallpaper() { return; } -void FakePersonalizationAppUiDelegate::CancelPreviewWallpaper() { +void FakePersonalizationAppWallpaperProvider::CancelPreviewWallpaper() { return; }
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.h b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h similarity index 78% rename from ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.h rename to ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h index 45ae178..4786ac1 100644 --- a/ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.h +++ b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_UI_DELEGATE_H_ -#define ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_UI_DELEGATE_H_ +#ifndef ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ +#define ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ -#include "ash/webui/personalization_app/personalization_app_ui_delegate.h" +#include "ash/webui/personalization_app/personalization_app_wallpaper_provider.h" #include <stdint.h> @@ -19,19 +19,19 @@ class WebUI; } // namespace content -class FakePersonalizationAppUiDelegate - : public ash::PersonalizationAppUiDelegate { +class FakePersonalizationAppWallpaperProvider + : public ash::PersonalizationAppWallpaperProvider { public: - explicit FakePersonalizationAppUiDelegate(content::WebUI* web_ui); + explicit FakePersonalizationAppWallpaperProvider(content::WebUI* web_ui); - FakePersonalizationAppUiDelegate(const FakePersonalizationAppUiDelegate&) = - delete; - FakePersonalizationAppUiDelegate& operator=( - const FakePersonalizationAppUiDelegate&) = delete; + FakePersonalizationAppWallpaperProvider( + const FakePersonalizationAppWallpaperProvider&) = delete; + FakePersonalizationAppWallpaperProvider& operator=( + const FakePersonalizationAppWallpaperProvider&) = delete; - ~FakePersonalizationAppUiDelegate() override; + ~FakePersonalizationAppWallpaperProvider() override; - // PersonalizationAppUIDelegate: + // PersonalizationAppWallpaperProvider: void BindInterface( mojo::PendingReceiver<ash::personalization_app::mojom::WallpaperProvider> receiver) override; @@ -85,4 +85,4 @@ wallpaper_receiver_{this}; }; -#endif // ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_UI_DELEGATE_H_ +#endif // ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_
diff --git a/ash/webui/personalization_app/test/personalization_app_browsertest_fixture.cc b/ash/webui/personalization_app/test/personalization_app_browsertest_fixture.cc index 10feb28..0f4dbfc 100644 --- a/ash/webui/personalization_app/test/personalization_app_browsertest_fixture.cc +++ b/ash/webui/personalization_app/test/personalization_app_browsertest_fixture.cc
@@ -8,15 +8,16 @@ #include "ash/webui/personalization_app/personalization_app_ui.h" #include "ash/webui/personalization_app/personalization_app_url_constants.h" -#include "ash/webui/personalization_app/test/fake_personalization_app_ui_delegate.h" +#include "ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h" #include "chrome/test/base/mojo_web_ui_browser_test.h" std::unique_ptr<content::WebUIController> TestPersonalizationAppWebUIProvider::NewWebUI(content::WebUI* web_ui, const GURL& url) { - auto delegate = std::make_unique<FakePersonalizationAppUiDelegate>(web_ui); - return std::make_unique<ash::PersonalizationAppUI>(web_ui, - std::move(delegate)); + auto wallpaper_provider = + std::make_unique<FakePersonalizationAppWallpaperProvider>(web_ui); + return std::make_unique<ash::PersonalizationAppUI>( + web_ui, std::move(wallpaper_provider)); } void PersonalizationAppBrowserTestFixture::SetUpOnMainThread() {
diff --git a/ash/webui/projector_app/resources/communication/message_types.js b/ash/webui/projector_app/resources/communication/message_types.js index f7a65a2..1ff91ec 100644 --- a/ash/webui/projector_app/resources/communication/message_types.js +++ b/ash/webui/projector_app/resources/communication/message_types.js
@@ -52,6 +52,7 @@ * @enum {number} */ export const NewScreencastPreconditionReason = { + SODA_INSTALLATION_ERROR: 0, ON_DEVICE_RECOGNITION_NOT_SUPPORTED: 1, USER_LOCALE_NOT_SUPPORTED: 2, IN_PROJECTOR_SESSION: 3,
diff --git a/ash/webui/scanning/resources/scan_preview.html b/ash/webui/scanning/resources/scan_preview.html index cacbd8f..1b17494 100644 --- a/ash/webui/scanning/resources/scan_preview.html +++ b/ash/webui/scanning/resources/scan_preview.html
@@ -100,7 +100,7 @@ } #cancelingProgressBar { - --paper-progress-active-color: var(--google-grey-refresh-500); + --paper-progress-active-color: var(--google-grey-500); --paper-progress-container-color: var(--google-grey-200); }
diff --git a/ash/webui/scanning/resources/scanning_app.html b/ash/webui/scanning/resources/scanning_app.html index 9d27b487..fe035f5 100644 --- a/ash/webui/scanning/resources/scanning_app.html +++ b/ash/webui/scanning/resources/scanning_app.html
@@ -130,7 +130,7 @@ } #toastInfoIcon { - fill: var(--google-red-refresh-300); + fill: var(--google-red-300); margin-inline-end: 10px; margin-inline-start: -8px; } @@ -146,7 +146,7 @@ } #getHelpLink { - color: var(--google-blue-refresh-300); + color: var(--google-blue-300); text-decoration: none; }
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc index c61903a..f6f79228 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -588,11 +588,26 @@ state_proto_.update_device_info().original_whitelabel_index()); } +void ShimlessRmaService::GetOriginalDramPartNumber( + GetOriginalDramPartNumberCallback callback) { + if (state_proto_.state_case() != rmad::RmadState::kUpdateDeviceInfo) { + // TODO(gavindodd): Consider replacing all invalid call handling with + // mojo::ReportBadMessage("error message"); + LOG(ERROR) << "GetOriginalDramPartNumber called from incorrect state " + << state_proto_.state_case(); + std::move(callback).Run(""); + return; + } + std::move(callback).Run( + state_proto_.update_device_info().original_dram_part_number()); +} + void ShimlessRmaService::SetDeviceInformation( const std::string& serial_number, uint8_t region_index, uint8_t sku_index, uint8_t white_label_index, + const std::string& dram_part_number, SetDeviceInformationCallback callback) { if (state_proto_.state_case() != rmad::RmadState::kUpdateDeviceInfo) { LOG(ERROR) << "SetDeviceInformation called from incorrect state " @@ -607,6 +622,8 @@ state_proto_.mutable_update_device_info()->set_sku_index(sku_index); state_proto_.mutable_update_device_info()->set_whitelabel_index( white_label_index); + state_proto_.mutable_update_device_info()->set_dram_part_number( + dram_part_number); TransitionNextStateGeneric(std::move(callback)); }
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.h b/ash/webui/shimless_rma/backend/shimless_rma_service.h index 890e4ce6..796b8355 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.h +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.h
@@ -98,10 +98,13 @@ void GetOriginalRegion(GetOriginalRegionCallback callback) override; void GetOriginalSku(GetOriginalSkuCallback callback) override; void GetOriginalWhiteLabel(GetOriginalWhiteLabelCallback callback) override; + void GetOriginalDramPartNumber( + GetOriginalDramPartNumberCallback callback) override; void SetDeviceInformation(const std::string& serial_number, uint8_t region_index, uint8_t sku_index, uint8_t white_label_index, + const std::string& dram_part_number, SetDeviceInformationCallback callback) override; void GetCalibrationComponentList(
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc index 0b2005fa..d255e5a 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -1855,6 +1855,58 @@ run_loop.Run(); } +TEST_F(ShimlessRmaServiceTest, GetOriginalDramPartNumber) { + rmad::GetStateReply update_device_info_state = + CreateStateReply(rmad::RmadState::kUpdateDeviceInfo, rmad::RMAD_ERROR_OK); + update_device_info_state.mutable_state() + ->mutable_update_device_info() + ->set_original_dram_part_number("123-456-789"); + update_device_info_state.mutable_state() + ->mutable_update_device_info() + ->set_dram_part_number("987-654-321"); + const std::vector<rmad::GetStateReply> fake_states = { + update_device_info_state, + CreateStateReply(rmad::RmadState::kDeviceDestination, + rmad::RMAD_ERROR_OK)}; + fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); + base::RunLoop run_loop; + shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( + [&](mojom::State state, bool can_cancel, bool can_go_back, + rmad::RmadErrorCode error) { + EXPECT_EQ(state, mojom::State::kUpdateDeviceInformation); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); + })); + run_loop.RunUntilIdle(); + + shimless_rma_provider_->GetOriginalDramPartNumber( + base::BindLambdaForTesting([&](const std::string& part_number) { + EXPECT_EQ(part_number, "123-456-789"); + run_loop.Quit(); + })); + run_loop.Run(); +} + +TEST_F(ShimlessRmaServiceTest, GetOriginalDramPartNumberFromWrongStateEmpty) { + const std::vector<rmad::GetStateReply> fake_states = {CreateStateReply( + rmad::RmadState::kDeviceDestination, rmad::RMAD_ERROR_OK)}; + fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); + base::RunLoop run_loop; + shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( + [&](mojom::State state, bool can_cancel, bool can_go_back, + rmad::RmadErrorCode error) { + EXPECT_EQ(state, mojom::State::kChooseDestination); + EXPECT_EQ(error, rmad::RmadErrorCode::RMAD_ERROR_OK); + })); + run_loop.RunUntilIdle(); + + shimless_rma_provider_->GetOriginalDramPartNumber( + base::BindLambdaForTesting([&](const std::string& part_number) { + EXPECT_EQ(part_number, ""); + run_loop.Quit(); + })); + run_loop.Run(); +} + TEST_F(ShimlessRmaServiceTest, SetDeviceInformation) { const std::vector<rmad::GetStateReply> fake_states = { CreateStateReply(rmad::RmadState::kUpdateDeviceInfo, rmad::RMAD_ERROR_OK), @@ -1868,6 +1920,7 @@ EXPECT_EQ(state.update_device_info().region_index(), 1UL); EXPECT_EQ(state.update_device_info().sku_index(), 2UL); EXPECT_EQ(state.update_device_info().whitelabel_index(), 3UL); + EXPECT_EQ(state.update_device_info().dram_part_number(), "123-456-789"); }); base::RunLoop run_loop; shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting( @@ -1879,7 +1932,7 @@ run_loop.RunUntilIdle(); shimless_rma_provider_->SetDeviceInformation( - "serial number", 1, 2, 3, + "serial number", 1, 2, 3, "123-456-789", base::BindLambdaForTesting([&](mojom::State state, bool can_cancel, bool can_go_back, rmad::RmadErrorCode error) { @@ -1904,7 +1957,7 @@ run_loop.RunUntilIdle(); shimless_rma_provider_->SetDeviceInformation( - "serial number", 1, 2, 3, + "serial number", 1, 2, 3, "123-456-789", base::BindLambdaForTesting([&](mojom::State state, bool can_cancel, bool can_go_back, rmad::RmadErrorCode error) {
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma.mojom b/ash/webui/shimless_rma/mojom/shimless_rma.mojom index ffa9e86..a46ce8d 100644 --- a/ash/webui/shimless_rma/mojom/shimless_rma.mojom +++ b/ash/webui/shimless_rma/mojom/shimless_rma.mojom
@@ -601,11 +601,13 @@ GetOriginalSku() => (uint8 sku_index); // Get the device white-label index at RMA start. GetOriginalWhiteLabel() => (uint8 white_label_index); + // Get the device dram part number at RMA start. + GetOriginalDramPartNumber() => (string dram_part_number); // Attempt to set device info and transition to the next state. // Returns the next state to display and an error code. SetDeviceInformation( string serial_number, uint8 region_index, uint8 sku_index, - uint8 white_label_index) + uint8 white_label_index, string dram_part_number) => (State state, bool can_cancel, bool can_go_back, RmadErrorCode error);
diff --git a/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js b/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js index d7f4e106..0157b94 100644 --- a/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js +++ b/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js
@@ -566,13 +566,30 @@ } /** + * @return {!Promise<!{dramPartNumber: string}>} + */ + getOriginalDramPartNumber() { + return this.methods_.resolveMethod('getOriginalDramPartNumber'); + } + + /** + * @param {string} dramPartNumber + */ + setGetOriginalDramPartNumberResult(dramPartNumber) { + this.methods_.setResult( + 'getOriginalDramPartNumber', {dramPartNumber: dramPartNumber}); + } + + /** * @param {string} serialNumber * @param {number} regionIndex * @param {number} skuIndex * @param {number} whiteLabelIndex + * @param {string} dramPartNumber * @return {!Promise<!StateResult>} */ - setDeviceInformation(serialNumber, regionIndex, skuIndex, whiteLabelIndex) { + setDeviceInformation( + serialNumber, regionIndex, skuIndex, whiteLabelIndex, dramPartNumber) { // TODO(gavindodd): Validate range of region and sku. return this.getNextStateForMethod_( 'setDeviceInformation', State.kUpdateDeviceInformation); @@ -1224,6 +1241,7 @@ this.methods_.register('getOriginalRegion'); this.methods_.register('getOriginalSku'); this.methods_.register('getOriginalWhiteLabel'); + this.methods_.register('getOriginalDramPartNumber'); this.methods_.register('setDeviceInformation'); this.methods_.register('getCalibrationComponentList');
diff --git a/ash/webui/shimless_rma/resources/mojo_interface_provider.js b/ash/webui/shimless_rma/resources/mojo_interface_provider.js index 6790c63..ebce6c3 100644 --- a/ash/webui/shimless_rma/resources/mojo_interface_provider.js +++ b/ash/webui/shimless_rma/resources/mojo_interface_provider.js
@@ -74,6 +74,7 @@ service.setGetOriginalSkuResult(1); service.setGetWhiteLabelListResult(fakeDeviceWhiteLabels); service.setGetOriginalWhiteLabelResult(1); + service.setGetOriginalDramPartNumberResult('dram# 0123'); service.setGetCalibrationSetupInstructionsResult( CalibrationSetupInstruction.kCalibrationInstructionPlaceLidOnFlatSurface);
diff --git a/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.html b/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.html index 5baca3b..073eae7 100644 --- a/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.html +++ b/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.html
@@ -6,7 +6,8 @@ <h1>[[i18n('chooseDestinationTitleText')]]</h1> <cr-radio-group id="chooseDestinationGroup" - on-selected-changed="onDestinationSelectionChanged_"> + on-selected-changed="onDestinationSelectionChanged_" + disabled="[[allButtonsDisabled]]"> <cr-radio-button name="originalOwner" id="destinationOriginalOwner"> [[i18n('sameOwnerText')]] </cr-radio-button>
diff --git a/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.js b/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.js index 61bba8f..3006245b 100644 --- a/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_choose_destination_page.js
@@ -40,6 +40,12 @@ static get properties() { return { + /** + * Set by shimless_rma.js. + * @type {boolean} + */ + allButtonsDisabled: Boolean, + /** @protected */ destinationOwner_: { type: String,
diff --git a/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.html b/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.html index c7a8074..212f7d1 100644 --- a/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.html +++ b/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.html
@@ -5,7 +5,7 @@ <div slot="header"> <h1>[[i18n('chooseWpDisableMethodPageTitleText')]]</h1> <cr-radio-group - id="hwwpDisableMethod" + id="hwwpDisableMethod" disabled="[[allButtonsDisabled]]" on-selected-changed="onHwwpDisableMethodSelectionChanged_"> <cr-radio-button name="hwwpDisableMethodManual"
diff --git a/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.js b/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.js index 27082f1b..1045399 100644 --- a/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_choose_wp_disable_method_page.js
@@ -41,6 +41,12 @@ static get properties() { return { + /** + * Set by shimless_rma.js. + * @type {boolean} + */ + allButtonsDisabled: Boolean, + /** @private */ hwwpMethod_: { type: String,
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html index d08b98a..f6a165ec 100644 --- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html +++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html
@@ -36,7 +36,8 @@ value="{{rsuCode_}}" pattern="[[rsuCodeValidationRegex_]]" invalid="{{rsuCodeInvalid_}}" - auto-validate> + auto-validate + disabled="[[allButtonsDisabled]]"> </cr-input> <div id="inputValidationLabel"> [[i18n('rsuCodeLabelText')]]
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js index 23a0407..a2cbdc66 100644 --- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
@@ -47,6 +47,12 @@ static get properties() { return { + /** + * Set by shimless_rma.js. + * @type {boolean} + */ + allButtonsDisabled: Boolean, + /** @protected */ canvasSize_: { type: Number, @@ -202,9 +208,13 @@ this.i18nAdvanced('rsuCodeInstructionsText', {attrs: ['id']}); const linkElement = this.shadowRoot.querySelector('#rsuCodeDialogLink'); linkElement.setAttribute('href', '#'); - linkElement.addEventListener( - 'click', - () => this.shadowRoot.querySelector('#rsuChallengeDialog').showModal()); + linkElement.addEventListener('click', () => { + if (this.allButtonsDisabled) { + return; + } + + this.shadowRoot.querySelector('#rsuChallengeDialog').showModal(); + }); } /**
diff --git a/ash/webui/shimless_rma/resources/reimaging_device_information_page.html b/ash/webui/shimless_rma/resources/reimaging_device_information_page.html index 76aac589..dddc93a 100644 --- a/ash/webui/shimless_rma/resources/reimaging_device_information_page.html +++ b/ash/webui/shimless_rma/resources/reimaging_device_information_page.html
@@ -45,7 +45,8 @@ </label> <div class="input-holder"> <cr-input id="serialNumber" placeholder="Enter Serial Number" - value="{{serialNumber_}}" aria-labelledby="serialNumberLabel"> + value="{{serialNumber_}}" aria-labelledby="serialNumberLabel" + disabled="[[allButtonsDisabled]]"> </cr-input> <cr-button id="resetSerialNumber" on-click="onResetSerialNumberButtonClicked_" @@ -55,12 +56,32 @@ </div> </div> <div class="input-row"> + <label id="dramPartNumberLabel" class="cr-form-field-label"> + [[i18n('confirmDeviceInfoDramPartNumberLabel')]] + </label> + <div class="input-holder"> + <cr-input + id="dramPartNumber" + placeholder= + "[[i18n('confirmDeviceInfoDramPartNumberPlaceholderLabel')]]" + value="{{dramPartNumber_}}" + aria-labelledby="dramPartNumberLabel"> + </cr-input> + <cr-button id="resetDramPartNumber" + on-click="onResetDramPartNumberButtonClicked_" + disabled="[[disableResetDramPartNumber_]]"> + [[i18n('confirmDeviceInfoResetButtonLabel')]] + </cr-button> + </div> + </div> + <div class="input-row"> <label id="regionLabel" class="cr-form-field-label"> [[i18n('confirmDeviceInfoRegionLabel')]] </label> <div class="input-holder"> <select id="regionSelect" class="md-select" - on-change="onSelectedRegionChange_" aria-labelledby="regionLabel"> + on-change="onSelectedRegionChange_" aria-labelledby="regionLabel" + disabled="[[allButtonsDisabled]]"> <template is="dom-repeat" items="[[regions_]]" as="region"> <option value="[[region]]"> [[region]] @@ -98,7 +119,8 @@ </label> <div class="input-holder"> <select id="skuSelect" class="md-select" - on-change="onSelectedSkuChange_" aria-labelledby="skuLabel"> + on-change="onSelectedSkuChange_" aria-labelledby="skuLabel" + disabled="[[allButtonsDisabled]]"> <template is="dom-repeat" items="[[skus_]]" as="sku"> <option value="[[sku]]"> [[sku]]
diff --git a/ash/webui/shimless_rma/resources/reimaging_device_information_page.js b/ash/webui/shimless_rma/resources/reimaging_device_information_page.js index d89cc44..d5bd4aaf 100644 --- a/ash/webui/shimless_rma/resources/reimaging_device_information_page.js +++ b/ash/webui/shimless_rma/resources/reimaging_device_information_page.js
@@ -39,25 +39,40 @@ return html`{__html_template__}`; } + static get observers() { + return [ + 'updateNextButtonDisabledState_(serialNumber_, skuIndex_, regionIndex_)', + ]; + } + static get properties() { return { + + /** + * Set by shimless_rma.js. + * @type {boolean} + */ + allButtonsDisabled: Boolean, + /** @protected */ disableResetSerialNumber_: { type: Boolean, - computed: - 'getDisableResetSerialNumber_(originalSerialNumber_, serialNumber_)', + computed: 'getDisableResetSerialNumber_(originalSerialNumber_,' + + 'serialNumber_, allButtonsDisabled)', }, /** @protected */ disableResetRegion_: { type: Boolean, - computed: 'getDisableResetRegion_(originalRegionIndex_, regionIndex_)', + computed: 'getDisableResetRegion_(originalRegionIndex_, regionIndex_,' + + 'allButtonsDisabled)', }, /** @protected */ disableResetSku_: { type: Boolean, - computed: 'getDisableResetSku_(originalSkuIndex_, skuIndex_)', + computed: 'getDisableResetSku_(originalSkuIndex_, skuIndex_,' + + 'allButtonsDisabled)', }, /** @protected */ @@ -68,6 +83,13 @@ }, /** @protected */ + disableResetDramPartNumber_: { + type: Boolean, + computed: 'getDisableResetDramPartNumber_(' + + 'originalDramPartNumber_, dramPartNumber_)', + }, + + /** @protected */ originalSerialNumber_: { type: String, value: '', @@ -88,13 +110,13 @@ /** @protected */ originalRegionIndex_: { type: Number, - value: 0, + value: -1, }, /** @protected */ regionIndex_: { type: Number, - value: 0, + value: -1, }, /** @protected {!Array<string>} */ @@ -106,13 +128,13 @@ /** @protected */ originalSkuIndex_: { type: Number, - value: 0, + value: -1, }, /** @protected */ skuIndex_: { type: Number, - value: 0, + value: -1, }, /** @protected {!Array<string>} */ @@ -132,6 +154,18 @@ type: Number, value: 0, }, + + /** @protected */ + originalDramPartNumber_: { + type: String, + value: '', + }, + + /** @protected */ + dramPartNumber_: { + type: String, + value: '', + }, }; } @@ -148,9 +182,21 @@ this.getOriginalRegionAndRegionList_(); this.getOriginalSkuAndSkuList_(); this.getOriginalWhiteLabelAndWhiteLabelList_(); + this.getOriginalDramPartNumber_(); + } + + /** @private */ + allInformationIsValid_() { + return (this.serialNumber_ !== '') && (this.skuIndex_ >= 0) && + (this.regionIndex_ >= 0); + } + + /** @private */ + updateNextButtonDisabledState_() { + const disabled = !this.allInformationIsValid_(); this.dispatchEvent(new CustomEvent( 'disable-next-button', - {bubbles: true, composed: true, detail: false}, + {bubbles: true, composed: true, detail: disabled}, )); } @@ -230,19 +276,29 @@ }); } + /** @private */ + getOriginalDramPartNumber_() { + this.shimlessRmaService_.getOriginalDramPartNumber().then((result) => { + this.originalDramPartNumber_ = result.dramPartNumber; + this.dramPartNumber_ = this.originalDramPartNumber_; + }); + } + /** @protected */ getDisableResetSerialNumber_() { - return this.originalSerialNumber_ === this.serialNumber_; + return this.originalSerialNumber_ === this.serialNumber_ || + this.allButtonsDisabled; } /** @protected */ getDisableResetRegion_() { - return this.originalRegionIndex_ === this.regionIndex_; + return this.originalRegionIndex_ === this.regionIndex_ || + this.allButtonsDisabled; } /** @protected */ getDisableResetSku_() { - return this.originalSkuIndex_ === this.skuIndex_; + return this.originalSkuIndex_ === this.skuIndex_ || this.allButtonsDisabled; } /** @protected */ @@ -251,6 +307,11 @@ } /** @protected */ + getDisableResetDramPartNumber_() { + return this.originalDramPartNumber_ === this.dramPartNumber_; + } + + /** @protected */ onSelectedRegionChange_(event) { this.regionIndex_ = this.shadowRoot.querySelector('#regionSelect').selectedIndex; @@ -292,14 +353,19 @@ this.whiteLabelIndex_; } + /** @protected */ + onResetDramPartNumberButtonClicked_(event) { + this.dramPartNumber_ = this.originalDramPartNumber_; + } + /** @return {!Promise<!StateResult>} */ onNextButtonClick() { - if (this.serialNumber_ === '') { - return Promise.reject(new Error('Serial number not set')); + if (!this.allInformationIsValid_()) { + return Promise.reject(new Error('Some required information is not set')); } else { return this.shimlessRmaService_.setDeviceInformation( this.serialNumber_, this.regionIndex_, this.skuIndex_, - this.whiteLabelIndex_); + this.whiteLabelIndex_, this.dramPartNumber_); } } }
diff --git a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.html b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.html index f581d49f..1bc5762 100644 --- a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.html +++ b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.html
@@ -8,7 +8,8 @@ <div> <cr-button id="retryProvisioningButton" class="cancel-button" on-click="onRetryProvsioningButtonClicked_" - hidden$="[[!shouldShowRetryButton_]]"> + hidden$="[[!shouldShowRetryButton_]]" + disabled="[[allButtonsDisabled]]"> [[i18n('provisioningPageFailedRetryButtonLabel')]] </cr-button> </div>
diff --git a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js index abc9cf2..8c95d2b 100644 --- a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js +++ b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js
@@ -52,6 +52,12 @@ static get properties() { return { + /** + * Set by shimless_rma.js. + * @type {boolean} + */ + allButtonsDisabled: Boolean, + /** @protected {!ProvisioningStatus} */ status_: { type: Object,
diff --git a/ash/webui/shimless_rma/resources/wrapup_finalize_page.html b/ash/webui/shimless_rma/resources/wrapup_finalize_page.html index 34ee41d..be90e75d 100644 --- a/ash/webui/shimless_rma/resources/wrapup_finalize_page.html +++ b/ash/webui/shimless_rma/resources/wrapup_finalize_page.html
@@ -4,12 +4,17 @@ <base-page orientation="column"> <div slot="header"> <h1>[[i18n('finalizePageTitleText')]]</h1> - <p id="finalizationMessage"> - [[finalizationMessage_]] - </p> + <div id="finalizationMessage">[[finalizationMessage_]]</div> + <div> + <cr-button id="retryFinalizationButton" class="cancel-button" + on-click="onRetryFinalizationButtonClicked_" + hidden$="[[!shouldShowRetryButton_]]"> + [[i18n('finalizePageFailedRetryButtonLabel')]] + </cr-button> + </div> </div> <div slot="body"> - <paper-spinner-lite active hidden$="[[finalizationComplete_]]" + <paper-spinner-lite active hidden$="[[shouldShowSpinner_]]" class="large-spinner"> </paper-spinner-lite> </div>
diff --git a/ash/webui/shimless_rma/resources/wrapup_finalize_page.js b/ash/webui/shimless_rma/resources/wrapup_finalize_page.js index f6ea4b9..a17ddd8f 100644 --- a/ash/webui/shimless_rma/resources/wrapup_finalize_page.js +++ b/ash/webui/shimless_rma/resources/wrapup_finalize_page.js
@@ -2,6 +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_elements/cr_button/cr_button.m.js'; import './shimless_rma_shared_css.js'; import './base_page.js'; @@ -49,6 +50,18 @@ type: String, value: '', }, + + /** @protected {boolean} */ + shouldShowSpinner_: { + type: Boolean, + value: false, + }, + + /** @protected {boolean} */ + shouldShowRetryButton_: { + type: Boolean, + value: false, + }, }; } @@ -81,6 +94,10 @@ 'disable-next-button', {bubbles: true, composed: true, detail: !this.finalizationComplete_}, )); + this.shouldShowSpinner_ = status === FinalizationStatus.kInProgress; + this.shouldShowRetryButton_ = + status === FinalizationStatus.kFailedBlocking || + status === FinalizationStatus.kFailedNonBlocking; } /** @return {!Promise<!StateResult>} */ @@ -91,6 +108,25 @@ return Promise.reject(new Error('Finalization is not complete.')); } } + + /** @private */ + onRetryFinalizationButtonClicked_() { + if (!this.shouldShowRetryButton_) { + console.error('Finalization has not failed.'); + return; + } + + this.dispatchEvent(new CustomEvent( + 'transition-state', + { + bubbles: true, + composed: true, + detail: (() => { + return this.shimlessRmaService_.retryFinalization(); + }) + }, + )); + } } customElements.define(WrapupFinalizePage.is, WrapupFinalizePage);
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc index 579630d9..45fd2e0 100644 --- a/ash/webui/shimless_rma/shimless_rma.cc +++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -172,6 +172,8 @@ IDS_SHIMLESS_RMA_FINALIZE_FAILED_BLOCKING}, {"finalizePageFailedNonBlockingText", IDS_SHIMLESS_RMA_FINALIZE_FAILED_NON_BLOCKING}, + {"finalizePageFailedRetryButtonLabel", + IDS_SHIMLESS_RMA_FINALIZE_FAILED_RETRY_BUTTON_LABEL}, // Run calibration page {"runCalibrationTitleText", IDS_SHIMLESS_RMA_RUN_CALIBRATION_PAGE_TITLE}, {"runCalibrationCompleteText", IDS_SHIMLESS_RMA_RUN_CALIBRATION_COMPLETE}, @@ -243,6 +245,10 @@ IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_WHITE_LABEL_LABEL}, {"confirmDeviceInfoEmptyWhiteLabelLabel", IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_EMPTY_WHITE_LABEL_LABEL}, + {"confirmDeviceInfoDramPartNumberLabel", + IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_DRAM_PART_NUMBER_LABEL}, + {"confirmDeviceInfoDramPartNumberPlaceholderLabel", + IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_DRAM_PART_NUMBER_PLACEHOLDER_LABEL}, {"confirmDeviceInfoSkuLabel", IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_SKU_LABEL}, {"confirmDeviceInfoResetButtonLabel",
diff --git a/ash/wm/desks/DEPS b/ash/wm/desks/DEPS index 324fee60..c7649cc6 100644 --- a/ash/wm/desks/DEPS +++ b/ash/wm/desks/DEPS
@@ -1,5 +1,4 @@ include_rules = [ - "+components/favicon_base/favicon_types.h", "+components/favicon_base/favicon_util.h", ]
diff --git a/ash/wm/desks/templates/desks_templates_icon_container.cc b/ash/wm/desks/templates/desks_templates_icon_container.cc index 2e02ee9..a66c56a 100644 --- a/ash/wm/desks/templates/desks_templates_icon_container.cc +++ b/ash/wm/desks/templates/desks_templates_icon_container.cc
@@ -13,6 +13,7 @@ #include "ash/wm/desks/templates/desks_templates_icon_view.h" #include "base/containers/contains.h" #include "components/app_restore/app_launch_info.h" +#include "components/app_restore/app_restore_utils.h" #include "extensions/common/constants.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -101,14 +102,23 @@ if (restore_data.second->urls.has_value() && is_browser) { const auto& urls = restore_data.second->urls.value(); for (int i = 0; i < static_cast<int>(urls.size()); ++i) { - InsertIdentifierInfo(urls[i].spec(), + // Strip extra information from the url so urls with the same host but + // different queries are treated the same. + InsertIdentifierInfo(urls[i].GetWithEmptyPath().spec(), active_tab_index == i ? activation_index : kInactiveTabOffset + activation_index, out_identifier_info); } } else { - InsertIdentifierInfo(app_id, activation_index, out_identifier_info); + // PWAs will have the same app id as chrome. For these apps, retrieve + // their app id from their app name if possible. + std::string new_app_id = app_id; + absl::optional<std::string> app_name = restore_data.second->app_name; + if (app_id == extension_misc::kChromeAppId && app_name.has_value()) + new_app_id = app_restore::GetAppIdFromAppName(app_name.value()); + + InsertIdentifierInfo(new_app_id, activation_index, out_identifier_info); } } }
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.cc b/ash/wm/desks/templates/desks_templates_icon_view.cc index 6154c279..b626c21b 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.cc +++ b/ash/wm/desks/templates/desks_templates_icon_view.cc
@@ -12,7 +12,6 @@ #include "base/bind.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "components/favicon_base/favicon_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/layer.h" @@ -98,14 +97,14 @@ if (!potential_url.is_valid()) { delegate->GetIconForAppId( icon_identifier_, kIconSize, - base::BindOnce(&DesksTemplatesIconView::OnAppIconLoaded, + base::BindOnce(&DesksTemplatesIconView::OnIconLoaded, weak_ptr_factory_.GetWeakPtr())); return; } delegate->GetFaviconForUrl( - icon_identifier_, kIconSize, - base::BindOnce(&DesksTemplatesIconView::OnFaviconLoaded, + icon_identifier_, + base::BindOnce(&DesksTemplatesIconView::OnIconLoaded, weak_ptr_factory_.GetWeakPtr()), &cancelable_task_tracker_); } @@ -131,30 +130,10 @@ } } -void DesksTemplatesIconView::OnFaviconLoaded( - const favicon_base::FaviconRawBitmapResult& image_result) { - if (image_result.is_valid()) { +void DesksTemplatesIconView::OnIconLoaded(const gfx::ImageSkia& icon) { + if (!icon.isNull()) { icon_view_->SetImage(gfx::ImageSkiaOperations::CreateResizedImage( - favicon_base::SelectFaviconFramesFromPNGs( - std::vector<favicon_base::FaviconRawBitmapResult>{image_result}, - favicon_base::GetFaviconScales(), kIconSize) - .AsImageSkia(), - skia::ImageOperations::RESIZE_BEST, gfx::Size(kIconSize, kIconSize))); - return; - } - LoadDefaultIcon(); -} - -void DesksTemplatesIconView::OnAppIconLoaded(apps::IconValuePtr icon_value) { - if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) { - LoadDefaultIcon(); - return; - } - - gfx::ImageSkia image_result = icon_value->uncompressed; - if (!icon_value->is_placeholder_icon && !image_result.isNull()) { - icon_view_->SetImage(gfx::ImageSkiaOperations::CreateResizedImage( - image_result, skia::ImageOperations::RESIZE_BEST, + icon, skia::ImageOperations::RESIZE_BEST, gfx::Size(kIconSize, kIconSize))); return; }
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.h b/ash/wm/desks/templates/desks_templates_icon_view.h index 7fad12da..150857f 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.h +++ b/ash/wm/desks/templates/desks_templates_icon_view.h
@@ -9,11 +9,13 @@ #include "base/memory/weak_ptr.h" #include "base/task/cancelable_task_tracker.h" -#include "components/favicon_base/favicon_types.h" -#include "components/services/app_service/public/cpp/icon_types.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/view.h" +namespace gfx { +class ImageSkia; +} // namespace gfx + namespace views { class Label; } // namespace views @@ -59,9 +61,7 @@ // Callbacks for when the app icon/favicon has been fetched. If the result is // non-null/empty then we'll set this's image to the result. Otherwise, we'll // use a placeholder icon. - void OnFaviconLoaded( - const favicon_base::FaviconRawBitmapResult& image_result); - void OnAppIconLoaded(apps::IconValuePtr icon_value); + void OnIconLoaded(const gfx::ImageSkia& icon); // Loads the default favicon to `icon_view_`. Should be called when we fail to // load an icon.
diff --git a/ash/wm/desks/templates/desks_templates_metrics_util.cc b/ash/wm/desks/templates/desks_templates_metrics_util.cc index 59cabc8..2af2ce4 100644 --- a/ash/wm/desks/templates/desks_templates_metrics_util.cc +++ b/ash/wm/desks/templates/desks_templates_metrics_util.cc
@@ -4,6 +4,10 @@ #include "ash/wm/desks/templates/desks_templates_metrics_util.h" #include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "components/app_restore/restore_data.h" +#include "components/desks_storage/core/desk_model.h" +#include "extensions/common/constants.h" namespace ash { @@ -23,4 +27,51 @@ base::UmaHistogramBoolean(kNewTemplateHistogramName, true); } -} // namespace ash \ No newline at end of file +void RecordAddOrUpdateTemplateStatusHistogram( + desks_storage::DeskModel::AddOrUpdateEntryStatus status) { + base::UmaHistogramEnumeration(kAddOrUpdateTemplateStatusHistogramName, + status); +} + +void RecordUserTemplateCountHistogram(size_t entry_count, + size_t max_entry_count) { + UMA_HISTOGRAM_EXACT_LINEAR(kUserTemplateCountHistogramName, entry_count, + max_entry_count); +} + +void RecordWindowAndTabCountHistogram(DeskTemplate* desk_template) { + const app_restore::RestoreData* restore_data = + desk_template->desk_restore_data(); + DCHECK(restore_data); + + int window_count = 0; + int tab_count = 0; + int total_count = 0; + + const auto& launch_list = restore_data->app_id_to_launch_list(); + for (const auto& iter : launch_list) { + // Since apps aren't guaranteed to have the url field set up correctly, this + // is necessary to ensure things are not double-counted. + if (iter.first != extension_misc::kChromeAppId) { + ++window_count; + ++total_count; + continue; + } + + for (const auto& window_iter : iter.second) { + absl::optional<std::vector<GURL>> urls = window_iter.second->urls; + if (!urls || urls->empty()) + continue; + + ++window_count; + tab_count += urls->size(); + total_count += urls->size(); + } + } + + base::UmaHistogramCounts100(kWindowCountHistogramName, window_count); + base::UmaHistogramCounts100(kTabCountHistogramName, tab_count); + base::UmaHistogramCounts100(kWindowAndTabCountHistogramName, total_count); +} + +} // namespace ash
diff --git a/ash/wm/desks/templates/desks_templates_metrics_util.h b/ash/wm/desks/templates/desks_templates_metrics_util.h index 3c71a2a..b314bdf0 100644 --- a/ash/wm/desks/templates/desks_templates_metrics_util.h +++ b/ash/wm/desks/templates/desks_templates_metrics_util.h
@@ -5,9 +5,12 @@ #ifndef ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_METRICS_UTIL_H_ #define ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_METRICS_UTIL_H_ +#include "ash/public/cpp/desk_template.h" +#include "components/desks_storage/core/desk_model.h" + namespace ash { -// Histogram names +// Histogram names. constexpr char kLoadTemplateGridHistogramName[] = "Ash.DeskTemplate.LoadTemplateGrid"; constexpr char kDeleteTemplateHistogramName[] = @@ -15,13 +18,28 @@ constexpr char kNewTemplateHistogramName[] = "Ash.DeskTemplate.NewTemplate"; constexpr char kLaunchTemplateHistogramName[] = "Ash.DeskTemplate.LaunchFromTemplate"; +constexpr char kAddOrUpdateTemplateStatusHistogramName[] = + "Ash.DeskTemplate.AddOrUpdateTemplateStatus"; +constexpr char kWindowCountHistogramName[] = "Ash.DeskTemplate.WindowCount"; +constexpr char kTabCountHistogramName[] = "Ash.DeskTemplate.TabCount"; +constexpr char kWindowAndTabCountHistogramName[] = + "Ash.DeskTemplate.WindowAndTabCount"; +constexpr char kLaunchFromTemplateHistogramName[] = + "Ash.DeskTemplate.LaunchFromTemplate"; +constexpr char kUserTemplateCountHistogramName[] = + "Ash.DeskTemplate.UserTemplateCount"; // Wrappers calls base::uma with correct histogram name. void RecordLoadTemplateHistogram(); void RecordDeleteTemplateHistogram(); void RecordLaunchTemplateHistogram(); void RecordNewTemplateHistogram(); +void RecordAddOrUpdateTemplateStatusHistogram( + desks_storage::DeskModel::AddOrUpdateEntryStatus status); +void RecordUserTemplateCountHistogram(size_t entry_count, + size_t max_entry_count); +void RecordWindowAndTabCountHistogram(DeskTemplate* desk_template); } // namespace ash -#endif // ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_METRICS_UTIL_H_ \ No newline at end of file +#endif // ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_METRICS_UTIL_H_
diff --git a/ash/wm/desks/templates/desks_templates_presenter.cc b/ash/wm/desks/templates/desks_templates_presenter.cc index 2fddd6c..1aacb2d 100644 --- a/ash/wm/desks/templates/desks_templates_presenter.cc +++ b/ash/wm/desks/templates/desks_templates_presenter.cc
@@ -28,10 +28,6 @@ DesksTemplatesPresenter* g_instance = nullptr; -// The amount of time for which the launch template toasts will remain -// displayed. -constexpr int kLaunchTemplateToastDurationMs = 6 * 1000; - // Toast name. constexpr char kMaximumDeskLaunchTemplateToastName[] = "MaximumDeskLaunchTemplateToast"; @@ -142,9 +138,7 @@ /*text=*/ l10n_util::GetStringFUTF16( IDS_ASH_DESKS_TEMPLATES_REACH_MAXIMUM_DESK_TOAST, - base::FormatNumber(desks_util::kMaxNumberOfDesks)), - kLaunchTemplateToastDurationMs, - /*dismiss_text=*/absl::nullopt}; + base::FormatNumber(desks_util::kMaxNumberOfDesks))}; ToastManager::Get()->Show(toast_data); return; } @@ -174,6 +168,9 @@ weak_ptr_factory_.InvalidateWeakPtrs(); + if (!is_update) + RecordWindowAndTabCountHistogram(desk_template.get()); + // Save or update `desk_template_clone` as an entry in DeskModel. GetDeskModel()->AddOrUpdateEntry( std::move(desk_template_clone), @@ -227,6 +224,7 @@ return; RecordDeleteTemplateHistogram(); + RecordUserTemplateCountHistogram(GetEntryCount(), GetMaxEntryCount()); GetAllEntries(); } @@ -255,6 +253,10 @@ void DesksTemplatesPresenter::OnAddOrUpdateEntry( bool was_update, desks_storage::DeskModel::AddOrUpdateEntryStatus status) { + // TODO(crbug.com/1284449): Add visible cue when failing to save a desk + // template. + RecordAddOrUpdateTemplateStatusHistogram(status); + if (status != desks_storage::DeskModel::AddOrUpdateEntryStatus::kOk) return; @@ -272,8 +274,10 @@ for (auto& overview_grid : grid_list) overview_grid->UpdateSaveDeskAsTemplateButton(); - if (!was_update) + if (!was_update) { RecordNewTemplateHistogram(); + RecordUserTemplateCountHistogram(GetEntryCount(), GetMaxEntryCount()); + } } } // namespace ash
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc index 25cfd89d..6778b023 100644 --- a/ash/wm/desks/templates/desks_templates_unittest.cc +++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -1807,6 +1807,10 @@ constexpr int kExpectedNewTemplates = 1; histogram_tester.ExpectTotalCount(kNewTemplateHistogramName, kExpectedNewTemplates); + histogram_tester.ExpectBucketCount( + kAddOrUpdateTemplateStatusHistogramName, + static_cast<int>(desks_storage::DeskModel::AddOrUpdateEntryStatus::kOk), + kExpectedNewTemplates); } // Tests to verify that clicking the spacebar doesn't cause the name view to @@ -1935,4 +1939,104 @@ } } +TEST_F(DesksTemplatesTest, UserTemplateCountRecordsCorrectly) { + // Record histogram. + base::HistogramTester histogram_tester; + + // Create three new templates through the UI. + for (unsigned long num_templates = 0; num_templates < 3; ++num_templates) { + // There are no saved template entries and one test window initially. + auto test_window = CreateAppWindow(); + + // Toggle overview if there isn't currently an overview. This is needed + // to save a template via the UI. + if (!GetOverviewSession()) { + ToggleOverview(); + WaitForDesksTemplatesUI(); + } + + // The `save_desk_as_template_widget` is visible when at least one window is + // open. + views::Widget* save_desk_as_template_widget = + GetSaveDeskAsTemplateButtonForRoot(Shell::GetPrimaryRootWindow()); + ASSERT_TRUE(save_desk_as_template_widget); + EXPECT_TRUE(save_desk_as_template_widget->GetContentsView()->GetVisible()); + + // Click on `save_desk_as_template_widget` button. + ClickOnView(save_desk_as_template_widget->GetContentsView()); + ASSERT_EQ(num_templates + 1, GetAllEntries().size()); + + // Expect that the Desk Templates grid is visible. + EXPECT_TRUE(GetOverviewGridList()[0]->IsShowingDesksTemplatesGrid()); + } + + OpenOverviewAndShowTemplatesGrid(); + + // Delete one of the templates which will iterate the histogram's second + // bucket. + DeleteTemplate(GetAllEntries()[0]->uuid(), /*expected_item_count=*/3); + + histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 1, 1); + histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 2, 2); + histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 3, 1); +} + +// Tests that the window and tab counts are properly recorded in their +// resepctive metrics. +TEST_F(DesksTemplatesTest, SaveDeskRecordsWindowAndTabCountMetrics) { + const std::string kAppId1 = extension_misc::kChromeAppId; + constexpr int kWindowId1 = 1; + constexpr int kActiveTabIndex1 = 1; + const std::vector<GURL> kTabs1{GURL("http://a.com"), GURL("http://b.com"), + GURL("http://c.com")}; + + const std::string kAppId2 = extension_misc::kChromeAppId; + constexpr int kWindowId2 = 2; + constexpr int kActiveTabIndex2 = 2; + const std::vector<GURL> kTabs2{GURL("http://d.com"), GURL("http://e.com"), + GURL("http://f.com")}; + + // Create `restore_data` for the template. + auto restore_data = std::make_unique<app_restore::RestoreData>(); + + // Add app launch info for the first browser instance. + auto app_launch_info_1 = + std::make_unique<app_restore::AppLaunchInfo>(kAppId1, kWindowId1); + app_launch_info_1->active_tab_index = kActiveTabIndex1; + app_launch_info_1->urls = absl::make_optional(kTabs1); + restore_data->AddAppLaunchInfo(std::move(app_launch_info_1)); + app_restore::WindowInfo window_info_1; + window_info_1.activation_index = absl::make_optional<int32_t>(kWindowId1); + restore_data->ModifyWindowInfo(kAppId1, kWindowId1, window_info_1); + + // Add app launch info for the second browser instance. + auto app_launch_info_2 = + std::make_unique<app_restore::AppLaunchInfo>(kAppId2, kWindowId2); + app_launch_info_2->active_tab_index = kActiveTabIndex2; + app_launch_info_2->urls = absl::make_optional(kTabs2); + restore_data->AddAppLaunchInfo(std::move(app_launch_info_2)); + app_restore::WindowInfo window_info_2; + window_info_2.activation_index = absl::make_optional<int32_t>(kWindowId2); + restore_data->ModifyWindowInfo(kAppId2, kWindowId2, window_info_2); + + auto desk_template = std::make_unique<DeskTemplate>( + base::GUID::GenerateRandomV4().AsLowercaseString(), + DeskTemplateSource::kUser, "template_1", base::Time::Now()); + desk_template->set_desk_restore_data(std::move(restore_data)); + + // Record histogram. + base::HistogramTester histogram_tester; + + ToggleOverview(); + WaitForDesksTemplatesUI(); + + // Mocks saving templates with some browsers. + DesksTemplatesPresenter::Get()->SaveOrUpdateDeskTemplate( + /*is_update=*/false, std::move(desk_template)); + + histogram_tester.ExpectBucketCount(kWindowCountHistogramName, 2, 1); + histogram_tester.ExpectBucketCount(kTabCountHistogramName, 6, 1); + histogram_tester.ExpectBucketCount(kWindowAndTabCountHistogramName, 6, 1); +} + } // namespace ash
diff --git a/ash/wm/gestures/wm_gesture_handler.cc b/ash/wm/gestures/wm_gesture_handler.cc index 58ac36d..e726520 100644 --- a/ash/wm/gestures/wm_gesture_handler.cc +++ b/ash/wm/gestures/wm_gesture_handler.cc
@@ -37,8 +37,6 @@ constexpr char kSwitchNextDeskToastId[] = "ash.wm.reverse_next_desk_toast"; constexpr char kSwitchLastDeskToastId[] = "ash.wm.reverse_last_desk_toast"; -constexpr base::TimeDelta kToastDurationMs = base::Milliseconds(2500); - // Check if the user used the wrong gestures. bool g_did_wrong_enter_overview_gesture = false; bool g_did_wrong_exit_overview_gesture = false; @@ -65,8 +63,7 @@ void ShowReverseGestureToast(const char* toast_id, int message_id) { Shell::Get()->toast_manager()->Show( - ToastData(toast_id, l10n_util::GetStringUTF16(message_id), - kToastDurationMs.InMilliseconds(), absl::nullopt)); + ToastData(toast_id, l10n_util::GetStringUTF16(message_id))); } // When reverse scrolling for touchpad is Off, if the user performs wrong
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 6810c4c..470ef93 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -134,7 +134,6 @@ // that is visible on all desks to another desk. constexpr char kMoveVisibleOnAllDesksWindowToastId[] = "ash.wm.overview.move_visible_on_all_desks_window_toast"; -constexpr int kToastDurationMs = 2500; // Histogram names for overview enter/exit smoothness in clamshell, // tablet mode and splitview. @@ -1428,10 +1427,10 @@ if (dragged_window_is_visible_on_all_desks) { // Show toast since items that are visible on all desks should not be able // to be unassigned during overview. - Shell::Get()->toast_manager()->Show(ToastData( - kMoveVisibleOnAllDesksWindowToastId, - l10n_util::GetStringUTF16(IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST), - kToastDurationMs, absl::nullopt)); + Shell::Get()->toast_manager()->Show( + ToastData(kMoveVisibleOnAllDesksWindowToastId, + l10n_util::GetStringUTF16( + IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST))); return false; }
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index f85d611f..1dcdb7ee 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -337,6 +337,10 @@ // `was_zero_state` is true then we will expand the desks bar. void ShowDesksTemplatesGrid(bool was_zero_state); + // Hides the overview mode items that must be closed for the grid of desks + // templates to show. + void HideForDesksTemplatesGrid(); + // Hides the grid of desks templates and reshow the overview items. Updates // the templates button if we are not exiting overview. void HideDesksTemplatesGrid(bool exit_overview);
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 57f072b6..229fd78 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -216,11 +216,11 @@ GetWindow()->SetProperty(kForceVisibleInMiniViewKey, true); DCHECK(item_widget_); - item_widget_->GetLayer()->SetOpacity(0.0f); + PerformFadeOutLayer(item_widget_->GetLayer()); - for (aura::Window* transient_child : GetTransientTreeIterator(GetWindow())) { - transient_child->SetProperty(kForceVisibleInMiniViewKey, true); - transient_child->layer()->SetOpacity(0.0f); + for (aura::Window* transient_child : + GetTransientTreeIterator(transform_window_.window())) { + PerformFadeOutLayer(transient_child->layer()); } item_widget_event_blocker_ =
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index 7ebefa0c7..6ac0677 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -50,7 +50,6 @@ // Toast data. constexpr char kAppCannotSnapToastId[] = "split_view_app_cannot_snap"; -constexpr int kAppCannotSnapToastDurationMs = 2500; // Gets the duration, tween type and delay before animation based on |type|. void GetAnimationValuesForType( @@ -399,10 +398,9 @@ } void ShowAppCannotSnapToast() { - Shell::Get()->toast_manager()->Show(ToastData( - kAppCannotSnapToastId, - l10n_util::GetStringUTF16(IDS_ASH_SPLIT_VIEW_CANNOT_SNAP), - kAppCannotSnapToastDurationMs, absl::optional<std::u16string>())); + Shell::Get()->toast_manager()->Show( + ToastData(kAppCannotSnapToastId, + l10n_util::GetStringUTF16(IDS_ASH_SPLIT_VIEW_CANNOT_SNAP))); } SplitViewController::SnapPosition GetSnapPositionForLocation(
diff --git a/ash/wm/window_cycle/window_cycle_controller.cc b/ash/wm/window_cycle/window_cycle_controller.cc index f7331b2..282e7080 100644 --- a/ash/wm/window_cycle/window_cycle_controller.cc +++ b/ash/wm/window_cycle/window_cycle_controller.cc
@@ -136,8 +136,11 @@ void WindowCycleController::HandleKeyboardNavigation( KeyboardNavDirection direction) { - if (!CanCycle() || !IsCycling() || !IsValidKeyboardNavigation(direction)) + // If the UI is not shown yet, discard the event. + if (!CanCycle() || !IsCycling() || !window_cycle_list_->cycle_view() || + !IsValidKeyboardNavigation(direction)) { return; + } switch (direction) { // Pressing the Up arrow key moves the focus from the window cycle list
diff --git a/ash/wm/window_cycle/window_cycle_controller_unittest.cc b/ash/wm/window_cycle/window_cycle_controller_unittest.cc index 03a56360..4539597 100644 --- a/ash/wm/window_cycle/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle/window_cycle_controller_unittest.cc
@@ -210,7 +210,7 @@ void SetUp() override { AshTestBase::SetUp(); - WindowCycleList::DisableInitialDelayForTesting(); + WindowCycleList::SetDisableInitialDelayForTesting(true); shelf_view_test_ = std::make_unique<ShelfViewTestAPI>( GetPrimaryShelf()->GetShelfViewForTesting()); @@ -1737,6 +1737,32 @@ EXPECT_FALSE(controller->IsCycling()); } +// Tests that pressing arrow key before cycle view UI is ready doesn't lead to a +// crash. Regression test for https://crbug.com/1246251. +TEST_F(WindowCycleControllerTest, ArrowKeyBeforeCycleViewUI) { + auto* desks_controller = DesksController::Get(); + desks_controller->NewDesk(DesksCreationRemovalSource::kButton); + std::unique_ptr<Window> w0(CreateTestWindowInShellWithId(0)); + std::unique_ptr<Window> w1(CreateTestWindowInShellWithId(1)); + WindowCycleController* controller = Shell::Get()->window_cycle_controller(); + + // Enable initial delay for testing so that once it starts cycling, the cycle + // view UI will not be shown right away. + WindowCycleList::SetDisableInitialDelayForTesting(false); + controller->StartCycling(); + EXPECT_TRUE(controller->IsCycling()); + EXPECT_FALSE(CycleViewExists()); + controller->HandleKeyboardNavigation( + WindowCycleController::KeyboardNavDirection::kUp); + controller->HandleKeyboardNavigation( + WindowCycleController::KeyboardNavDirection::kDown); + controller->HandleKeyboardNavigation( + WindowCycleController::KeyboardNavDirection::kLeft); + controller->HandleKeyboardNavigation( + WindowCycleController::KeyboardNavDirection::kRight); + CompleteCycling(controller); +} + class ReverseGestureWindowCycleControllerTest : public WindowCycleControllerTest { public: @@ -3037,7 +3063,7 @@ void SetUp() override { NoSessionAshTestBase::SetUp(); - WindowCycleList::DisableInitialDelayForTesting(); + WindowCycleList::SetDisableInitialDelayForTesting(true); shelf_view_test_ = std::make_unique<ShelfViewTestAPI>( GetPrimaryShelf()->GetShelfViewForTesting()); shelf_view_test_->SetAnimationDuration(base::Milliseconds(1));
diff --git a/ash/wm/window_cycle/window_cycle_list.cc b/ash/wm/window_cycle/window_cycle_list.cc index af20eb4a..3ff161d 100644 --- a/ash/wm/window_cycle/window_cycle_list.cc +++ b/ash/wm/window_cycle/window_cycle_list.cc
@@ -266,8 +266,8 @@ } // static -void WindowCycleList::DisableInitialDelayForTesting() { - g_disable_initial_delay = true; +void WindowCycleList::SetDisableInitialDelayForTesting(bool disabled) { + g_disable_initial_delay = disabled; } void WindowCycleList::OnWindowDestroying(aura::Window* window) {
diff --git a/ash/wm/window_cycle/window_cycle_list.h b/ash/wm/window_cycle/window_cycle_list.h index 14f0736..17129b50 100644 --- a/ash/wm/window_cycle/window_cycle_list.h +++ b/ash/wm/window_cycle/window_cycle_list.h
@@ -42,6 +42,8 @@ WindowCycleList& operator=(const WindowCycleList&) = delete; ~WindowCycleList() override; + const WindowCycleView* cycle_view() const { return cycle_view_; } + // Returns the |target_window_| from |cycle_view_|. aura::Window* GetTargetWindow(); @@ -98,14 +100,14 @@ user_did_accept_ = user_did_accept; } + static void SetDisableInitialDelayForTesting(bool disabled); + private: friend class ModeSelectionWindowCycleControllerTest; friend class MultiUserWindowCycleControllerTest; friend class WindowCycleListTestApi; friend class WindowCycleControllerTest; - static void DisableInitialDelayForTesting(); - // aura::WindowObserver: // There is a chance a window is destroyed, for example by JS code. We need to // take care of that even if it is not intended for the user to close a window
diff --git a/base/BUILD.gn b/base/BUILD.gn index 0e3a8ef..64ea2b1 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -417,6 +417,7 @@ "memory/unsafe_shared_memory_pool.h", "memory/unsafe_shared_memory_region.cc", "memory/unsafe_shared_memory_region.h", + "memory/values_equivalent.h", "memory/weak_ptr.cc", "memory/weak_ptr.h", "memory/writable_shared_memory_region.cc", @@ -3115,6 +3116,7 @@ "memory/shared_memory_region_unittest.cc", "memory/singleton_unittest.cc", "memory/unsafe_shared_memory_pool_unittest.cc", + "memory/values_equivalent_unittest.cc", "memory/weak_ptr_unittest.cc", "message_loop/message_pump_glib_unittest.cc", "message_loop/message_pump_unittest.cc",
diff --git a/base/allocator/partition_allocator/address_pool_manager.cc b/base/allocator/partition_allocator/address_pool_manager.cc index a503995..82f9d6c4 100644 --- a/base/allocator/partition_allocator/address_pool_manager.cc +++ b/base/allocator/partition_allocator/address_pool_manager.cc
@@ -42,11 +42,11 @@ namespace { // This will crash if the range cannot be decommitted. -void DecommitPages(void* address, size_t size) { +void DecommitPages(uintptr_t address, size_t size) { // Callers rely on the pages being zero-initialized when recommitting them. // |DecommitSystemPages| doesn't guarantee this on all operating systems, in // particular on macOS, but |DecommitAndZeroSystemPages| does. - DecommitAndZeroSystemPages(address, size); + DecommitAndZeroSystemPages(reinterpret_cast<void*>(address), size); } } // namespace @@ -94,27 +94,26 @@ pool->Reset(); } -char* AddressPoolManager::Reserve(pool_handle handle, - void* requested_address, - size_t length) { +uintptr_t AddressPoolManager::Reserve(pool_handle handle, + uintptr_t requested_address, + size_t length) { Pool* pool = GetPool(handle); if (!requested_address) - return reinterpret_cast<char*>(pool->FindChunk(length)); - const bool is_available = pool->TryReserveChunk( - reinterpret_cast<uintptr_t>(requested_address), length); + return pool->FindChunk(length); + const bool is_available = pool->TryReserveChunk(requested_address, length); if (is_available) - return static_cast<char*>(requested_address); - return reinterpret_cast<char*>(pool->FindChunk(length)); + return requested_address; + return pool->FindChunk(length); } void AddressPoolManager::UnreserveAndDecommit(pool_handle handle, - void* ptr, + uintptr_t address, size_t length) { PA_DCHECK(0 < handle && handle <= kNumPools); Pool* pool = GetPool(handle); PA_DCHECK(pool->IsInitialized()); - DecommitPages(ptr, length); - pool->FreeChunk(reinterpret_cast<uintptr_t>(ptr), length); + DecommitPages(address, length); + pool->FreeChunk(address, length); } void AddressPoolManager::Pool::Initialize(uintptr_t ptr, size_t length) { @@ -298,25 +297,22 @@ } } -char* AddressPoolManager::Reserve(pool_handle handle, - void* requested_address, - size_t length) { +uintptr_t AddressPoolManager::Reserve(pool_handle handle, + uintptr_t requested_address, + size_t length) { PA_DCHECK(!(length & DirectMapAllocationGranularityOffsetMask())); - char* ptr = reinterpret_cast<char*>( - AllocPages(requested_address, length, kSuperPageSize, PageInaccessible, - PageTag::kPartitionAlloc)); - if (UNLIKELY(!ptr)) - return nullptr; - return ptr; + uintptr_t address = reinterpret_cast<uintptr_t>( + AllocPages(reinterpret_cast<void*>(requested_address), length, + kSuperPageSize, PageInaccessible, PageTag::kPartitionAlloc)); + return address; } void AddressPoolManager::UnreserveAndDecommit(pool_handle handle, - void* ptr, + uintptr_t address, size_t length) { - uintptr_t ptr_as_uintptr = reinterpret_cast<uintptr_t>(ptr); - PA_DCHECK(!(ptr_as_uintptr & kSuperPageOffsetMask)); + PA_DCHECK(!(address & kSuperPageOffsetMask)); PA_DCHECK(!(length & DirectMapAllocationGranularityOffsetMask())); - FreePages(ptr, length); + FreePages(reinterpret_cast<void*>(address), length); } void AddressPoolManager::MarkUsed(pool_handle handle,
diff --git a/base/allocator/partition_allocator/address_pool_manager.h b/base/allocator/partition_allocator/address_pool_manager.h index af6060c..7ddb9bb 100644 --- a/base/allocator/partition_allocator/address_pool_manager.h +++ b/base/allocator/partition_allocator/address_pool_manager.h
@@ -60,11 +60,14 @@ #endif // Reserves address space from GigaCage. - char* Reserve(pool_handle handle, void* requested_address, size_t length); + uintptr_t Reserve(pool_handle handle, + uintptr_t requested_address, + size_t length); // Frees address space back to GigaCage and decommits underlying system pages. - // TODO(bartekn): void* -> uintptr_t - void UnreserveAndDecommit(pool_handle handle, void* ptr, size_t length); + void UnreserveAndDecommit(pool_handle handle, + uintptr_t address, + size_t length); void ResetForTesting(); #if !defined(PA_HAS_64_BITS_POINTERS)
diff --git a/base/allocator/partition_allocator/address_pool_manager_bitmap.h b/base/allocator/partition_allocator/address_pool_manager_bitmap.h index 7b18db11..66af4c12 100644 --- a/base/allocator/partition_allocator/address_pool_manager_bitmap.h +++ b/base/allocator/partition_allocator/address_pool_manager_bitmap.h
@@ -125,9 +125,7 @@ #endif // BUILDFLAG(NEVER_REMOVE_FROM_BRP_POOL_BLOCKLIST) } - static bool IsAllowedSuperPageForBRPPool(const void* address) { - uintptr_t address_as_uintptr = reinterpret_cast<uintptr_t>(address); - + static bool IsAllowedSuperPageForBRPPool(uintptr_t address) { // The only potentially dangerous scenario, in which this check is used, is // when the assignment of the first raw_ptr<T> object for a non-GigaCage // address is racing with the allocation of a new GigCage super-page at the @@ -141,10 +139,10 @@ // Since we rely on that external synchronization, the relaxed memory // ordering should be sufficient. #if BUILDFLAG(NEVER_REMOVE_FROM_BRP_POOL_BLOCKLIST) - return !brp_forbidden_super_page_map_[address_as_uintptr >> kSuperPageShift] - .load(std::memory_order_relaxed); + return !brp_forbidden_super_page_map_[address >> kSuperPageShift].load( + std::memory_order_relaxed); #else - return super_page_refcount_map_[address_as_uintptr >> kSuperPageShift].load( + return super_page_refcount_map_[address >> kSuperPageShift].load( std::memory_order_relaxed) == 0; #endif // BUILDFLAG(NEVER_REMOVE_FROM_BRP_POOL_BLOCKLIST) }
diff --git a/base/allocator/partition_allocator/address_pool_manager_unittest.cc b/base/allocator/partition_allocator/address_pool_manager_unittest.cc index 3f93726b..1336e27 100644 --- a/base/allocator/partition_allocator/address_pool_manager_unittest.cc +++ b/base/allocator/partition_allocator/address_pool_manager_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/allocator/partition_allocator/address_pool_manager.h" +#include <cstdint> #include "base/allocator/partition_allocator/page_allocator.h" #include "base/allocator/partition_allocator/page_allocator_internal.h" @@ -29,17 +30,16 @@ void SetUp() override { manager_ = std::make_unique<AddressPoolManagerForTesting>(); - base_address_ = - AllocPages(nullptr, kPoolSize, kSuperPageSize, base::PageInaccessible, - PageTag::kPartitionAlloc); + base_ptr_ = AllocPages(nullptr, kPoolSize, kSuperPageSize, + base::PageInaccessible, PageTag::kPartitionAlloc); + base_address_ = reinterpret_cast<uintptr_t>(base_ptr_); ASSERT_TRUE(base_address_); - pool_ = - manager_->Add(reinterpret_cast<uintptr_t>(base_address_), kPoolSize); + pool_ = manager_->Add(base_address_, kPoolSize); } void TearDown() override { manager_->Remove(pool_); - FreePages(base_address_, kPoolSize); + FreePages(base_ptr_, kPoolSize); manager_.reset(); } @@ -49,7 +49,8 @@ static constexpr size_t kPoolSize = kSuperPageSize * kPageCnt; std::unique_ptr<AddressPoolManagerForTesting> manager_; - void* base_address_; + void* base_ptr_; + uintptr_t base_address_; pool_handle pool_; }; @@ -61,64 +62,53 @@ } TEST_F(PartitionAllocAddressPoolManagerTest, ManyPages) { - char* base_ptr = reinterpret_cast<char*>(base_address_); - - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, - kPageCnt * kSuperPageSize), - base_ptr); - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize), - nullptr); - GetAddressPoolManager()->UnreserveAndDecommit(pool_, base_ptr, + EXPECT_EQ( + GetAddressPoolManager()->Reserve(pool_, 0, kPageCnt * kSuperPageSize), + base_address_); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize), 0u); + GetAddressPoolManager()->UnreserveAndDecommit(pool_, base_address_, kPageCnt * kSuperPageSize); - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, - kPageCnt * kSuperPageSize), - base_ptr); - GetAddressPoolManager()->UnreserveAndDecommit(pool_, base_ptr, + EXPECT_EQ( + GetAddressPoolManager()->Reserve(pool_, 0, kPageCnt * kSuperPageSize), + base_address_); + GetAddressPoolManager()->UnreserveAndDecommit(pool_, base_address_, kPageCnt * kSuperPageSize); } TEST_F(PartitionAllocAddressPoolManagerTest, PagesFragmented) { - char* base_ptr = reinterpret_cast<char*>(base_address_); - void* addrs[kPageCnt]; + uintptr_t addrs[kPageCnt]; for (size_t i = 0; i < kPageCnt; ++i) { - addrs[i] = GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize); + addrs[i] = GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + EXPECT_EQ(addrs[i], base_address_ + i * kSuperPageSize); } - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize), - nullptr); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize), 0u); // Free other other super page, so that we have plenty of free space, but none // of the empty spaces can fit 2 super pages. for (size_t i = 1; i < kPageCnt; i += 2) { GetAddressPoolManager()->UnreserveAndDecommit(pool_, addrs[i], kSuperPageSize); } - EXPECT_EQ( - GetAddressPoolManager()->Reserve(pool_, nullptr, 2 * kSuperPageSize), - nullptr); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, 2 * kSuperPageSize), 0u); // Reserve freed super pages back, so that there are no free ones. for (size_t i = 1; i < kPageCnt; i += 2) { - addrs[i] = GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize); + addrs[i] = GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + EXPECT_EQ(addrs[i], base_address_ + i * kSuperPageSize); } - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize), - nullptr); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize), 0u); // Lastly, clean up. - for (size_t i = 0; i < kPageCnt; ++i) { - GetAddressPoolManager()->UnreserveAndDecommit(pool_, addrs[i], - kSuperPageSize); + for (uintptr_t addr : addrs) { + GetAddressPoolManager()->UnreserveAndDecommit(pool_, addr, kSuperPageSize); } } TEST_F(PartitionAllocAddressPoolManagerTest, GetUsedSuperpages) { - char* base_ptr = reinterpret_cast<char*>(base_address_); - void* addrs[kPageCnt]; + uintptr_t addrs[kPageCnt]; for (size_t i = 0; i < kPageCnt; ++i) { - addrs[i] = GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize); + addrs[i] = GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + EXPECT_EQ(addrs[i], base_address_ + i * kSuperPageSize); } - EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize), - nullptr); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize), 0u); std::bitset<base::kMaxSuperPagesInPool> used_super_pages; GetAddressPoolManager()->GetPoolUsedSuperPages(pool_, used_super_pages); @@ -135,9 +125,7 @@ kSuperPageSize); } - EXPECT_EQ( - GetAddressPoolManager()->Reserve(pool_, nullptr, 2 * kSuperPageSize), - nullptr); + EXPECT_EQ(GetAddressPoolManager()->Reserve(pool_, 0, 2 * kSuperPageSize), 0u); GetAddressPoolManager()->GetPoolUsedSuperPages(pool_, used_super_pages); @@ -165,45 +153,35 @@ } TEST_F(PartitionAllocAddressPoolManagerTest, IrregularPattern) { - char* base_ptr = reinterpret_cast<char*>(base_address_); - - void* a1 = GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - EXPECT_EQ(a1, base_ptr); - void* a2 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 2 * kSuperPageSize); - EXPECT_EQ(a2, base_ptr + 1 * kSuperPageSize); - void* a3 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 3 * kSuperPageSize); - EXPECT_EQ(a3, base_ptr + 3 * kSuperPageSize); - void* a4 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 4 * kSuperPageSize); - EXPECT_EQ(a4, base_ptr + 6 * kSuperPageSize); - void* a5 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 5 * kSuperPageSize); - EXPECT_EQ(a5, base_ptr + 10 * kSuperPageSize); + uintptr_t a1 = GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + EXPECT_EQ(a1, base_address_); + uintptr_t a2 = GetAddressPoolManager()->Reserve(pool_, 0, 2 * kSuperPageSize); + EXPECT_EQ(a2, base_address_ + 1 * kSuperPageSize); + uintptr_t a3 = GetAddressPoolManager()->Reserve(pool_, 0, 3 * kSuperPageSize); + EXPECT_EQ(a3, base_address_ + 3 * kSuperPageSize); + uintptr_t a4 = GetAddressPoolManager()->Reserve(pool_, 0, 4 * kSuperPageSize); + EXPECT_EQ(a4, base_address_ + 6 * kSuperPageSize); + uintptr_t a5 = GetAddressPoolManager()->Reserve(pool_, 0, 5 * kSuperPageSize); + EXPECT_EQ(a5, base_address_ + 10 * kSuperPageSize); GetAddressPoolManager()->UnreserveAndDecommit(pool_, a4, 4 * kSuperPageSize); - void* a6 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 6 * kSuperPageSize); - EXPECT_EQ(a6, base_ptr + 15 * kSuperPageSize); + uintptr_t a6 = GetAddressPoolManager()->Reserve(pool_, 0, 6 * kSuperPageSize); + EXPECT_EQ(a6, base_address_ + 15 * kSuperPageSize); GetAddressPoolManager()->UnreserveAndDecommit(pool_, a5, 5 * kSuperPageSize); - void* a7 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 7 * kSuperPageSize); - EXPECT_EQ(a7, base_ptr + 6 * kSuperPageSize); - void* a8 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 3 * kSuperPageSize); - EXPECT_EQ(a8, base_ptr + 21 * kSuperPageSize); - void* a9 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 2 * kSuperPageSize); - EXPECT_EQ(a9, base_ptr + 13 * kSuperPageSize); + uintptr_t a7 = GetAddressPoolManager()->Reserve(pool_, 0, 7 * kSuperPageSize); + EXPECT_EQ(a7, base_address_ + 6 * kSuperPageSize); + uintptr_t a8 = GetAddressPoolManager()->Reserve(pool_, 0, 3 * kSuperPageSize); + EXPECT_EQ(a8, base_address_ + 21 * kSuperPageSize); + uintptr_t a9 = GetAddressPoolManager()->Reserve(pool_, 0, 2 * kSuperPageSize); + EXPECT_EQ(a9, base_address_ + 13 * kSuperPageSize); GetAddressPoolManager()->UnreserveAndDecommit(pool_, a7, 7 * kSuperPageSize); GetAddressPoolManager()->UnreserveAndDecommit(pool_, a9, 2 * kSuperPageSize); GetAddressPoolManager()->UnreserveAndDecommit(pool_, a6, 6 * kSuperPageSize); - void* a10 = - GetAddressPoolManager()->Reserve(pool_, nullptr, 15 * kSuperPageSize); - EXPECT_EQ(a10, base_ptr + 6 * kSuperPageSize); + uintptr_t a10 = + GetAddressPoolManager()->Reserve(pool_, 0, 15 * kSuperPageSize); + EXPECT_EQ(a10, base_address_ + 6 * kSuperPageSize); // Clean up. GetAddressPoolManager()->UnreserveAndDecommit(pool_, a1, kSuperPageSize); @@ -215,27 +193,31 @@ } TEST_F(PartitionAllocAddressPoolManagerTest, DecommittedDataIsErased) { - void* data = GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - ASSERT_TRUE(data); - RecommitSystemPages(data, kSuperPageSize, PageReadWrite, + uintptr_t address = + GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + ASSERT_TRUE(address); + void* ptr = reinterpret_cast<void*>(address); + RecommitSystemPages(ptr, kSuperPageSize, PageReadWrite, PageUpdatePermissions); - memset(data, 42, kSuperPageSize); - GetAddressPoolManager()->UnreserveAndDecommit(pool_, data, kSuperPageSize); + memset(ptr, 42, kSuperPageSize); + GetAddressPoolManager()->UnreserveAndDecommit(pool_, address, kSuperPageSize); - void* data2 = - GetAddressPoolManager()->Reserve(pool_, nullptr, kSuperPageSize); - ASSERT_EQ(data, data2); - RecommitSystemPages(data2, kSuperPageSize, PageReadWrite, + uintptr_t address2 = + GetAddressPoolManager()->Reserve(pool_, 0, kSuperPageSize); + ASSERT_EQ(address, address2); + uint8_t* ptr2 = reinterpret_cast<uint8_t*>(address2); + RecommitSystemPages(ptr2, kSuperPageSize, PageReadWrite, PageUpdatePermissions); uint32_t sum = 0; for (size_t i = 0; i < kSuperPageSize; i++) { - sum += reinterpret_cast<uint8_t*>(data2)[i]; + sum += ptr2[i]; } EXPECT_EQ(0u, sum) << sum / 42 << " bytes were not zeroed"; - GetAddressPoolManager()->UnreserveAndDecommit(pool_, data2, kSuperPageSize); + GetAddressPoolManager()->UnreserveAndDecommit(pool_, address2, + kSuperPageSize); } #else // defined(PA_HAS_64_BITS_POINTERS) @@ -245,14 +227,12 @@ static const size_t kNumPages[kAllocCount] = {1, 4, 7, 8, 13, 16, 31, 60}; uintptr_t addrs[kAllocCount]; for (size_t i = 0; i < kAllocCount; ++i) { - addrs[i] = - reinterpret_cast<uintptr_t>(AddressPoolManager::GetInstance()->Reserve( - GetRegularPool(), nullptr, - AddressPoolManagerBitmap::kBytesPer1BitOfRegularPoolBitmap * - kNumPages[i])); + addrs[i] = AddressPoolManager::GetInstance()->Reserve( + GetRegularPool(), 0, + AddressPoolManagerBitmap::kBytesPer1BitOfRegularPoolBitmap * + kNumPages[i]); EXPECT_TRUE(addrs[i]); - EXPECT_TRUE( - !(reinterpret_cast<uintptr_t>(addrs[i]) & kSuperPageOffsetMask)); + EXPECT_TRUE(!(addrs[i] & kSuperPageOffsetMask)); AddressPoolManager::GetInstance()->MarkUsed( GetRegularPool(), addrs[i], AddressPoolManagerBitmap::kBytesPer1BitOfRegularPoolBitmap * @@ -282,7 +262,7 @@ AddressPoolManagerBitmap::kBytesPer1BitOfRegularPoolBitmap * kNumPages[i]); AddressPoolManager::GetInstance()->UnreserveAndDecommit( - GetRegularPool(), reinterpret_cast<void*>(addrs[i]), + GetRegularPool(), addrs[i], AddressPoolManagerBitmap::kBytesPer1BitOfRegularPoolBitmap * kNumPages[i]); EXPECT_FALSE(AddressPoolManager::IsManagedByRegularPool(addrs[i])); @@ -297,12 +277,10 @@ static const size_t kNumPages[kAllocCount] = {1, 3, 7, 11}; uintptr_t addrs[kAllocCount]; for (size_t i = 0; i < kAllocCount; ++i) { - addrs[i] = - reinterpret_cast<uintptr_t>(AddressPoolManager::GetInstance()->Reserve( - GetBRPPool(), nullptr, kSuperPageSize * kNumPages[i])); + addrs[i] = AddressPoolManager::GetInstance()->Reserve( + GetBRPPool(), 0, kSuperPageSize * kNumPages[i]); EXPECT_TRUE(addrs[i]); - EXPECT_TRUE( - !(reinterpret_cast<uintptr_t>(addrs[i]) & kSuperPageOffsetMask)); + EXPECT_TRUE(!(addrs[i] & kSuperPageOffsetMask)); AddressPoolManager::GetInstance()->MarkUsed(GetBRPPool(), addrs[i], kSuperPageSize * kNumPages[i]); } @@ -335,8 +313,7 @@ AddressPoolManager::GetInstance()->MarkUnused( GetBRPPool(), addrs[i], kSuperPageSize * kNumPages[i]); AddressPoolManager::GetInstance()->UnreserveAndDecommit( - GetBRPPool(), reinterpret_cast<void*>(addrs[i]), - kSuperPageSize * kNumPages[i]); + GetBRPPool(), addrs[i], kSuperPageSize * kNumPages[i]); EXPECT_FALSE(AddressPoolManager::IsManagedByRegularPool(addrs[i])); EXPECT_FALSE(AddressPoolManager::IsManagedByBRPPool(addrs[i])); }
diff --git a/base/allocator/partition_allocator/partition_address_space.cc b/base/allocator/partition_allocator/partition_address_space.cc index 1d03aae4f..1574d1f1 100644 --- a/base/allocator/partition_allocator/partition_address_space.cc +++ b/base/allocator/partition_allocator/partition_address_space.cc
@@ -113,16 +113,17 @@ #if PA_STARSCAN_USE_CARD_TABLE // Reserve memory for PCScan quarantine card table. - void* requested_address = - reinterpret_cast<void*>(setup_.regular_pool_base_address_); - char* actual_address = internal::AddressPoolManager::GetInstance()->Reserve( - setup_.regular_pool_, requested_address, kSuperPageSize); + uintptr_t requested_address = setup_.regular_pool_base_address_; + uintptr_t actual_address = + internal::AddressPoolManager::GetInstance()->Reserve( + setup_.regular_pool_, requested_address, kSuperPageSize); PA_CHECK(requested_address == actual_address) << "QuarantineCardTable is required to be allocated at the beginning of " "the regular pool"; #endif // PA_STARSCAN_USE_CARD_TABLE } +// TODO(bartekn): Consider void* -> uintptr_t void PartitionAddressSpace::InitConfigurablePool(void* address, size_t size) { // The ConfigurablePool must only be initialized once. PA_CHECK(!IsConfigurablePoolInitialized());
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index 5b0982c..650a5567 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -102,13 +102,11 @@ #if (DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)) && \ BUILDFLAG(USE_BACKUP_REF_PTR) -// TODO(bartekn): void* -> uintptr_t -void CheckThatSlotOffsetIsZero(void* ptr) { +void CheckThatSlotOffsetIsZero(uintptr_t address) { // Add kPartitionPastAllocationAdjustment, because // PartitionAllocGetSlotStartInBRPPool will subtract it. PA_CHECK(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + - kPartitionPastAllocationAdjustment) == ptr); + address + kPartitionPastAllocationAdjustment) == address); } #endif
diff --git a/base/allocator/partition_allocator/partition_alloc_config.h b/base/allocator/partition_allocator/partition_alloc_config.h index c5dfbc0..550d72f 100644 --- a/base/allocator/partition_allocator/partition_alloc_config.h +++ b/base/allocator/partition_allocator/partition_alloc_config.h
@@ -161,4 +161,13 @@ #define PA_HAS_ALLOCATION_GUARD #endif +// Lazy commit should only be enabled on Windows, because commit charge is +// only meaningful and limited on Windows. It affects performance on other +// platforms and is simply not needed there due to OS supporting overcommit. +#if defined(OS_WIN) +constexpr bool kUseLazyCommit = true; +#else +constexpr bool kUseLazyCommit = false; +#endif + #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
diff --git a/base/allocator/partition_allocator/partition_alloc_forward.h b/base/allocator/partition_allocator/partition_alloc_forward.h index 38aaa66..6c6b7bd 100644 --- a/base/allocator/partition_allocator/partition_alloc_forward.h +++ b/base/allocator/partition_allocator/partition_alloc_forward.h
@@ -47,7 +47,7 @@ #if (DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)) && \ BUILDFLAG(USE_BACKUP_REF_PTR) -BASE_EXPORT void CheckThatSlotOffsetIsZero(void*); +BASE_EXPORT void CheckThatSlotOffsetIsZero(uintptr_t address); #endif } // namespace internal
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index e855d5a..1b300751 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <cstddef> +#include <cstdint> #include <limits> #include <memory> #include <random> @@ -61,6 +62,10 @@ { EXPECT_EQ(memory::UnmaskPtr(ptr1), memory::UnmaskPtr(ptr2)); } #define PA_EXPECT_PTR_NE(ptr1, ptr2) \ { EXPECT_NE(memory::UnmaskPtr(ptr1), memory::UnmaskPtr(ptr2)); } +#define PA_EXPECT_ADDR_EQ(addr1, addr2) \ + { EXPECT_EQ(memory::UnmaskPtr(addr1), memory::UnmaskPtr(addr2)); } +#define PA_EXPECT_ADDR_NE(addr1, addr2) \ + { EXPECT_NE(memory::UnmaskPtr(addr1), memory::UnmaskPtr(addr2)); } #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) @@ -957,10 +962,11 @@ EXPECT_EQ(predicted_capacity, actual_capacity); EXPECT_LT(requested_size, actual_capacity); #if BUILDFLAG(USE_BACKUP_REF_PTR) + uintptr_t address = reinterpret_cast<uintptr_t>(ptr); for (size_t offset = 0; offset < requested_size; ++offset) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_ADDR_EQ( + PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) allocator.root()->Free(ptr); @@ -976,10 +982,10 @@ EXPECT_EQ(predicted_capacity, actual_capacity); EXPECT_EQ(requested_size, actual_capacity); #if BUILDFLAG(USE_BACKUP_REF_PTR) + address = reinterpret_cast<uintptr_t>(ptr); for (size_t offset = 0; offset < requested_size; offset += 877) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) allocator.root()->Free(ptr); @@ -1000,10 +1006,10 @@ EXPECT_EQ(predicted_capacity, actual_capacity); EXPECT_EQ(requested_size + SystemPageSize(), actual_capacity); #if BUILDFLAG(USE_BACKUP_REF_PTR) + address = reinterpret_cast<uintptr_t>(ptr); for (size_t offset = 0; offset < requested_size; offset += 4999) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) @@ -1017,10 +1023,10 @@ EXPECT_EQ(predicted_capacity, actual_capacity); EXPECT_EQ(requested_size, actual_capacity); #if BUILDFLAG(USE_BACKUP_REF_PTR) + address = reinterpret_cast<uintptr_t>(ptr); for (size_t offset = 0; offset < requested_size; offset += 4999) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) @@ -1040,10 +1046,11 @@ EXPECT_EQ(predicted_capacity, actual_capacity); EXPECT_LT(requested_size, actual_capacity); #if BUILDFLAG(USE_BACKUP_REF_PTR) + address = reinterpret_cast<uintptr_t>(ptr); for (size_t offset = 0; offset < requested_size; offset += 16111) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_PTR_EQ( + PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) allocator.root()->Free(ptr); @@ -1153,13 +1160,13 @@ for (size_t i = 0; i < num_slots; ++i) { ptrs.push_back(allocator.root()->Alloc(requested_size, type_name)); } - for (size_t i = 0; i < num_slots; ++i) { - char* ptr = static_cast<char*>(ptrs[i]); + for (void* ptr : ptrs) { + uintptr_t address = reinterpret_cast<uintptr_t>(ptr); EXPECT_EQ(allocator.root()->AllocationCapacityFromPtr(ptr), requested_size); for (size_t offset = 0; offset < requested_size; offset += 13) { - PA_EXPECT_PTR_EQ(PartitionAllocGetSlotStartInBRPPool( - reinterpret_cast<uintptr_t>(ptr) + offset), - allocator.root()->AdjustPointerForExtrasSubtract(ptr)); + PA_EXPECT_PTR_EQ( + PartitionAllocGetSlotStartInBRPPool(address + offset), + allocator.root()->AdjustPointerForExtrasSubtract(address)); } allocator.root()->Free(ptr); } @@ -1746,9 +1753,8 @@ EXPECT_EQ(nullptr, bucket->empty_slot_spans_head); EXPECT_EQ(1, slot_span->num_allocated_slots); // Lazy commit commits only needed pages. - size_t expected_committed_size = allocator.root()->use_lazy_commit - ? SystemPageSize() - : PartitionPageSize(); + size_t expected_committed_size = + kUseLazyCommit ? SystemPageSize() : PartitionPageSize(); EXPECT_EQ(expected_committed_size, allocator.root()->get_total_size_of_committed_pages()); allocator.root()->Free(ptr); @@ -1766,9 +1772,8 @@ ->buckets[test_bucket_index_] .num_system_pages_per_slot_span; size_t expected_size = - allocator.root()->use_lazy_commit - ? SystemPageSize() - : num_system_pages_per_slot_span * SystemPageSize(); + kUseLazyCommit ? SystemPageSize() + : num_system_pages_per_slot_span * SystemPageSize(); EXPECT_EQ(expected_size, allocator.root()->get_total_size_of_committed_pages()); @@ -3084,9 +3089,8 @@ // A full slot span of size 1 partition page is committed. void* ptr = root.Alloc(small_size - kExtraAllocSize, type_name); // Lazy commit commits only needed pages. - size_t expected_committed_size = allocator.root()->use_lazy_commit - ? SystemPageSize() - : PartitionPageSize(); + size_t expected_committed_size = + kUseLazyCommit ? SystemPageSize() : PartitionPageSize(); size_t expected_super_pages_size = kSuperPageSize; size_t expected_max_committed_size = expected_committed_size; size_t bucket_index = SizeToIndex(small_size - kExtraAllocSize); @@ -3132,9 +3136,8 @@ // Allocating another size commits another slot span. ptr = root.Alloc(2 * small_size - kExtraAllocSize, type_name); - expected_committed_size += allocator.root()->use_lazy_commit - ? SystemPageSize() - : PartitionPageSize(); + expected_committed_size += + kUseLazyCommit ? SystemPageSize() : PartitionPageSize(); expected_max_committed_size = std::max(expected_max_committed_size, expected_committed_size); expected_max_allocated_size = @@ -3329,8 +3332,8 @@ *ptr1 = kCookie; - auto* ref_count = - PartitionRefCountPointer(reinterpret_cast<char*>(ptr1) - kPointerOffset); + auto* ref_count = PartitionRefCountPointer(reinterpret_cast<uintptr_t>(ptr1) - + kPointerOffset); EXPECT_TRUE(ref_count->IsAliveWithNoKnownRefs()); ref_count->Acquire(); @@ -3359,7 +3362,7 @@ // Remask ref_count because PartitionAlloc retags ptr to enforce quarantine. ref_count = memory::RemaskPtr(ref_count); EXPECT_TRUE(ref_count->Release()); - PartitionAllocFreeForRefCounting(reinterpret_cast<char*>(ptr1) - + PartitionAllocFreeForRefCounting(reinterpret_cast<uintptr_t>(ptr1) - kPointerOffset); uint64_t* ptr3 = reinterpret_cast<uint64_t*>( allocator.root()->Alloc(alloc_size, type_name)); @@ -3372,8 +3375,8 @@ void* ptr1 = allocator.root()->Alloc(orig_size, type_name); EXPECT_TRUE(ptr1); - auto* ref_count1 = - PartitionRefCountPointer(reinterpret_cast<char*>(ptr1) - kPointerOffset); + auto* ref_count1 = PartitionRefCountPointer( + reinterpret_cast<uintptr_t>(ptr1) - kPointerOffset); EXPECT_TRUE(ref_count1->IsAliveWithNoKnownRefs()); ref_count1->Acquire(); @@ -3387,8 +3390,8 @@ ref_count1 = memory::RemaskPtr(ref_count1); // Re-query ref-count. It may have moved if Realloc changed the slot. - auto* ref_count2 = - PartitionRefCountPointer(reinterpret_cast<char*>(ptr2) - kPointerOffset); + auto* ref_count2 = PartitionRefCountPointer( + reinterpret_cast<uintptr_t>(ptr2) - kPointerOffset); if (memory::UnmaskPtr(ptr1) == memory::UnmaskPtr(ptr2)) { // If the slot didn't change, ref-count should stay the same.
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index 5000b77..accde667 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/allocator/partition_allocator/partition_bucket.h" +#include <cstdint> #include "base/allocator/buildflags.h" #include "base/allocator/partition_allocator/address_pool_manager.h" @@ -12,6 +13,7 @@ #include "base/allocator/partition_allocator/partition_address_space.h" #include "base/allocator/partition_allocator/partition_alloc.h" #include "base/allocator/partition_allocator/partition_alloc_check.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_direct_map_extent.h" #include "base/allocator/partition_allocator/partition_oom.h" @@ -52,11 +54,11 @@ // kSuperPageSize granularity, a partial super page is considered blocked if // there is a raw_ptr<T> pointing anywhere in that super page, even if doesn't // point to that partially allocated region. -bool AreAllowedSuperPagesForBRPPool(const char* start, const char* end) { - PA_DCHECK(!(reinterpret_cast<uintptr_t>(start) % kSuperPageSize)); - for (const char* super_page = start; super_page < end; +bool AreAllowedSuperPagesForBRPPool(uintptr_t start, uintptr_t end) { + PA_DCHECK(!(start % kSuperPageSize)); + for (uintptr_t super_page = start; super_page < end; super_page += kSuperPageSize) { - // If any blocked superpage is found inside the given memory region, + // If any blocked super page is found inside the given memory region, // the memory region is blocked. if (!AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page)) return false; @@ -68,7 +70,7 @@ // Reserves |requested_size| worth of super pages from the specified pool of the // GigaCage. If BRP pool is requested this function will honor BRP block list. // -// The returned pointer will be aligned to kSuperPageSize, and so +// The returned address will be aligned to kSuperPageSize, and so // |requested_address| should be. |requested_size| doesn't have to be, however. // // |requested_address| is merely a hint, which will be attempted, but easily @@ -82,12 +84,12 @@ // AreAllowedSuperPagesForBRPPool. // - IsAllowedSuperPageForBRPPool (used by AreAllowedSuperPagesForBRPPool) is // designed to not need locking. -char* ReserveMemoryFromGigaCage(pool_handle pool, - void* requested_address, - size_t requested_size) { - PA_DCHECK(!(reinterpret_cast<uintptr_t>(requested_address) % kSuperPageSize)); +uintptr_t ReserveMemoryFromGigaCage(pool_handle pool, + uintptr_t requested_address, + size_t requested_size) { + PA_DCHECK(!(requested_address % kSuperPageSize)); - char* ptr = AddressPoolManager::GetInstance()->Reserve( + uintptr_t reserved_address = AddressPoolManager::GetInstance()->Reserve( pool, requested_address, requested_size); // In 32-bit mode, when allocating from BRP pool, verify that the requested @@ -96,14 +98,16 @@ if (pool == GetBRPPool()) { constexpr int kMaxRandomAddressTries = 10; for (int i = 0; i < kMaxRandomAddressTries; ++i) { - if (!ptr || AreAllowedSuperPagesForBRPPool(ptr, ptr + requested_size)) + if (!reserved_address || + AreAllowedSuperPagesForBRPPool(reserved_address, + reserved_address + requested_size)) break; - AddressPoolManager::GetInstance()->UnreserveAndDecommit(pool, ptr, - requested_size); + AddressPoolManager::GetInstance()->UnreserveAndDecommit( + pool, reserved_address, requested_size); // No longer try to honor |requested_address|, because it didn't work for // us last time. - ptr = AddressPoolManager::GetInstance()->Reserve(pool, nullptr, - requested_size); + reserved_address = + AddressPoolManager::GetInstance()->Reserve(pool, 0, requested_size); } // If the allocation attempt succeeds, we will break out of the following @@ -112,25 +116,29 @@ // Last resort: sequentially scan the whole 32-bit address space. The number // of blocked super-pages should be very small, so we expect to practically // never need to run the following code. Note that it may fail to find an - // available page, e.g., when it becomes available after the scan passes - // through it, but we accept the risk. - for (uintptr_t ptr_to_try = kSuperPageSize; ptr_to_try != 0; - ptr_to_try += kSuperPageSize) { - if (!ptr || AreAllowedSuperPagesForBRPPool(ptr, ptr + requested_size)) + // available super page, e.g., when it becomes available after the scan + // passes through it, but we accept the risk. + for (uintptr_t address_to_try = kSuperPageSize; address_to_try != 0; + address_to_try += kSuperPageSize) { + if (!reserved_address || + AreAllowedSuperPagesForBRPPool(reserved_address, + reserved_address + requested_size)) break; - AddressPoolManager::GetInstance()->UnreserveAndDecommit(pool, ptr, - requested_size); + AddressPoolManager::GetInstance()->UnreserveAndDecommit( + pool, reserved_address, requested_size); // Reserve() can return a different pointer than attempted. - ptr = AddressPoolManager::GetInstance()->Reserve( - pool, reinterpret_cast<void*>(ptr_to_try), requested_size); + reserved_address = AddressPoolManager::GetInstance()->Reserve( + pool, address_to_try, requested_size); } // If the loop ends naturally, the last allocated region hasn't been // verified. Do it now. - if (ptr && !AreAllowedSuperPagesForBRPPool(ptr, ptr + requested_size)) { - AddressPoolManager::GetInstance()->UnreserveAndDecommit(pool, ptr, - requested_size); - ptr = nullptr; + if (reserved_address && + !AreAllowedSuperPagesForBRPPool(reserved_address, + reserved_address + requested_size)) { + AddressPoolManager::GetInstance()->UnreserveAndDecommit( + pool, reserved_address, requested_size); + reserved_address = 0; } } #endif // !defined(PA_HAS_64_BITS_POINTERS) && BUILDFLAG(USE_BACKUP_REF_PTR) @@ -141,13 +149,13 @@ // raw_ptr<T> object that points to non-PA memory in another thread. // If `MarkUsed` was called earlier, the other thread could incorrectly // determine that the allocation had come form PartitionAlloc. - if (ptr) - AddressPoolManager::GetInstance()->MarkUsed( - pool, reinterpret_cast<uintptr_t>(ptr), requested_size); + if (reserved_address) + AddressPoolManager::GetInstance()->MarkUsed(pool, reserved_address, + requested_size); #endif - PA_DCHECK(!(reinterpret_cast<uintptr_t>(ptr) % kSuperPageSize)); - return ptr; + PA_DCHECK(!(reserved_address % kSuperPageSize)); + return reserved_address; } template <bool thread_safe> @@ -236,15 +244,14 @@ // Allocate from GigaCage. Route to the appropriate GigaCage pool based on // BackupRefPtr support. pool_handle pool = root->ChoosePool(); - char* reservation_start; + uintptr_t reservation_start; { // Reserving memory from the GigaCage is actually not a syscall on 64 bit // platforms. #if !defined(PA_HAS_64_BITS_POINTERS) ScopedSyscallTimer<thread_safe> timer{root}; #endif - reservation_start = - ReserveMemoryFromGigaCage(pool, nullptr, reservation_size); + reservation_start = ReserveMemoryFromGigaCage(pool, 0, reservation_size); } if (UNLIKELY(!reservation_start)) { if (return_null) @@ -257,13 +264,13 @@ reservation_size, std::memory_order_relaxed); // Shift by 1 partition page (metadata + guard pages) and alignment padding. - char* const slot_start = + const uintptr_t slot_start = reservation_start + PartitionPageSize() + padding_for_alignment; { ScopedSyscallTimer<thread_safe> timer{root}; RecommitSystemPages( - reservation_start + SystemPageSize(), + reinterpret_cast<void*>(reservation_start + SystemPageSize()), #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) // If PUT_REF_COUNT_IN_PREVIOUS_SLOT is on, and if the BRP pool is // used, allocate 2 SystemPages, one for SuperPage metadata and the @@ -281,21 +288,19 @@ // so no other thread can update the same offset table entries at the // same time. Furthermore, nobody will be ready these offsets until this // function returns. - uintptr_t ptr_start = reinterpret_cast<uintptr_t>(reservation_start); - uintptr_t ptr_end = ptr_start + reservation_size; - auto* offset_ptr = ReservationOffsetPointer(ptr_start); - int offset = 0; - while (ptr_start < ptr_end) { - PA_DCHECK(offset_ptr < GetReservationOffsetTableEnd(ptr_start)); + uintptr_t address_start = reservation_start; + uintptr_t address_end = address_start + reservation_size; + auto* offset_ptr = ReservationOffsetPointer(address_start); + uint16_t offset = 0; + while (address_start < address_end) { + PA_DCHECK(offset_ptr < GetReservationOffsetTableEnd(address_start)); PA_DCHECK(offset < kOffsetTagNormalBuckets); *offset_ptr++ = offset++; - ptr_start += kSuperPageSize; + address_start += kSuperPageSize; } auto* super_page_extent = - reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea( - reinterpret_cast<uintptr_t>(reservation_start))); + PartitionSuperPageToExtent<thread_safe>(reservation_start); super_page_extent->root = root; // The new structures are all located inside a fresh system page so they // will all be zeroed out. These DCHECKs are for documentation and to assert @@ -305,7 +310,8 @@ PartitionPage<thread_safe>* first_page = reinterpret_cast<PartitionPage<thread_safe>*>(super_page_extent) + 1; - page = PartitionPage<thread_safe>::FromPtr(slot_start); + page = PartitionPage<thread_safe>::FromPtr( + reinterpret_cast<void*>(slot_start)); // |first_page| and |page| may be equal, if there is no alignment padding. if (page != first_page) { PA_DCHECK(page > first_page); @@ -383,7 +389,8 @@ return nullptr; } - auto* next_entry = new (slot_start) PartitionFreelistEntry(); + auto* next_entry = + new (reinterpret_cast<void*>(slot_start)) PartitionFreelistEntry(); page->slot_span_metadata.SetFreelistHead(next_entry); map_extent = &metadata->direct_map_extent; @@ -504,7 +511,7 @@ PA_DCHECK(slot_span_committed_size % SystemPageSize() == 0); PA_DCHECK(slot_span_committed_size <= slot_span_reservation_size); - auto adjusted_next_partition_page = + uintptr_t adjusted_next_partition_page = bits::AlignUp(root->next_partition_page, slot_span_alignment); if (UNLIKELY(adjusted_next_partition_page + slot_span_reservation_size > root->next_partition_page_end)) { @@ -525,10 +532,10 @@ root->next_partition_page_end); } - auto* gap_start_page = - PartitionPage<thread_safe>::FromPtr(root->next_partition_page); - auto* gap_end_page = - PartitionPage<thread_safe>::FromPtr(adjusted_next_partition_page); + auto* gap_start_page = PartitionPage<thread_safe>::FromPtr( + reinterpret_cast<void*>(root->next_partition_page)); + auto* gap_end_page = PartitionPage<thread_safe>::FromPtr( + reinterpret_cast<void*>(adjusted_next_partition_page)); for (auto* page = gap_start_page; page < gap_end_page; ++page) { PA_DCHECK(!page->is_valid); page->has_valid_span_after_this = 1; @@ -536,18 +543,18 @@ root->next_partition_page = adjusted_next_partition_page + slot_span_reservation_size; - void* slot_span_start = adjusted_next_partition_page; + uintptr_t slot_span_start = adjusted_next_partition_page; auto* slot_span = &gap_end_page->slot_span_metadata; InitializeSlotSpan(slot_span); // Now that slot span is initialized, it's safe to call FromSlotStartPtr. - PA_DCHECK(slot_span == - SlotSpanMetadata<thread_safe>::FromSlotStartPtr(slot_span_start)); + PA_DCHECK(slot_span == SlotSpanMetadata<thread_safe>::FromSlotStartPtr( + reinterpret_cast<void*>(slot_span_start))); // System pages in the super page come in a decommited state. Commit them // before vending them back. // If lazy commit is enabled, pages will be committed when provisioning slots, // in ProvisionMoreSlotsAndAllocOne(), not here. - if (!root->use_lazy_commit) { + if (!kUseLazyCommit) { PA_DEBUG_DATA_ON_STACK("slotsize", slot_size); PA_DEBUG_DATA_ON_STACK("spansize", slot_span_reservation_size); PA_DEBUG_DATA_ON_STACK("spancmt", slot_span_committed_size); @@ -567,37 +574,36 @@ } template <bool thread_safe> -ALWAYS_INLINE void* PartitionBucket<thread_safe>::AllocNewSuperPage( +ALWAYS_INLINE uintptr_t PartitionBucket<thread_safe>::AllocNewSuperPage( PartitionRoot<thread_safe>* root, int flags) { // Need a new super page. We want to allocate super pages in a contiguous // address region as much as possible. This is important for not causing // page table bloat and not fragmenting address spaces in 32 bit // architectures. - char* requested_address = root->next_super_page; + uintptr_t requested_address = root->next_super_page; // Allocate from GigaCage. Route to the appropriate GigaCage pool based on // BackupRefPtr support. pool_handle pool = root->ChoosePool(); - char* super_page = + uintptr_t super_page = ReserveMemoryFromGigaCage(pool, requested_address, kSuperPageSize); if (UNLIKELY(!super_page)) { if (flags & PartitionAllocReturnNull) - return nullptr; + return 0; // Didn't manage to get a new uncommitted super page -> address space issue. ScopedUnlockGuard<thread_safe> unlock{root->lock_}; PartitionOutOfMemoryMappingFailure(root, kSuperPageSize); } - *ReservationOffsetPointer(reinterpret_cast<uintptr_t>(super_page)) = - kOffsetTagNormalBuckets; + *ReservationOffsetPointer(super_page) = kOffsetTagNormalBuckets; root->total_size_of_super_pages.fetch_add(kSuperPageSize, std::memory_order_relaxed); root->next_super_page = super_page + kSuperPageSize; - char* state_bitmap = super_page + PartitionPageSize(); - PA_DCHECK(reinterpret_cast<char*>(SuperPageStateBitmap(super_page)) == + uintptr_t state_bitmap = super_page + PartitionPageSize(); + PA_DCHECK(reinterpret_cast<uintptr_t>(SuperPageStateBitmap(super_page)) == state_bitmap); const size_t state_bitmap_reservation_size = root->IsQuarantineAllowed() ? ReservedStateBitmapSize() : 0; @@ -606,10 +612,10 @@ PA_DCHECK(state_bitmap_reservation_size % PartitionPageSize() == 0); PA_DCHECK(state_bitmap_size_to_commit % SystemPageSize() == 0); PA_DCHECK(state_bitmap_size_to_commit <= state_bitmap_reservation_size); - char* ret = state_bitmap + state_bitmap_reservation_size; - root->next_partition_page = ret; + uintptr_t payload = state_bitmap + state_bitmap_reservation_size; + root->next_partition_page = payload; root->next_partition_page_end = root->next_super_page - PartitionPageSize(); - PA_DCHECK(ret == + PA_DCHECK(payload == SuperPagePayloadBegin(super_page, root->IsQuarantineAllowed())); PA_DCHECK(root->next_partition_page_end == SuperPagePayloadEnd(super_page)); @@ -619,7 +625,7 @@ { ScopedSyscallTimer<thread_safe> timer{root}; RecommitSystemPages( - super_page + SystemPageSize(), + reinterpret_cast<void*>(super_page + SystemPageSize()), #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) // If PUT_REF_COUNT_IN_PREVIOUS_SLOT is on, and if the BRP pool is used, // allocate 2 SystemPages, one for SuperPage metadata and the other for @@ -638,14 +644,11 @@ // successful mapping, which is far from random. So we just get fresh // randomness for the next mapping attempt. if (requested_address && requested_address != super_page) - root->next_super_page = nullptr; + root->next_super_page = 0; // We allocated a new super page so update super page metadata. // First check if this is a new extent or not. - auto* latest_extent = - reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea( - reinterpret_cast<uintptr_t>(super_page))); + auto* latest_extent = PartitionSuperPageToExtent<thread_safe>(super_page); // By storing the root in every extent metadata object, we have a fast way // to go from a pointer within the partition to the root object. latest_extent->root = root; @@ -674,8 +677,8 @@ // little. PA_DCHECK(current_extent->number_of_consecutive_super_pages); ++current_extent->number_of_consecutive_super_pages; - PA_DCHECK(ret > SuperPagesBeginFromExtent(current_extent) && - ret < SuperPagesEndFromExtent(current_extent)); + PA_DCHECK(payload > SuperPagesBeginFromExtent(current_extent) && + payload < SuperPagesEndFromExtent(current_extent)); } // If PCScan is used, commit the state bitmap. Otherwise, leave it uncommitted @@ -686,13 +689,14 @@ if (root->IsQuarantineEnabled()) { { ScopedSyscallTimer<thread_safe> timer{root}; - RecommitSystemPages(state_bitmap, state_bitmap_size_to_commit, - PageReadWrite, PageUpdatePermissions); + RecommitSystemPages(reinterpret_cast<void*>(state_bitmap), + state_bitmap_size_to_commit, PageReadWrite, + PageUpdatePermissions); } - PCScan::RegisterNewSuperPage(root, reinterpret_cast<uintptr_t>(super_page)); + PCScan::RegisterNewSuperPage(root, super_page); } - return ret; + return payload; } template <bool thread_safe> @@ -759,7 +763,7 @@ // Note, we can't use PageKeepPermissionsIfPossible, because we have no // knowledge which pages have been committed before (it doesn't matter on // Windows anyway). - if (root->use_lazy_commit) { + if (kUseLazyCommit) { // TODO(lizeb): Handle commit failure. root->RecommitSystemPagesForData(reinterpret_cast<uintptr_t>(commit_start), commit_end - commit_start, @@ -974,20 +978,17 @@ // If lazy commit is enabled, pages will be recommitted when provisioning // slots, in ProvisionMoreSlotsAndAllocOne(), not here. - if (!root->use_lazy_commit) { + if (!kUseLazyCommit) { uintptr_t address = reinterpret_cast<uintptr_t>( SlotSpanMetadata<thread_safe>::ToSlotSpanStartPtr(new_slot_span)); - // If lazy commit isn't used, we have a guarantee that all slot span + // Since lazy commit isn't used, we have a guarantee that all slot span // pages have been previously committed, and then decommitted using // PageKeepPermissionsIfPossible, so use the same option as an - // optimization. Otherwise fall back to PageUpdatePermissions (slower). - // (Insider knowledge: as of writing this comment, lazy commit is only - // used on Windows and this flag is ignored there, thus no perf impact.) + // optimization. // TODO(lizeb): Handle commit failure. root->RecommitSystemPagesForData( address, new_slot_span->bucket->get_bytes_per_span(), - root->use_lazy_commit ? PageUpdatePermissions - : PageKeepPermissionsIfPossible); + PageKeepPermissionsIfPossible); } new_slot_span->Reset();
diff --git a/base/allocator/partition_allocator/partition_bucket.h b/base/allocator/partition_allocator/partition_bucket.h index 68206336..f61bd72 100644 --- a/base/allocator/partition_allocator/partition_bucket.h +++ b/base/allocator/partition_allocator/partition_bucket.h
@@ -159,10 +159,11 @@ int flags, size_t slot_span_alignment) EXCLUSIVE_LOCKS_REQUIRED(root->lock_); - // Allocates a new super page from the current extent. All slot-spans will be - // in the decommitted state. Returns nullptr on error. - ALWAYS_INLINE void* AllocNewSuperPage(PartitionRoot<thread_safe>* root, - int flags) + // Allocates a new super page from the current extent, if possible. All + // slot-spans will be in the decommitted state. Returns the address of the + // super page's payload, or 0 on error. + ALWAYS_INLINE uintptr_t AllocNewSuperPage(PartitionRoot<thread_safe>* root, + int flags) EXCLUSIVE_LOCKS_REQUIRED(root->lock_); // Each bucket allocates a slot span when it runs out of slots.
diff --git a/base/allocator/partition_allocator/partition_cookie.h b/base/allocator/partition_allocator/partition_cookie.h index c2bab92..7e9396c 100644 --- a/base/allocator/partition_allocator/partition_cookie.h +++ b/base/allocator/partition_allocator/partition_cookie.h
@@ -23,14 +23,14 @@ constexpr size_t kPartitionCookieSizeAdjustment = kCookieSize; -ALWAYS_INLINE void PartitionCookieCheckValue(void* ptr) { - unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(ptr); +ALWAYS_INLINE void PartitionCookieCheckValue(uintptr_t address) { + unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(address); for (size_t i = 0; i < kCookieSize; ++i, ++cookie_ptr) PA_DCHECK(*cookie_ptr == kCookieValue[i]); } -ALWAYS_INLINE void PartitionCookieWriteValue(void* ptr) { - unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(ptr); +ALWAYS_INLINE void PartitionCookieWriteValue(uintptr_t address) { + unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(address); for (size_t i = 0; i < kCookieSize; ++i, ++cookie_ptr) *cookie_ptr = kCookieValue[i]; } @@ -39,9 +39,10 @@ constexpr size_t kPartitionCookieSizeAdjustment = 0; -ALWAYS_INLINE void PartitionCookieCheckValue(void* ptr) {} +ALWAYS_INLINE void PartitionCookieCheckValue(uintptr_t address) {} -ALWAYS_INLINE void PartitionCookieWriteValue(void* ptr) {} +ALWAYS_INLINE void PartitionCookieWriteValue(uintptr_t address) {} + #endif // DCHECK_IS_ON() } // namespace internal
diff --git a/base/allocator/partition_allocator/partition_page.cc b/base/allocator/partition_allocator/partition_page.cc index fcc404e..a880904 100644 --- a/base/allocator/partition_allocator/partition_page.cc +++ b/base/allocator/partition_allocator/partition_page.cc
@@ -12,6 +12,7 @@ #include "base/allocator/partition_allocator/page_allocator_constants.h" #include "base/allocator/partition_allocator/partition_address_space.h" #include "base/allocator/partition_allocator/partition_alloc_check.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_alloc_forward.h" #include "base/allocator/partition_allocator/partition_direct_map_extent.h" @@ -218,7 +219,7 @@ // If lazy commit is enabled, only provisioned slots are committed. size_t dirty_size = bits::AlignUp(GetProvisionedSize(), SystemPageSize()); size_t size_to_decommit = - root->use_lazy_commit ? dirty_size : bucket->get_bytes_per_span(); + kUseLazyCommit ? dirty_size : bucket->get_bytes_per_span(); PA_DCHECK(root->empty_slot_spans_dirty_bytes >= dirty_size); root->empty_slot_spans_dirty_bytes -= dirty_size; @@ -352,7 +353,7 @@ // After resetting the table entries, unreserve and decommit the memory. AddressPoolManager::GetInstance()->UnreserveAndDecommit( - pool, reinterpret_cast<void*>(reservation_start), reservation_size); + pool, reservation_start, reservation_size); } } // namespace
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index 631b2c22..09f4eaac 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -63,12 +63,12 @@ // CAUTION! |extent| must point to the extent of the first super page in the // range of consecutive super pages. template <bool thread_safe> -ALWAYS_INLINE char* SuperPagesBeginFromExtent( - PartitionSuperPageExtentEntry<thread_safe>* extent) { +ALWAYS_INLINE uintptr_t +SuperPagesBeginFromExtent(PartitionSuperPageExtentEntry<thread_safe>* extent) { PA_DCHECK(0 < extent->number_of_consecutive_super_pages); - PA_DCHECK(IsManagedByNormalBuckets(reinterpret_cast<uintptr_t>(extent))); - return base::bits::AlignDown(reinterpret_cast<char*>(extent), - kSuperPageAlignment); + uintptr_t extent_as_uintptr = reinterpret_cast<uintptr_t>(extent); + PA_DCHECK(IsManagedByNormalBuckets(extent_as_uintptr)); + return base::bits::AlignDown(extent_as_uintptr, kSuperPageAlignment); } // Returns the end of the last super page in the range of consecutive super @@ -77,8 +77,8 @@ // CAUTION! |extent| must point to the extent of the first super page in the // range of consecutive super pages. template <bool thread_safe> -ALWAYS_INLINE char* SuperPagesEndFromExtent( - PartitionSuperPageExtentEntry<thread_safe>* extent) { +ALWAYS_INLINE uintptr_t +SuperPagesEndFromExtent(PartitionSuperPageExtentEntry<thread_safe>* extent) { return SuperPagesBeginFromExtent(extent) + (extent->number_of_consecutive_super_pages * kSuperPageSize); } @@ -363,20 +363,25 @@ subsequent_page_metadata) == 0, ""); -// TODO(bartekn): char* -> PartitionPage* or uintptr_t -ALWAYS_INLINE char* PartitionSuperPageToMetadataArea(uintptr_t address) { - PA_DCHECK(IsReservationStart(address)); - PA_DCHECK(!(address & kSuperPageOffsetMask)); +template <bool thread_safe> +ALWAYS_INLINE PartitionPage<thread_safe>* PartitionSuperPageToMetadataArea( + uintptr_t super_page) { + // This can't be just any super page, but it has to be the first super page of + // the reservation, as we assume here that the metadata is near its beginning. + PA_DCHECK(IsReservationStart(super_page)); + PA_DCHECK(!(super_page & kSuperPageOffsetMask)); // The metadata area is exactly one system page (the guard page) into the // super page. - return reinterpret_cast<char*>(address + SystemPageSize()); + return reinterpret_cast<PartitionPage<thread_safe>*>(super_page + + SystemPageSize()); } template <bool thread_safe> ALWAYS_INLINE PartitionSuperPageExtentEntry<thread_safe>* -PartitionSuperPageToExtent(uintptr_t address) { +PartitionSuperPageToExtent(uintptr_t super_page) { + // The very first entry of the metadata is the super page extent entry. return reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea(address)); + PartitionSuperPageToMetadataArea<thread_safe>(super_page)); } // Size that should be reserved for state bitmap (if present) inside a super @@ -396,42 +401,38 @@ // Returns the pointer to the state bitmap in the super page. It's the caller's // responsibility to ensure that the bitmaps even exist. -ALWAYS_INLINE AllocationStateMap* SuperPageStateBitmap(char* super_page_base) { - PA_DCHECK( - !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment)); - return reinterpret_cast<AllocationStateMap*>(super_page_base + +ALWAYS_INLINE AllocationStateMap* SuperPageStateBitmap(uintptr_t super_page) { + PA_DCHECK(!(super_page % kSuperPageAlignment)); + return reinterpret_cast<AllocationStateMap*>(super_page + PartitionPageSize()); } -ALWAYS_INLINE char* SuperPagePayloadBegin(char* super_page_base, - bool with_quarantine) { - PA_DCHECK( - !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment)); - return super_page_base + PartitionPageSize() + +ALWAYS_INLINE uintptr_t SuperPagePayloadBegin(uintptr_t super_page, + bool with_quarantine) { + PA_DCHECK(!(super_page % kSuperPageAlignment)); + return super_page + PartitionPageSize() + (with_quarantine ? ReservedStateBitmapSize() : 0); } -ALWAYS_INLINE char* SuperPagePayloadEnd(char* super_page_base) { - PA_DCHECK( - !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment)); - return super_page_base + kSuperPageSize - PartitionPageSize(); +ALWAYS_INLINE uintptr_t SuperPagePayloadEnd(uintptr_t super_page) { + PA_DCHECK(!(super_page % kSuperPageAlignment)); + return super_page + kSuperPageSize - PartitionPageSize(); } -ALWAYS_INLINE size_t SuperPagePayloadSize(char* super_page_base, +ALWAYS_INLINE size_t SuperPagePayloadSize(uintptr_t super_page, bool with_quarantine) { - return SuperPagePayloadEnd(super_page_base) - - SuperPagePayloadBegin(super_page_base, with_quarantine); + return SuperPagePayloadEnd(super_page) - + SuperPagePayloadBegin(super_page, with_quarantine); } template <bool thread_safe> ALWAYS_INLINE void PartitionSuperPageExtentEntry< thread_safe>::IncrementNumberOfNonemptySlotSpans() { #if DCHECK_IS_ON() - char* super_page_begin = - base::bits::AlignDown(reinterpret_cast<char*>(this), kSuperPageAlignment); - PA_DCHECK( - (SuperPagePayloadSize(super_page_begin, root->IsQuarantineAllowed()) / - PartitionPageSize()) > number_of_nonempty_slot_spans); + uintptr_t super_page = base::bits::AlignDown( + reinterpret_cast<uintptr_t>(this), kSuperPageAlignment); + PA_DCHECK((SuperPagePayloadSize(super_page, root->IsQuarantineAllowed()) / + PartitionPageSize()) > number_of_nonempty_slot_spans); #endif ++number_of_nonempty_slot_spans; } @@ -452,11 +453,9 @@ address = memory::UnmaskPtr(address); PA_DCHECK(IsManagedByNormalBuckets(address)); // TODO(bartekn): char* -> uintptr_t, incl. callees - char* super_page_base = reinterpret_cast<char*>(address & kSuperPageBaseMask); - uintptr_t payload_start = reinterpret_cast<uintptr_t>( - SuperPagePayloadBegin(super_page_base, with_quarantine)); - uintptr_t payload_end = - reinterpret_cast<uintptr_t>(SuperPagePayloadEnd(super_page_base)); + uintptr_t super_page = address & kSuperPageBaseMask; + uintptr_t payload_start = SuperPagePayloadBegin(super_page, with_quarantine); + uintptr_t payload_end = SuperPagePayloadEnd(super_page); return address >= payload_start && address < payload_end; } @@ -492,9 +491,7 @@ #if DCHECK_IS_ON() PA_DCHECK(IsReservationStart(super_page)); if (IsManagedByNormalBuckets(address)) { - auto* extent = - reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea(super_page)); + auto* extent = PartitionSuperPageToExtent<thread_safe>(super_page); PA_DCHECK( IsWithinSuperPagePayload(address, extent->root->IsQuarantineAllowed())); } else { @@ -510,9 +507,8 @@ // for other exclusions. PA_DCHECK(partition_page_index); PA_DCHECK(partition_page_index < NumPartitionPagesPerSuperPage() - 1); - return reinterpret_cast<PartitionPage<thread_safe>*>( - PartitionSuperPageToMetadataArea(super_page) + - (partition_page_index << kPageMetadataShift)); + return PartitionSuperPageToMetadataArea<thread_safe>(super_page) + + partition_page_index; } // Converts from a pointer to the SlotSpanMetadata object (within a super @@ -577,14 +573,14 @@ template <bool thread_safe> ALWAYS_INLINE PartitionSuperPageExtentEntry<thread_safe>* SlotSpanMetadata<thread_safe>::ToSuperPageExtent() const { - uintptr_t super_page_base = - reinterpret_cast<uintptr_t>(this) & kSuperPageBaseMask; - return reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea(super_page_base)); + uintptr_t super_page = reinterpret_cast<uintptr_t>(this) & kSuperPageBaseMask; + return PartitionSuperPageToExtent<thread_safe>(super_page); } // Like |FromSlotInnerPtr|, but asserts that pointer points to the beginning of // the slot. This works on direct maps too. +// +// TODO(bartekn): void* -> uintptr_t, Ptr -> Addr template <bool thread_safe> ALWAYS_INLINE SlotSpanMetadata<thread_safe>* SlotSpanMetadata<thread_safe>::FromSlotStartPtr(void* slot_start) { @@ -760,39 +756,30 @@ // Returns the state bitmap from a pointer within a normal-bucket super page. // It's the caller's responsibility to ensure that the bitmap exists. -// -// TODO(bartekn): void* -> address, Ptr -> Address -ALWAYS_INLINE AllocationStateMap* StateBitmapFromPointer(void* ptr) { - uintptr_t address = reinterpret_cast<uintptr_t>(ptr); +ALWAYS_INLINE AllocationStateMap* StateBitmapFromPointer(uintptr_t address) { PA_DCHECK(IsManagedByNormalBuckets(address)); - auto* super_page_base = reinterpret_cast<char*>(address & kSuperPageBaseMask); - return SuperPageStateBitmap(super_page_base); + uintptr_t super_page = address & kSuperPageBaseMask; + return SuperPageStateBitmap(super_page); } // Iterates over all slot spans in a super-page. |Callback| must return true if // early return is needed. -// -// TODO(bartekn): char* -> uintptr_t template <bool thread_safe, typename Callback> -void IterateSlotSpans(char* super_page_base, +void IterateSlotSpans(uintptr_t super_page, bool with_quarantine, Callback callback) { #if DCHECK_IS_ON() - PA_DCHECK( - !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment)); - auto* extent_entry = - reinterpret_cast<PartitionSuperPageExtentEntry<thread_safe>*>( - PartitionSuperPageToMetadataArea( - reinterpret_cast<uintptr_t>(super_page_base))); + PA_DCHECK(!(super_page % kSuperPageAlignment)); + auto* extent_entry = PartitionSuperPageToExtent<thread_safe>(super_page); extent_entry->root->lock_.AssertAcquired(); #endif using Page = PartitionPage<thread_safe>; using SlotSpan = SlotSpanMetadata<thread_safe>; - auto* const first_page = - Page::FromPtr(SuperPagePayloadBegin(super_page_base, with_quarantine)); - auto* const last_page = - Page::FromPtr(SuperPagePayloadEnd(super_page_base) - PartitionPageSize()); + auto* const first_page = Page::FromPtr(reinterpret_cast<void*>( + SuperPagePayloadBegin(super_page, with_quarantine))); + auto* const last_page = Page::FromPtr(reinterpret_cast<void*>( + SuperPagePayloadEnd(super_page) - PartitionPageSize())); Page* page; SlotSpan* slot_span; for (page = first_page; page <= last_page;) {
diff --git a/base/allocator/partition_allocator/partition_ref_count.h b/base/allocator/partition_allocator/partition_ref_count.h index 0e56237..b6f4db1 100644 --- a/base/allocator/partition_allocator/partition_ref_count.h +++ b/base/allocator/partition_allocator/partition_ref_count.h
@@ -187,25 +187,23 @@ "PartitionRefCount Bitmap size must be smaller than or equal to " "<= SystemPageSize()."); -ALWAYS_INLINE PartitionRefCount* PartitionRefCountPointer(void* slot_start) { +ALWAYS_INLINE PartitionRefCount* PartitionRefCountPointer( + uintptr_t slot_start) { PA_DCHECK(slot_start == memory::RemaskPtr(slot_start)); #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) CheckThatSlotOffsetIsZero(slot_start); #endif - uintptr_t slot_start_as_uintptr = reinterpret_cast<uintptr_t>(slot_start); - if (LIKELY(slot_start_as_uintptr & SystemPageOffsetMask())) { - uintptr_t refcount_ptr_as_uintptr = - slot_start_as_uintptr - sizeof(PartitionRefCount); + if (LIKELY(slot_start & SystemPageOffsetMask())) { + uintptr_t refcount_address = slot_start - sizeof(PartitionRefCount); #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) - PA_CHECK(refcount_ptr_as_uintptr % alignof(PartitionRefCount) == 0); + PA_CHECK(refcount_address % alignof(PartitionRefCount) == 0); #endif - return reinterpret_cast<PartitionRefCount*>(refcount_ptr_as_uintptr); + return reinterpret_cast<PartitionRefCount*>(refcount_address); } else { PartitionRefCount* bitmap_base = reinterpret_cast<PartitionRefCount*>( - (slot_start_as_uintptr & kSuperPageBaseMask) + SystemPageSize() * 2); - size_t index = - ((slot_start_as_uintptr & kSuperPageOffsetMask) >> SystemPageShift()) * - kPartitionRefCountIndexMultiplier; + (slot_start & kSuperPageBaseMask) + SystemPageSize() * 2); + size_t index = ((slot_start & kSuperPageOffsetMask) >> SystemPageShift()) * + kPartitionRefCountIndexMultiplier; #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) PA_CHECK(sizeof(PartitionRefCount) * index <= SystemPageSize()); #endif @@ -225,7 +223,8 @@ // only then we'll be able to find ref-count in that slot. constexpr size_t kPartitionPastAllocationAdjustment = 1; -ALWAYS_INLINE PartitionRefCount* PartitionRefCountPointer(void* slot_start) { +ALWAYS_INLINE PartitionRefCount* PartitionRefCountPointer( + uintptr_t slot_start) { #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) CheckThatSlotOffsetIsZero(slot_start); #endif
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc index 132057d..289c204 100644 --- a/base/allocator/partition_allocator/partition_root.cc +++ b/base/allocator/partition_allocator/partition_root.cc
@@ -733,18 +733,17 @@ // bucket->slot_size is the currently committed size of the allocation. size_t current_slot_size = slot_span->bucket->slot_size; - char* slot_start = - static_cast<char*>(SlotSpan::ToSlotSpanStartPtr(slot_span)); - uintptr_t slot_start_as_uintptr = reinterpret_cast<uintptr_t>(slot_start); + uintptr_t slot_start = + reinterpret_cast<uintptr_t>(SlotSpan::ToSlotSpanStartPtr(slot_span)); // This is the available part of the reservation up to which the new // allocation can grow. size_t available_reservation_size = current_reservation_size - extent->padding_for_alignment - PartitionRoot<thread_safe>::GetDirectMapMetadataAndGuardPagesSize(); #if DCHECK_IS_ON() - uintptr_t reservation_start = slot_start_as_uintptr & kSuperPageBaseMask; + uintptr_t reservation_start = slot_start & kSuperPageBaseMask; PA_DCHECK(internal::IsReservationStart(reservation_start)); - PA_DCHECK(slot_start_as_uintptr + available_reservation_size == + PA_DCHECK(slot_start + available_reservation_size == reservation_start + current_reservation_size - GetDirectMapMetadataAndGuardPagesSize() + PartitionPageSize()); #endif @@ -755,15 +754,15 @@ } else if (new_slot_size < current_slot_size) { // Shrink by decommitting unneeded pages and making them inaccessible. size_t decommit_size = current_slot_size - new_slot_size; - DecommitSystemPagesForData(slot_start_as_uintptr + new_slot_size, - decommit_size, PageUpdatePermissions); + DecommitSystemPagesForData(slot_start + new_slot_size, decommit_size, + PageUpdatePermissions); // Since the decommited system pages are still reserved, we don't need to // change the entries for decommitted pages in the reservation offset table. } else if (new_slot_size <= available_reservation_size) { // Grow within the actually reserved address space. Just need to make the // pages accessible again. size_t recommit_slot_size_growth = new_slot_size - current_slot_size; - RecommitSystemPagesForData(slot_start_as_uintptr + current_slot_size, + RecommitSystemPagesForData(slot_start + current_slot_size, recommit_slot_size_growth, PageUpdatePermissions); // The recommited system pages had been already reserved and all the @@ -771,8 +770,8 @@ // region) have been already initialized. #if DCHECK_IS_ON() - memset(slot_start + current_slot_size, kUninitializedByte, - recommit_slot_size_growth); + memset(reinterpret_cast<void*>(slot_start + current_slot_size), + kUninitializedByte, recommit_slot_size_growth); #endif } else { // We can't perform the realloc in-place. @@ -790,8 +789,7 @@ #if DCHECK_IS_ON() // Write a new trailing cookie. if (allow_cookie) { - char* user_data_start = - static_cast<char*>(AdjustPointerForExtrasAdd(slot_start)); + uintptr_t user_data_start = AdjustPointerForExtrasAdd(slot_start); size_t usable_size = slot_span->GetUsableSize(this); internal::PartitionCookieWriteValue(user_data_start + usable_size); } @@ -805,8 +803,8 @@ void* ptr, SlotSpan* slot_span, size_t new_size) { - PA_DCHECK( - internal::IsManagedByNormalBuckets(reinterpret_cast<uintptr_t>(ptr))); + uintptr_t address = reinterpret_cast<uintptr_t>(ptr); + PA_DCHECK(internal::IsManagedByNormalBuckets(address)); // TODO: note that tcmalloc will "ignore" a downsizing realloc() unless the // new size is a significant percentage smaller. We could do the same if we @@ -820,7 +818,7 @@ // statistics (and cookie, if present). if (slot_span->CanStoreRawSize()) { #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) && DCHECK_IS_ON() - void* slot_start = AdjustPointerForExtrasSubtract(ptr); + uintptr_t slot_start = AdjustPointerForExtrasSubtract(address); internal::PartitionRefCount* old_ref_count; if (brp_enabled()) { old_ref_count = internal::PartitionRefCountPointer(slot_start); @@ -840,8 +838,7 @@ // raw size (otherwise we wouldn't know where to look for it later). if (allow_cookie) { size_t usable_size = slot_span->GetUsableSize(this); - internal::PartitionCookieWriteValue(static_cast<char*>(ptr) + - usable_size); + internal::PartitionCookieWriteValue(address + usable_size); } #endif // DCHECK_IS_ON() }
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h index 86f012a5..1be69c1 100644 --- a/base/allocator/partition_allocator/partition_root.h +++ b/base/allocator/partition_allocator/partition_root.h
@@ -234,15 +234,6 @@ #endif bool use_configurable_pool; - // Lazy commit should only be enabled on Windows, because commit charge is - // only meaningful and limited on Windows. It affects performance on other - // platforms and is simply not needed there due to OS supporting overcommit. -#if defined(OS_WIN) - static constexpr bool use_lazy_commit = true; -#else - static constexpr bool use_lazy_commit = false; -#endif - #if !defined(PA_EXTRAS_REQUIRED) // Teach the compiler that code can be optimized in builds that use no extras. static constexpr uint32_t extras_size = 0; @@ -326,9 +317,9 @@ // useful to make tests deterministic and easier to reason about. int max_empty_slot_spans_dirty_bytes_shift = 3; - char* next_super_page = nullptr; - char* next_partition_page = nullptr; - char* next_partition_page_end = nullptr; + uintptr_t next_super_page = 0; + uintptr_t next_partition_page = 0; + uintptr_t next_partition_page_end = 0; SuperPageExtentEntry* current_extent = nullptr; SuperPageExtentEntry* first_extent = nullptr; DirectMapExtent* direct_map_list GUARDED_BY(lock_) = nullptr; @@ -363,12 +354,12 @@ ALWAYS_INLINE static bool IsValidSlotSpan(SlotSpan* slot_span); ALWAYS_INLINE static PartitionRoot* FromSlotSpan(SlotSpan* slot_span); // These two functions work unconditionally for normal buckets. - // For direct map, they only work for the first SuperPage of an allocation, + // For direct map, they only work for the first super page of a reservation, // that is the first "2MiB minus a bit" (see partition_alloc_constants.h for // the direct map allocation layout). - // In particular, the functions always work for a pointer to the start of an - // allocation. - ALWAYS_INLINE static PartitionRoot* FromFirstSuperPage(char* super_page); + // In particular, the functions always work for a pointer to the start of a + // reservation. + ALWAYS_INLINE static PartitionRoot* FromFirstSuperPage(uintptr_t super_page); ALWAYS_INLINE static PartitionRoot* FromPointerInFirstSuperpage(char* ptr); ALWAYS_INLINE void IncreaseCommittedPages(size_t len); @@ -456,9 +447,9 @@ // Same as |Free()|, bypasses the allocator hooks. ALWAYS_INLINE static void FreeNoHooks(void* ptr); // Immediately frees the pointer bypassing the quarantine. - ALWAYS_INLINE void FreeNoHooksImmediate(void* ptr, + ALWAYS_INLINE void FreeNoHooksImmediate(uintptr_t address, SlotSpan* slot_span, - void* slot_start); + uintptr_t slot_start); ALWAYS_INLINE static size_t GetUsableSize(void* ptr); @@ -539,7 +530,7 @@ return quarantine_mode == QuarantineMode::kEnabled; } - ALWAYS_INLINE bool ShouldQuarantine(void* slot_start) const { + ALWAYS_INLINE bool ShouldQuarantine(uintptr_t slot_start) const { if (UNLIKELY(quarantine_mode != QuarantineMode::kEnabled)) return false; #if HAS_MEMORY_TAGGING @@ -547,7 +538,7 @@ return true; // If quarantine is enabled and tag overflows, move slot to quarantine, to // prevent the attacker from exploiting a pointer that has old tag. - return HasOverflowTag(reinterpret_cast<uintptr_t>(slot_start)); + return HasOverflowTag(slot_start); #else return true; #endif @@ -640,14 +631,25 @@ return size - extras_size; } + // TODO(bartekn): Consider |void* SlotStartToObjectStart(uintptr_t)|. + ALWAYS_INLINE uintptr_t AdjustPointerForExtrasAdd(uintptr_t address) const { + return address + extras_offset; + } + // TODO(bartekn): Remove the |void*| variant. ALWAYS_INLINE void* AdjustPointerForExtrasAdd(void* ptr) const { - return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + - extras_offset); + return reinterpret_cast<void*>( + AdjustPointerForExtrasAdd(reinterpret_cast<uintptr_t>(ptr))); } + // TODO(bartekn): Consider |uintptr_t ObjectStartToSlotStart(void*)|. + ALWAYS_INLINE uintptr_t + AdjustPointerForExtrasSubtract(uintptr_t address) const { + return address - extras_offset; + } + // TODO(bartekn): Remove the |void*| variant. ALWAYS_INLINE void* AdjustPointerForExtrasSubtract(void* ptr) const { - return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) - - extras_offset); + return reinterpret_cast<void*>( + AdjustPointerForExtrasSubtract(reinterpret_cast<uintptr_t>(ptr))); } bool brp_enabled() const { @@ -714,6 +716,8 @@ // |requested_size|. // - |usable_size| and |is_already_zeroed| are output only. |usable_size| is // guaranteed to be larger or equal to AllocFlags()'s |requested_size|. + // + // TODO(bartekn): void* -> uintptr_t ALWAYS_INLINE void* RawAlloc(Bucket* bucket, int flags, size_t raw_size, @@ -763,9 +767,8 @@ #if BUILDFLAG(USE_BACKUP_REF_PTR) -// TODO(bartekn): void* -> uintptr_t -ALWAYS_INLINE void* PartitionAllocGetDirectMapSlotStartInBRPPool( - uintptr_t address) { +ALWAYS_INLINE uintptr_t +PartitionAllocGetDirectMapSlotStartInBRPPool(uintptr_t address) { PA_DCHECK(IsManagedByPartitionAllocBRPPool(address)); #if defined(PA_HAS_64_BITS_POINTERS) // Use this variant of GetDirectMapReservationStart as it has better @@ -777,7 +780,7 @@ uintptr_t reservation_start = GetDirectMapReservationStart(address); #endif if (!reservation_start) - return nullptr; + return 0; // The direct map allocation may not start exactly from the first page, as // there may be padding for alignment. The first page metadata holds an offset @@ -799,7 +802,7 @@ reinterpret_cast<void*>(reservation_start + PartitionPageSize() + padding_for_alignment)); #endif // DCHECK_IS_ON() - return ret; + return reinterpret_cast<uintptr_t>(ret); // TODO(bartekn): Remove cast. } // Gets the pointer to the beginning of the allocated slot. @@ -811,9 +814,7 @@ // This function is not a template, and can be used on either variant // (thread-safe or not) of the allocator. This relies on the two PartitionRoot<> // having the same layout, which is enforced by static_assert(). -// -// TODO(bartekn): void* -> uinptr_t -ALWAYS_INLINE void* PartitionAllocGetSlotStartInBRPPool(uintptr_t address) { +ALWAYS_INLINE uintptr_t PartitionAllocGetSlotStartInBRPPool(uintptr_t address) { // Adjust to support pointers right past the end of an allocation, which in // some cases appear to point outside the designated allocation slot. // @@ -826,7 +827,7 @@ PA_DCHECK(IsManagedByNormalBucketsOrDirectMap(address)); DCheckIfManagedByPartitionAllocBRPPool(address); - void* directmap_slot_start = + uintptr_t directmap_slot_start = PartitionAllocGetDirectMapSlotStartInBRPPool(address); if (UNLIKELY(directmap_slot_start)) return directmap_slot_start; @@ -845,9 +846,9 @@ size_t offset_in_slot_span = address - slot_span_start; auto* bucket = slot_span->bucket; - return memory::RemaskPtr(reinterpret_cast<void*>( - slot_span_start + - bucket->slot_size * bucket->GetSlotNumber(offset_in_slot_span))); + return memory::RemaskPtr(slot_span_start + + bucket->slot_size * + bucket->GetSlotNumber(offset_in_slot_span)); } // Checks whether a given pointer stays within the same allocation slot after @@ -867,7 +868,7 @@ PA_DCHECK(IsManagedByNormalBucketsOrDirectMap(adjusted_address)); DCheckIfManagedByPartitionAllocBRPPool(adjusted_address); - void* slot_start = PartitionAllocGetSlotStartInBRPPool(adjusted_address); + uintptr_t slot_start = PartitionAllocGetSlotStartInBRPPool(adjusted_address); // Get |slot_span| from |slot_start| instead of |adjusted_address|, because // for direct map, PartitionAllocGetSlotSpanForSizeQuery() only works on the // first partition page of the allocation. @@ -878,13 +879,14 @@ adjusted_address = 0; auto* slot_span = internal::PartitionAllocGetSlotSpanForSizeQuery<internal::ThreadSafe>( - reinterpret_cast<uintptr_t>(slot_start)); + slot_start); auto* root = PartitionRoot<internal::ThreadSafe>::FromSlotSpan(slot_span); // Double check that ref-count is indeed present. PA_DCHECK(root->brp_enabled()); - uintptr_t user_data_start = - reinterpret_cast<uintptr_t>(root->AdjustPointerForExtrasAdd(slot_start)); + // TODO(bartekn): Remove reinterpret_casts. + uintptr_t user_data_start = reinterpret_cast<uintptr_t>( + root->AdjustPointerForExtrasAdd(reinterpret_cast<void*>(slot_start))); size_t user_data_size = slot_span->GetUsableSize(root); uintptr_t new_address = address + delta_in_bytes; return user_data_start <= new_address && @@ -893,10 +895,11 @@ new_address <= user_data_start + user_data_size; } -ALWAYS_INLINE void PartitionAllocFreeForRefCounting(void* slot_start) { +ALWAYS_INLINE void PartitionAllocFreeForRefCounting(uintptr_t slot_start) { PA_DCHECK(!internal::PartitionRefCountPointer(slot_start)->IsAlive()); - auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotStartPtr(slot_start); + auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotStartPtr( + reinterpret_cast<void*>(slot_start)); auto* root = PartitionRoot<ThreadSafe>::FromSlotSpan(slot_span); // PartitionRefCount is required to be allocated inside a `PartitionRoot` that // supports reference counts. @@ -904,7 +907,7 @@ // memset() can be really expensive. #if EXPENSIVE_DCHECKS_ARE_ON() - memset(slot_start, kFreedByte, + memset(reinterpret_cast<void*>(slot_start), kFreedByte, slot_span->GetUtilizedSlotSize() #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) - sizeof(internal::PartitionRefCount) @@ -917,7 +920,7 @@ root->total_count_of_brp_quarantined_slots.fetch_sub( 1, std::memory_order_relaxed); - root->RawFreeWithThreadCache(slot_start, slot_span); + root->RawFreeWithThreadCache(reinterpret_cast<void*>(slot_start), slot_span); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) @@ -1013,6 +1016,7 @@ // cases where we don't would be delayed free() in PCScan, but |*ptr| can be // cold in cache. PA_PREFETCH(ptr); + uintptr_t address = reinterpret_cast<uintptr_t>(ptr); // On Android, malloc() interception is more fragile than on other // platforms, as we use wrapped symbols. However, the GigaCage allows us to @@ -1062,12 +1066,12 @@ PA_DCHECK(FromSlotSpan(slot_span) == root); const size_t slot_size = slot_span->bucket->slot_size; - void* slot_start = root->AdjustPointerForExtrasSubtract(ptr); + uintptr_t slot_start = root->AdjustPointerForExtrasSubtract(address); if (LIKELY(slot_size <= kMaxMemoryTaggingSize)) { // Incrementing the memory range returns the true underlying tag, so // RemaskPtr is not required here. slot_start = memory::TagMemoryRangeIncrement(slot_start, slot_size); - ptr = memory::RemaskPtr(ptr); + address = memory::RemaskPtr(address); } // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by @@ -1075,22 +1079,21 @@ if (UNLIKELY(root->ShouldQuarantine(slot_start))) { // PCScan safepoint. Call before potentially scheduling scanning task. PCScan::JoinScanIfNeeded(); - if (LIKELY(internal::IsManagedByNormalBuckets( - reinterpret_cast<uintptr_t>(ptr)))) { + if (LIKELY(internal::IsManagedByNormalBuckets(address))) { PCScan::MoveToQuarantine(ptr, slot_span->GetUsableSize(root), slot_start, slot_span->bucket->slot_size); return; } } - root->FreeNoHooksImmediate(ptr, slot_span, slot_start); + root->FreeNoHooksImmediate(address, slot_span, slot_start); } template <bool thread_safe> ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooksImmediate( - void* ptr, + uintptr_t address, SlotSpan* slot_span, - void* slot_start) { + uintptr_t slot_start) { // The thread cache is added "in the middle" of the main allocator, that is: // - After all the cookie/ref-count management // - Before the "raw" allocator. @@ -1100,11 +1103,12 @@ // 2. Deallocation // a. Return to the thread cache if possible. If it succeeds, return. // b. Otherwise, call the "raw" allocator <-- Locking - PA_DCHECK(ptr); + PA_DCHECK(address); PA_DCHECK(slot_span); PA_DCHECK(IsValidSlotSpan(slot_span)); + PA_DCHECK(slot_start); - // |ptr| points after the ref-count. + // |address| points after the ref-count. // // Layout inside the slot: // <-extras-> <-extras-> @@ -1112,7 +1116,7 @@ // <-GetUsableSize()--> // |[refcnt]|...data...|[empty]|[cookie]|[unused]| // ^ - // ptr + // address // // Note: ref-count and cookie can be 0-sized. // @@ -1122,8 +1126,7 @@ if (allow_cookie) { // Verify the cookie after the allocated region. // If this assert fires, you probably corrupted memory. - char* char_ptr = static_cast<char*>(ptr); - internal::PartitionCookieCheckValue(char_ptr + + internal::PartitionCookieCheckValue(address + slot_span->GetUsableSize(this)); } #endif @@ -1131,12 +1134,11 @@ // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by // default. if (UNLIKELY(IsQuarantineEnabled())) { - if (LIKELY(internal::IsManagedByNormalBuckets( - reinterpret_cast<uintptr_t>(ptr)))) { - auto* unmasked_slot_start = memory::UnmaskPtr(slot_start); + if (LIKELY(internal::IsManagedByNormalBuckets(address))) { + uintptr_t unmasked_slot_start = memory::UnmaskPtr(slot_start); // Mark the state in the state bitmap as freed. internal::StateBitmapFromPointer(unmasked_slot_start) - ->Free(reinterpret_cast<uintptr_t>(unmasked_slot_start)); + ->Free(unmasked_slot_start); } } @@ -1149,7 +1151,7 @@ // immediately. Otherwise, defer the operation and zap the memory to turn // potential use-after-free issues into unexploitable crashes. if (UNLIKELY(!ref_count->IsAliveWithNoKnownRefs())) - internal::SecureMemset(ptr, kQuarantinedByte, + internal::SecureMemset(reinterpret_cast<void*>(address), kQuarantinedByte, slot_span->GetUsableSize(this)); if (UNLIKELY(!(ref_count->ReleaseFromAllocator()))) { @@ -1164,7 +1166,7 @@ // memset() can be really expensive. #if EXPENSIVE_DCHECKS_ARE_ON() - memset(slot_start, kFreedByte, + memset(reinterpret_cast<void*>(slot_start), kFreedByte, slot_span->GetUtilizedSlotSize() #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) - sizeof(internal::PartitionRefCount) @@ -1175,7 +1177,7 @@ // efficiency. if (UNLIKELY(internal::RandomPeriod()) && !IsDirectMappedBucket(slot_span->bucket)) { - internal::SecureMemset(slot_start, 0, + internal::SecureMemset(reinterpret_cast<void*>(slot_start), 0, slot_span->GetUtilizedSlotSize() #if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) - sizeof(internal::PartitionRefCount) @@ -1184,7 +1186,7 @@ } #endif // defined(PA_ZERO_RANDOMLY_ON_FREE) - RawFreeWithThreadCache(slot_start, slot_span); + RawFreeWithThreadCache(reinterpret_cast<void*>(slot_start), slot_span); } template <bool thread_safe> @@ -1264,6 +1266,7 @@ slot_span->AppendFreeList(head, tail, size); } +// TODO(bartekn): void* -> uintptr_t template <bool thread_safe> ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeWithThreadCache( void* slot_start, @@ -1315,28 +1318,23 @@ return extent_entry->root; } -// TODO(bartekn): char* -> uintptr_t template <bool thread_safe> ALWAYS_INLINE PartitionRoot<thread_safe>* -PartitionRoot<thread_safe>::FromFirstSuperPage(char* super_page) { - PA_DCHECK( - internal::IsReservationStart(reinterpret_cast<uintptr_t>(super_page))); - auto* extent_entry = reinterpret_cast<SuperPageExtentEntry*>( - internal::PartitionSuperPageToMetadataArea( - reinterpret_cast<uintptr_t>(super_page))); +PartitionRoot<thread_safe>::FromFirstSuperPage(uintptr_t super_page) { + PA_DCHECK(internal::IsReservationStart(super_page)); + auto* extent_entry = + internal::PartitionSuperPageToExtent<thread_safe>(super_page); PartitionRoot* root = extent_entry->root; PA_DCHECK(root->inverted_self == ~reinterpret_cast<uintptr_t>(root)); return root; } -// TODO(bartekn): char* -> uintptr_t +// TODO(bartekn): char* -> uintptr_t, Pointer -> Addr template <bool thread_safe> ALWAYS_INLINE PartitionRoot<thread_safe>* PartitionRoot<thread_safe>::FromPointerInFirstSuperpage(char* ptr) { - char* super_page = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(ptr) & - kSuperPageBaseMask); - PA_DCHECK( - internal::IsReservationStart(reinterpret_cast<uintptr_t>(super_page))); + uintptr_t super_page = reinterpret_cast<uintptr_t>(ptr) & kSuperPageBaseMask; + PA_DCHECK(internal::IsReservationStart(super_page)); return FromFirstSuperPage(super_page); } @@ -1539,6 +1537,7 @@ uint16_t bucket_index = SizeToBucketIndex(raw_size); size_t usable_size; bool is_already_zeroed = false; + // TODO(bartekn): void* -> uintptr_t void* slot_start = nullptr; size_t slot_size; @@ -1664,8 +1663,8 @@ #if DCHECK_IS_ON() // Add the cookie after the allocation. if (allow_cookie) { - char* char_ret = static_cast<char*>(ret); - internal::PartitionCookieWriteValue(char_ret + usable_size); + uintptr_t address = reinterpret_cast<uintptr_t>(ret); + internal::PartitionCookieWriteValue(address + usable_size); } #endif @@ -1686,8 +1685,8 @@ // TODO(keishi): Add LIKELY when brp is fully enabled as |brp_enabled| will be // false only for the aligned partition. if (brp_enabled()) { - new (internal::PartitionRefCountPointer(slot_start)) - internal::PartitionRefCount(); + new (internal::PartitionRefCountPointer( + reinterpret_cast<uintptr_t>(slot_start))) internal::PartitionRefCount(); } #endif // BUILDFLAG(USE_BACKUP_REF_PTR) @@ -1696,10 +1695,11 @@ if (UNLIKELY(is_quarantine_enabled)) { if (LIKELY(internal::IsManagedByNormalBuckets( reinterpret_cast<uintptr_t>(ret)))) { - auto* unmasked_slot_start = memory::UnmaskPtr(slot_start); + uintptr_t unmasked_slot_start = + memory::UnmaskPtr(reinterpret_cast<uintptr_t>(slot_start)); // Mark the corresponding bits in the state bitmap as allocated. internal::StateBitmapFromPointer(unmasked_slot_start) - ->Allocate(reinterpret_cast<uintptr_t>(unmasked_slot_start)); + ->Allocate(unmasked_slot_start); } }
diff --git a/base/allocator/partition_allocator/starscan/pcscan.h b/base/allocator/partition_allocator/starscan/pcscan.h index a30e4ea2..847ab0f 100644 --- a/base/allocator/partition_allocator/starscan/pcscan.h +++ b/base/allocator/partition_allocator/starscan/pcscan.h
@@ -101,7 +101,7 @@ ALWAYS_INLINE static void MoveToQuarantine(void* ptr, size_t usable_size, - void* slot_start, + uintptr_t slot_start, size_t slot_size); // Performs scanning unconditionally. @@ -234,7 +234,7 @@ ALWAYS_INLINE void PCScan::MoveToQuarantine(void* ptr, size_t usable_size, - void* slot_start, + uintptr_t slot_start, size_t slot_size) { PCScan& instance = Instance(); if (instance.clear_type_ == ClearType::kEager) { @@ -247,13 +247,13 @@ SecureMemset(ptr, 0, usable_size); } - auto* unmasked_slot = memory::UnmaskPtr(slot_start); - auto* state_bitmap = StateBitmapFromPointer(unmasked_slot); + uintptr_t unmasked_slot_start = memory::UnmaskPtr(slot_start); + auto* state_bitmap = StateBitmapFromPointer(unmasked_slot_start); // Mark the state in the state bitmap as quarantined. Make sure to do it after // the clearing to avoid racing with *Scan Sweeper. - const bool succeeded = state_bitmap->Quarantine( - reinterpret_cast<uintptr_t>(unmasked_slot), instance.epoch()); + const bool succeeded = + state_bitmap->Quarantine(unmasked_slot_start, instance.epoch()); #if PA_STARSCAN_EAGER_DOUBLE_FREE_DETECTION_ENABLED if (UNLIKELY(!succeeded)) DoubleFreeAttempt();
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc index 6e2ebf9..29bd833 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -8,6 +8,7 @@ #include <array> #include <chrono> #include <condition_variable> +#include <cstdint> #include <mutex> #include <numeric> #include <set> @@ -128,8 +129,9 @@ // state while scanning. Unmarking on the step 3) ensures that unmarking // actually happens (and we don't hit too many false positives). // -// The code here relies on the fact that |ptr| is in the regular pool and that -// the card table (this object) is allocated at the very beginning of that pool. +// The code here relies on the fact that |address| is in the regular pool and +// that the card table (this object) is allocated at the very beginning of that +// pool. class QuarantineCardTable final { public: // Avoid the load of the base of the regular pool. @@ -149,12 +151,12 @@ return SetImpl(begin, size, false); } - // Returns whether the card to which |ptr| points to contains quarantined + // Returns whether the card to which |address| points to contains quarantined // objects. May return false positives for but should never return false // negatives, as otherwise this breaks security. - ALWAYS_INLINE bool IsQuarantined(uintptr_t ptr) const { - ptr = memory::UnmaskPtr(ptr); - const size_t byte = Byte(ptr); + ALWAYS_INLINE bool IsQuarantined(uintptr_t address) const { + address = memory::UnmaskPtr(address); + const size_t byte = Byte(address); PA_SCAN_DCHECK(byte < bytes_.size()); return bytes_[byte]; } @@ -209,25 +211,24 @@ size_t slot_size = 0; }; -// Returns the start of a slot, or nullptr if |maybe_inner_ptr| is not inside of -// an existing slot span. The function may return a non-nullptr pointer even -// inside a decommitted or free slot span, it's the caller responsibility to -// check if memory is actually allocated. +// Returns the start of a slot, or 0 if |maybe_inner_address| is not inside of +// an existing slot span. The function may return a non-0 address even inside a +// decommitted or free slot span, it's the caller responsibility to check if +// memory is actually allocated. // -// |maybe_inner_ptr| must be within a normal-bucket super page and can also +// |maybe_inner_address| must be within a normal-bucket super page and can also // point to guard pages or slot-span metadata. PA_SCAN_INLINE GetSlotStartResult -GetSlotStartInSuperPage(uintptr_t maybe_inner_ptr) { - PA_SCAN_DCHECK(IsManagedByNormalBuckets(maybe_inner_ptr)); +GetSlotStartInSuperPage(uintptr_t maybe_inner_address) { + PA_SCAN_DCHECK(IsManagedByNormalBuckets(maybe_inner_address)); // Don't use FromSlotInnerPtr() or FromPtr() because they expect a pointer to // a valid slot span. - const uintptr_t super_page_base = maybe_inner_ptr & kSuperPageBaseMask; + const uintptr_t super_page = maybe_inner_address & kSuperPageBaseMask; const uintptr_t partition_page_index = - (maybe_inner_ptr & kSuperPageOffsetMask) >> PartitionPageShift(); - auto* page = reinterpret_cast<PartitionPage<ThreadSafe>*>( - PartitionSuperPageToMetadataArea(super_page_base) + - (partition_page_index << kPageMetadataShift)); + (maybe_inner_address & kSuperPageOffsetMask) >> PartitionPageShift(); + auto* page = PartitionSuperPageToMetadataArea<ThreadSafe>(super_page) + + partition_page_index; // Check if page is valid. The check also works for the guard pages and the // metadata page. if (!page->is_valid) @@ -243,7 +244,7 @@ PA_SCAN_DCHECK(PartitionRoot<ThreadSafe>::IsValidSlotSpan(slot_span)); const uintptr_t slot_span_start = reinterpret_cast<uintptr_t>( SlotSpanMetadata<ThreadSafe>::ToSlotSpanStartPtr(slot_span)); - const ptrdiff_t ptr_offset = maybe_inner_ptr - slot_span_start; + const ptrdiff_t ptr_offset = maybe_inner_address - slot_span_start; PA_SCAN_DCHECK(0 <= ptr_offset && ptr_offset < static_cast<ptrdiff_t>( slot_span->bucket->get_pages_per_slot_span() * @@ -254,15 +255,14 @@ const size_t slot_size = slot_span->bucket->slot_size; const size_t slot_number = slot_span->bucket->GetSlotNumber(ptr_offset); const uintptr_t slot_start = slot_span_start + (slot_number * slot_size); - PA_SCAN_DCHECK(slot_start <= maybe_inner_ptr && - maybe_inner_ptr < slot_start + slot_size); - return {.slot_start = reinterpret_cast<uintptr_t>(slot_start), - .slot_size = slot_size}; + PA_SCAN_DCHECK(slot_start <= maybe_inner_address && + maybe_inner_address < slot_start + slot_size); + return {.slot_start = slot_start, .slot_size = slot_size}; } #if PA_SCAN_DCHECK_IS_ON() bool IsQuarantineEmptyOnSuperPage(uintptr_t super_page) { - auto* bitmap = SuperPageStateBitmap(reinterpret_cast<char*>(super_page)); + auto* bitmap = SuperPageStateBitmap(super_page); size_t visited = 0; bitmap->IterateQuarantined([&visited](auto) { ++visited; }); return !visited; @@ -291,10 +291,10 @@ } template <class Function> -void IterateNonEmptySlotSpans(uintptr_t super_page_base, +void IterateNonEmptySlotSpans(uintptr_t super_page, size_t nonempty_slot_spans, Function function) { - PA_SCAN_DCHECK(!(super_page_base % kSuperPageAlignment)); + PA_SCAN_DCHECK(!(super_page % kSuperPageAlignment)); PA_SCAN_DCHECK(nonempty_slot_spans); size_t slot_spans_to_visit = nonempty_slot_spans; @@ -303,7 +303,7 @@ #endif IterateSlotSpans<ThreadSafe>( - reinterpret_cast<char*>(super_page_base), true /*with_quarantine*/, + super_page, true /*with_quarantine*/, [&function, &slot_spans_to_visit #if PA_SCAN_DCHECK_IS_ON() , @@ -649,7 +649,7 @@ #endif // defined(PA_HAS_64_BITS_POINTERS) // We are certain here that |maybe_ptr| points to an allocated super-page. - return StateBitmapFromPointer(reinterpret_cast<char*>(maybe_ptr)); + return StateBitmapFromPointer(maybe_ptr); } // Looks up and marks a potential dangling pointer. Returns the size of the slot @@ -725,13 +725,11 @@ #endif StarScanSnapshot::ClearingView view(*snapshot_); - view.VisitConcurrently([clear_type](uintptr_t super_page_base) { - auto* bitmap = - StateBitmapFromPointer(reinterpret_cast<char*>(super_page_base)); - auto* root = - Root::FromFirstSuperPage(reinterpret_cast<char*>(super_page_base)); - bitmap->IterateQuarantined([root, clear_type](uintptr_t ptr) { - auto* object = memory::RemaskPtr(reinterpret_cast<void*>(ptr)); + view.VisitConcurrently([clear_type](uintptr_t super_page) { + auto* bitmap = StateBitmapFromPointer(super_page); + auto* root = Root::FromFirstSuperPage(super_page); + bitmap->IterateQuarantined([root, clear_type](uintptr_t address) { + auto* object = memory::RemaskPtr(reinterpret_cast<void*>(address)); auto* slot_span = SlotSpan::FromSlotInnerPtr(object); // Use zero as a zapping value to speed up the fast bailout check in // ScanPartitions. @@ -740,7 +738,7 @@ memset(object, 0, size); #if PA_STARSCAN_USE_CARD_TABLE // Set card(s) for this quarantined object. - QuarantineCardTable::GetFrom(ptr).Quarantine(ptr, size); + QuarantineCardTable::GetFrom(address).Quarantine(address, size); #endif }); }); @@ -868,7 +866,7 @@ pcscan.ProtectPages(reinterpret_cast<uintptr_t>(begin), (end - begin) * sizeof(uintptr_t)); - auto* bitmap = StateBitmapFromPointer(reinterpret_cast<void*>(begin)); + auto* bitmap = StateBitmapFromPointer(reinterpret_cast<uintptr_t>(begin)); const size_t slot_size_in_words = slot_size / sizeof(uintptr_t); for (uintptr_t* current_slot = begin; current_slot < end; @@ -931,56 +929,55 @@ size_t discarded_bytes = 0; }; -void UnmarkInCardTable(void* object, SlotSpanMetadata<ThreadSafe>* slot_span) { +void UnmarkInCardTable(uintptr_t object, + SlotSpanMetadata<ThreadSafe>* slot_span) { #if PA_STARSCAN_USE_CARD_TABLE - const uintptr_t object_as_uintptr = - reinterpret_cast<uintptr_t>(memory::UnmaskPtr(object)); + object = memory::UnmaskPtr(object); // Reset card(s) for this quarantined object. Please note that the // cards may still contain quarantined objects (which were // promoted in this scan cycle), but // ClearQuarantinedObjectsAndFilterSuperPages() will set them // again in the next PCScan cycle. - QuarantineCardTable::GetFrom(object_as_uintptr) - .Unquarantine(object_as_uintptr, slot_span->GetUtilizedSlotSize()); + QuarantineCardTable::GetFrom(object).Unquarantine( + object, slot_span->GetUtilizedSlotSize()); #endif } [[maybe_unused]] size_t FreeAndUnmarkInCardTable( PartitionRoot<ThreadSafe>* root, SlotSpanMetadata<ThreadSafe>* slot_span, - void* object) { + uintptr_t object) { object = memory::RemaskPtr(object); const size_t slot_size = slot_span->bucket->slot_size; - void* slot_start = root->AdjustPointerForExtrasSubtract(object); + uintptr_t slot_start = root->AdjustPointerForExtrasSubtract(object); root->FreeNoHooksImmediate(object, slot_span, slot_start); UnmarkInCardTable(object, slot_span); return slot_size; } [[maybe_unused]] void SweepSuperPage(ThreadSafePartitionRoot* root, - void* super_page, + uintptr_t super_page, size_t epoch, SweepStat& stat) { auto* bitmap = StateBitmapFromPointer(super_page); - ThreadSafePartitionRoot::FromFirstSuperPage(static_cast<char*>(super_page)); - bitmap->IterateUnmarkedQuarantined(epoch, [root, &stat](uintptr_t ptr) { - auto* object = reinterpret_cast<void*>(ptr); - auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr(object); - stat.swept_bytes += - FreeAndUnmarkInCardTable(root, slot_span, reinterpret_cast<void*>(ptr)); + ThreadSafePartitionRoot::FromFirstSuperPage(super_page); + bitmap->IterateUnmarkedQuarantined(epoch, [root, &stat](uintptr_t object) { + auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr( + reinterpret_cast<void*>(object)); + stat.swept_bytes += FreeAndUnmarkInCardTable(root, slot_span, object); }); } [[maybe_unused]] void SweepSuperPageAndDiscardMarkedQuarantine( ThreadSafePartitionRoot* root, - void* super_page, + uintptr_t super_page, size_t epoch, SweepStat& stat) { auto* bitmap = StateBitmapFromPointer(super_page); - bitmap->IterateQuarantined(epoch, [root, &stat](uintptr_t ptr, + bitmap->IterateQuarantined(epoch, [root, &stat](uintptr_t object, bool is_marked) { - auto* object = reinterpret_cast<void*>(ptr); - auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr(object); + auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr( + reinterpret_cast<void*>(object)); if (LIKELY(!is_marked)) { stat.swept_bytes += FreeAndUnmarkInCardTable(root, slot_span, object); return; @@ -993,8 +990,8 @@ // Since no data is stored in quarantined objects (e.g. the |next| // pointer), we can freely discard physical memory. const uintptr_t discard_end = - bits::AlignDown(ptr + slot_size, SystemPageSize()); - const uintptr_t discard_begin = bits::AlignUp(ptr, SystemPageSize()); + bits::AlignDown(object + slot_size, SystemPageSize()); + const uintptr_t discard_begin = bits::AlignUp(object, SystemPageSize()); const intptr_t discard_size = discard_end - discard_begin; if (discard_size > 0) { DiscardSystemPages(reinterpret_cast<void*>(discard_begin), @@ -1007,22 +1004,21 @@ [[maybe_unused]] void SweepSuperPageWithBatchedFree( ThreadSafePartitionRoot* root, - void* super_page, + uintptr_t super_page, size_t epoch, SweepStat& stat) { using SlotSpan = SlotSpanMetadata<ThreadSafe>; auto* bitmap = StateBitmapFromPointer(super_page); - SlotSpan* previous_slot_span = nullptr; internal::PartitionFreelistEntry* freelist_tail = nullptr; internal::PartitionFreelistEntry* freelist_head = nullptr; size_t freelist_entries = 0; - const auto bitmap_iterator = [&](uintptr_t ptr) { - auto* ptr_void = memory::RemaskPtr(reinterpret_cast<void*>((ptr))); - SlotSpan* current_slot_span = SlotSpan::FromSlotStartPtr(ptr_void); - auto* entry = new (ptr_void) PartitionFreelistEntry(); + const auto bitmap_iterator = [&](uintptr_t address) { + auto* ptr = reinterpret_cast<void*>(memory::RemaskPtr(address)); + SlotSpan* current_slot_span = SlotSpan::FromSlotStartPtr(ptr); + auto* entry = new (ptr) PartitionFreelistEntry(); if (current_slot_span != previous_slot_span) { // We started scanning a new slot span. Flush the accumulated freelist to @@ -1043,7 +1039,7 @@ freelist_tail = entry; ++freelist_entries; - UnmarkInCardTable(ptr_void, current_slot_span); + UnmarkInCardTable(address, current_slot_span); stat.swept_bytes += current_slot_span->bucket->slot_size; }; @@ -1073,20 +1069,17 @@ StarScanSnapshot::SweepingView sweeping_view(*snapshot_); sweeping_view.VisitNonConcurrently( [this, &stat, should_discard](uintptr_t super_page) { - void* super_page_as_void = reinterpret_cast<void*>(super_page); - auto* root = ThreadSafePartitionRoot::FromFirstSuperPage( - static_cast<char*>(super_page_as_void)); + auto* root = ThreadSafePartitionRoot::FromFirstSuperPage(super_page); #if PA_STARSCAN_BATCHED_FREE - SweepSuperPageWithBatchedFree(root, super_page_as_void, pcscan_epoch_, - stat); + SweepSuperPageWithBatchedFree(root, super_page, pcscan_epoch_, stat); (void)should_discard; #else if (UNLIKELY(should_discard && !root->allow_cookie)) - SweepSuperPageAndDiscardMarkedQuarantine(root, super_page_as_void, + SweepSuperPageAndDiscardMarkedQuarantine(root, super_page, pcscan_epoch_, stat); else - SweepSuperPage(root, super_page_as_void, pcscan_epoch_, stat); + SweepSuperPage(root, super_page, pcscan_epoch_, stat); #endif }); @@ -1418,18 +1411,18 @@ PCScanInternal::SuperPages super_pages; for (auto* super_page_extent = root.first_extent; super_page_extent; super_page_extent = super_page_extent->next) { - for (char *super_page = SuperPagesBeginFromExtent(super_page_extent), - *super_page_end = SuperPagesEndFromExtent(super_page_extent); + for (uintptr_t super_page = SuperPagesBeginFromExtent(super_page_extent), + super_page_end = SuperPagesEndFromExtent(super_page_extent); super_page != super_page_end; super_page += kSuperPageSize) { // Make sure the metadata is committed. // TODO(bikineev): Remove once this is known to work. - const volatile char* metadata = PartitionSuperPageToMetadataArea( - reinterpret_cast<uintptr_t>(super_page)); + const volatile char* metadata = reinterpret_cast<char*>( + PartitionSuperPageToMetadataArea<ThreadSafe>(super_page)); *metadata; - RecommitSystemPages(internal::SuperPageStateBitmap(super_page), + RecommitSystemPages(SuperPageStateBitmap(super_page), state_bitmap_size_to_commit, PageReadWrite, PageUpdatePermissions); - super_pages.push_back(reinterpret_cast<uintptr_t>(super_page)); + super_pages.push_back(super_page); } } return super_pages; @@ -1487,8 +1480,8 @@ PA_DCHECK(!(super_page_base % kSuperPageAlignment)); // Make sure the metadata is committed. // TODO(bikineev): Remove once this is known to work. - const volatile char* metadata = - PartitionSuperPageToMetadataArea(super_page_base); + const volatile char* metadata = reinterpret_cast<char*>( + PartitionSuperPageToMetadataArea<ThreadSafe>(super_page_base)); *metadata; std::lock_guard<std::mutex> lock(roots_mutex_);
diff --git a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc index c7b805c3..0054019 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <cstdint> #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) #include "base/allocator/partition_allocator/starscan/pcscan.h" @@ -94,9 +95,8 @@ void FinishPCScanAsScanner() { PCScan::FinishScanForTesting(); } bool IsInQuarantine(void* ptr) const { - auto* unmasked = memory::UnmaskPtr(ptr); - return StateBitmapFromPointer(unmasked)->IsQuarantined( - reinterpret_cast<uintptr_t>(unmasked)); + uintptr_t address = memory::UnmaskPtr(reinterpret_cast<uintptr_t>(ptr)); + return StateBitmapFromPointer(address)->IsQuarantined(address); } ThreadSafePartitionRoot& root() { return *allocator_.root(); } @@ -336,8 +336,7 @@ void* first_slot_span_end = nullptr; void* second_slot_span_start = nullptr; IterateSlotSpans<ThreadSafe>( - reinterpret_cast<char*>(super_page), true, - [&](SlotSpan* slot_span) -> bool { + super_page, true, [&](SlotSpan* slot_span) -> bool { if (i == 0) { first_slot_span_end = reinterpret_cast<char*>( SlotSpan::ToSlotSpanStartPtr(slot_span)) + @@ -711,7 +710,7 @@ TEST_F(PartitionAllocPCScanTest, PointersToGuardPages) { struct Pointers { - void* super_page_base; + void* super_page; void* metadata_page; void* guard_page1; void* scan_bitmap; @@ -721,17 +720,18 @@ auto* const pointers = static_cast<Pointers*>( root().AllocFlagsNoHooks(0, sizeof(Pointers), PartitionPageSize())); - char* const super_page = reinterpret_cast<char*>( - reinterpret_cast<uintptr_t>(pointers) & kSuperPageBaseMask); + const uintptr_t super_page = + reinterpret_cast<uintptr_t>(pointers) & kSuperPageBaseMask; // Initialize scannable pointers with addresses of guard pages and metadata. - pointers->super_page_base = super_page; + pointers->super_page = reinterpret_cast<void*>(super_page); pointers->metadata_page = - PartitionSuperPageToMetadataArea(reinterpret_cast<uintptr_t>(super_page)); + PartitionSuperPageToMetadataArea<ThreadSafe>(super_page); pointers->guard_page1 = static_cast<char*>(pointers->metadata_page) + SystemPageSize(); pointers->scan_bitmap = SuperPageStateBitmap(super_page); - pointers->guard_page1 = super_page + kSuperPageSize - PartitionPageSize(); + pointers->guard_page1 = reinterpret_cast<void*>(super_page + kSuperPageSize - + PartitionPageSize()); // Simply run PCScan and expect no crashes. RunPCScan();
diff --git a/base/allocator/partition_allocator/thread_cache_unittest.cc b/base/allocator/partition_allocator/thread_cache_unittest.cc index 7c396975..716a5ec6 100644 --- a/base/allocator/partition_allocator/thread_cache_unittest.cc +++ b/base/allocator/partition_allocator/thread_cache_unittest.cc
@@ -12,6 +12,7 @@ #include "base/allocator/partition_allocator/extended_api.h" #include "base/allocator/partition_allocator/partition_address_space.h" #include "base/allocator/partition_allocator/partition_alloc.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_lock.h" #include "base/bind.h" #include "base/callback.h" @@ -876,9 +877,8 @@ auto* tc_bucket = &root_->buckets[tc_bucket_index]; size_t expected_allocated_size = tc_bucket->slot_size; // For the ThreadCache itself. - size_t expected_committed_size = root_->use_lazy_commit - ? SystemPageSize() - : tc_bucket->get_bytes_per_span(); + size_t expected_committed_size = + kUseLazyCommit ? SystemPageSize() : tc_bucket->get_bytes_per_span(); EXPECT_EQ(expected_committed_size, root_->total_size_of_committed_pages); EXPECT_EQ(expected_committed_size, root_->max_size_of_committed_pages); @@ -891,9 +891,8 @@ auto* medium_bucket = &root_->buckets[root_->SizeToBucketIndex(kMediumSize)]; size_t medium_alloc_size = medium_bucket->slot_size; expected_allocated_size += medium_alloc_size; - expected_committed_size += root_->use_lazy_commit - ? SystemPageSize() - : medium_bucket->get_bytes_per_span(); + expected_committed_size += + kUseLazyCommit ? SystemPageSize() : medium_bucket->get_bytes_per_span(); EXPECT_EQ(expected_committed_size, root_->total_size_of_committed_pages); EXPECT_EQ(expected_committed_size, root_->max_size_of_committed_pages);
diff --git a/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java b/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java index 7bc8d7c..c7533c50 100644 --- a/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java +++ b/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java
@@ -9,9 +9,12 @@ import android.app.PictureInPictureParams; import android.content.ClipData; import android.content.ClipDescription; +import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; +import android.os.Bundle; import android.os.Process; +import android.view.Display; import android.view.textclassifier.TextClassification; import android.view.textclassifier.TextLinks; import android.view.textclassifier.TextSelection; @@ -93,4 +96,12 @@ public static TextClassification getTextClassification(TextSelection textSelection) { return textSelection.getTextClassification(); } + + /** + * See Context#createWindowContext. + */ + public static Context createWindowContext( + Context context, Display display, int type, Bundle options) { + return context.createWindowContext(display, type, options); + } }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java index 69f6db4b..f024ef4a 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -26,8 +26,6 @@ import org.chromium.base.memory.MemoryPressureCallback; import org.chromium.base.metrics.RecordHistogram; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.concurrent.Executor; @@ -719,33 +717,16 @@ return true; } - // NOTE: Keep values in sync with OnServiceConnectedTimedOutResult in enums.xml. - @Retention(RetentionPolicy.SOURCE) - public @interface TimeoutResult { - int ALREADY_CONNECTED = 0; - int NOT_NEEDED = 1; - int FALLBACK = 2; - int NUM_ENTRIES = 3; - } - private void checkBindTimeOut() { assert isRunningOnLauncherThread(); assert mFallbackServiceName != null; - final String histogramName = - "Android.ChildProcessLauncher.OnServiceConnectedTimedOutResult"; if (mDidOnServiceConnected || mServiceDisconnected) { - RecordHistogram.recordEnumeratedHistogram( - histogramName, TimeoutResult.ALREADY_CONNECTED, TimeoutResult.NUM_ENTRIES); return; } if (mUnbound) { - RecordHistogram.recordEnumeratedHistogram( - histogramName, TimeoutResult.NOT_NEEDED, TimeoutResult.NUM_ENTRIES); return; } - RecordHistogram.recordEnumeratedHistogram( - histogramName, TimeoutResult.FALLBACK, TimeoutResult.NUM_ENTRIES); Log.w(TAG, "Fallback to " + mFallbackServiceName); sFallbackEnabled = true; boolean isStrongBindingBound = mStrongBinding.isBound();
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc index bd4763b..c4cad28 100644 --- a/base/debug/stack_trace.cc +++ b/base/debug/stack_trace.cc
@@ -49,6 +49,27 @@ constexpr size_t kStackFrameAdjustment = 0; #endif +// On Arm-v8.3+ systems with pointer authentication codes (PAC), signature bits +// are set in the top bits of the pointer, which confuses test assertions. +// Because the signature size can vary based on the system configuration, use +// the xpaclri instruction to remove the signature. +static uintptr_t StripPointerAuthenticationBits(uintptr_t ptr) { +#if defined(ARCH_CPU_ARM64) + // A single Chromium binary currently spans all Arm systems (including those + // with and without pointer authentication). xpaclri is used here because it's + // in the HINT space and treated as a no-op on older Arm cores (unlike the + // more generic xpaci which has a new encoding). The downside is that ptr has + // to be moved to x30 to use this instruction. TODO(richard.townsend@arm.com): + // replace with an intrinsic once that is available. + register uintptr_t x30 __asm("x30") = ptr; + asm("xpaclri" : "+r"(x30)); + return x30; +#else + // No-op on other platforms. + return ptr; +#endif +} + uintptr_t GetNextStackFrame(uintptr_t fp) { const uintptr_t* fp_addr = reinterpret_cast<const uintptr_t*>(fp); MSAN_UNPOISON(fp_addr, sizeof(uintptr_t)); @@ -58,7 +79,7 @@ uintptr_t GetStackFramePC(uintptr_t fp) { const uintptr_t* fp_addr = reinterpret_cast<const uintptr_t*>(fp); MSAN_UNPOISON(&fp_addr[1], sizeof(uintptr_t)); - return fp_addr[1]; + return StripPointerAuthenticationBits(fp_addr[1]); } bool IsStackFrameValid(uintptr_t fp, uintptr_t prev_fp, uintptr_t stack_end) {
diff --git a/base/immediate_crash.h b/base/immediate_crash.h index 19d2cbc..b4ce643 100644 --- a/base/immediate_crash.h +++ b/base/immediate_crash.h
@@ -134,7 +134,7 @@ // calling function, but to this anonymous lambda. This is still useful as the // full name of the lambda will typically include the name of the function that // calls CHECK() and the debugger will still break at the right line of code. -#if !defined(COMPILER_GCC) +#if !defined(COMPILER_GCC) || defined(__clang__) #define WRAPPED_TRAP_SEQUENCE_() TRAP_SEQUENCE_() @@ -145,7 +145,7 @@ [] { TRAP_SEQUENCE_(); }(); \ } while (false) -#endif // !defined(COMPILER_GCC) +#endif // !defined(COMPILER_GCC) || defined(__clang__) #if defined(__clang__) || defined(COMPILER_GCC)
diff --git a/base/mac/authorization_util.h b/base/mac/authorization_util.h index 4629039..e818f94 100644 --- a/base/mac/authorization_util.h +++ b/base/mac/authorization_util.h
@@ -30,8 +30,7 @@ #include "base/base_export.h" -namespace base { -namespace mac { +namespace base::mac { // Obtains an AuthorizationRef for the rights indicated by |rights|. If // necessary, prompts the user for authentication. If the user is prompted, @@ -76,7 +75,6 @@ FILE** pipe, int* exit_status); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_AUTHORIZATION_UTIL_H_
diff --git a/base/mac/authorization_util.mm b/base/mac/authorization_util.mm index 872a79b..e1900a303 100644 --- a/base/mac/authorization_util.mm +++ b/base/mac/authorization_util.mm
@@ -21,8 +21,7 @@ #include "base/strings/string_util.h" #include "base/threading/hang_watcher.h" -namespace base { -namespace mac { +namespace base::mac { AuthorizationRef GetAuthorizationRightsWithPrompt( AuthorizationRights* rights, @@ -206,5 +205,4 @@ return status; } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/backup_util.h b/base/mac/backup_util.h index de81298..26c9f7a 100644 --- a/base/mac/backup_util.h +++ b/base/mac/backup_util.h
@@ -8,10 +8,10 @@ #include "base/base_export.h" namespace base { - class FilePath; +} -namespace mac { +namespace base::mac { // Returns true if the file or directory at `file_path` is excluded from // OS-managed backups. @@ -20,7 +20,6 @@ // Excludes the file or directory given by `file_path` from OS-managed backups. BASE_EXPORT bool SetBackupExclusion(const FilePath& file_path); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_BACKUP_UTIL_H_
diff --git a/base/mac/backup_util.mm b/base/mac/backup_util.mm index 8747536..b23972c 100644 --- a/base/mac/backup_util.mm +++ b/base/mac/backup_util.mm
@@ -15,8 +15,7 @@ #include "base/threading/scoped_blocking_call.h" #include "build/build_config.h" -namespace base { -namespace mac { +namespace base::mac { bool GetBackupExclusion(const FilePath& file_path) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, @@ -73,5 +72,4 @@ #endif } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/backup_util_unittest.mm b/base/mac/backup_util_unittest.mm index 25169f1..854a4147 100644 --- a/base/mac/backup_util_unittest.mm +++ b/base/mac/backup_util_unittest.mm
@@ -17,8 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -namespace base { -namespace mac { +namespace base::mac { namespace { @@ -68,5 +67,4 @@ } // namespace -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/bundle_locations.h b/base/mac/bundle_locations.h index 5cc44ba..17bad6e4 100644 --- a/base/mac/bundle_locations.h +++ b/base/mac/bundle_locations.h
@@ -15,10 +15,10 @@ #endif // __OBJC__ namespace base { - class FilePath; +} -namespace mac { +namespace base::mac { // This file provides several functions to explicitly request the various // component bundles of Chrome. Please use these methods rather than calling @@ -60,7 +60,6 @@ BASE_EXPORT void SetOverrideOuterBundlePath(const FilePath& file_path); BASE_EXPORT void SetOverrideFrameworkBundlePath(const FilePath& file_path); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_BUNDLE_LOCATIONS_H_
diff --git a/base/mac/bundle_locations.mm b/base/mac/bundle_locations.mm index 3a6ae7c..7455c17d 100644 --- a/base/mac/bundle_locations.mm +++ b/base/mac/bundle_locations.mm
@@ -8,8 +8,7 @@ #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" -namespace base { -namespace mac { +namespace base::mac { // NSBundle isn't threadsafe, all functions in this file must be called on the // main thread. @@ -79,5 +78,4 @@ AssignOverridePath(file_path, &g_override_framework_bundle); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/call_with_eh_frame.cc b/base/mac/call_with_eh_frame.cc index f26d1e5..f59a4f9 100644 --- a/base/mac/call_with_eh_frame.cc +++ b/base/mac/call_with_eh_frame.cc
@@ -9,8 +9,7 @@ #include "build/build_config.h" -namespace base { -namespace mac { +namespace base::mac { #if defined(__x86_64__) || defined(__aarch64__) extern "C" _Unwind_Reason_Code __gxx_personality_v0(int, @@ -49,5 +48,4 @@ block(); } #endif // defined(__x86_64__) || defined(__aarch64__) -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/call_with_eh_frame.h b/base/mac/call_with_eh_frame.h index 1f7d5e0..b9c0c99 100644 --- a/base/mac/call_with_eh_frame.h +++ b/base/mac/call_with_eh_frame.h
@@ -7,8 +7,7 @@ #include "base/base_export.h" -namespace base { -namespace mac { +namespace base::mac { // Invokes the specified block in a stack frame with a special exception // handler. This function creates an exception handling stack frame that @@ -20,7 +19,6 @@ // in such a way that disrupts the generation of useful stack traces. void BASE_EXPORT CallWithEHFrame(void (^block)(void)); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_CALL_WITH_EH_FRAME_H_
diff --git a/base/mac/call_with_eh_frame_unittest.mm b/base/mac/call_with_eh_frame_unittest.mm index 4dad822..6fd51c25 100644 --- a/base/mac/call_with_eh_frame_unittest.mm +++ b/base/mac/call_with_eh_frame_unittest.mm
@@ -8,8 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" -namespace base { -namespace mac { +namespace base::mac { namespace { class CallWithEHFrameTest : public testing::Test { @@ -51,5 +50,4 @@ } } // namespace -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/foundation_util.h b/base/mac/foundation_util.h index 29fd05c4..28f1d7a 100644 --- a/base/mac/foundation_util.h +++ b/base/mac/foundation_util.h
@@ -47,10 +47,10 @@ typedef struct CF_BRIDGED_TYPE(id) __SecPolicy* SecPolicyRef; namespace base { - class FilePath; +} -namespace mac { +namespace base::mac { // Returns true if the application is running from a bundle BASE_EXPORT bool AmIBundled(); @@ -151,8 +151,7 @@ // make its own copy of new_base_bundle_id. BASE_EXPORT void SetBaseBundleID(const char* new_base_bundle_id); -} // namespace mac -} // namespace base +} // namespace base::mac #if !defined(__OBJC__) #define OBJC_CPP_CLASS_DECL(x) class x; @@ -225,8 +224,7 @@ #undef CF_TO_NS_MUTABLE_CAST_DECL #undef OBJC_CPP_CLASS_DECL -namespace base { -namespace mac { +namespace base::mac { // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more // specific CoreFoundation type. The compatibility of the passed @@ -373,8 +371,7 @@ NSRange* range_out) WARN_UNUSED_RESULT; #endif // defined(__OBJC__) -} // namespace mac -} // namespace base +} // namespace base::mac // Stream operations for CFTypes. They can be used with NSTypes as well // by using the NSToCFCast methods above.
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm index 6e5d76dc..2a42798b 100644 --- a/base/mac/foundation_util.mm +++ b/base/mac/foundation_util.mm
@@ -40,8 +40,7 @@ #endif } // extern "C" -namespace base { -namespace mac { +namespace base::mac { namespace { @@ -499,8 +498,7 @@ return false; } -} // namespace mac -} // namespace base +} // namespace base::mac std::ostream& operator<<(std::ostream& o, const CFStringRef string) { return o << base::SysCFStringRefToUTF8(string);
diff --git a/base/mac/foundation_util_unittest.mm b/base/mac/foundation_util_unittest.mm index 40117cc..d6993df 100644 --- a/base/mac/foundation_util_unittest.mm +++ b/base/mac/foundation_util_unittest.mm
@@ -17,8 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" -namespace base { -namespace mac { +namespace base::mac { TEST(FoundationUtilTest, CFCast) { // Build out the CF types to be tested as empty containers. @@ -422,5 +421,4 @@ EXPECT_LOG_EQ("{0, 100}", NSMakeRange(0, 100)); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/launch_services_util.h b/base/mac/launch_services_util.h index 7979535c..e511710 100644 --- a/base/mac/launch_services_util.h +++ b/base/mac/launch_services_util.h
@@ -11,8 +11,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" -namespace base { -namespace mac { +namespace base::mac { // Launches the application bundle at |bundle_path|, passing argv[1..] from // |command_line| as command line arguments if the app isn't already running. @@ -24,7 +23,6 @@ const CommandLine& command_line, NSWorkspaceLaunchOptions launch_options); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_LAUNCH_SERVICES_UTIL_H_
diff --git a/base/mac/launch_services_util.mm b/base/mac/launch_services_util.mm index 18b0d9d..8786e84 100644 --- a/base/mac/launch_services_util.mm +++ b/base/mac/launch_services_util.mm
@@ -7,8 +7,7 @@ #include "base/logging.h" #include "base/strings/sys_string_conversions.h" -namespace base { -namespace mac { +namespace base::mac { NSRunningApplication* OpenApplicationWithPath( const base::FilePath& bundle_path, @@ -49,5 +48,4 @@ return app; } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/launchd.cc b/base/mac/launchd.cc index ded1306829..b65a62f 100644 --- a/base/mac/launchd.cc +++ b/base/mac/launchd.cc
@@ -12,8 +12,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -namespace base { -namespace mac { +namespace base::mac { // MessageForJob sends a single message to launchd with a simple dictionary // mapping |operation| to |job_label|, and returns the result of calling @@ -76,7 +75,6 @@ return launch_data_get_integer(pid_data); } -} // namespace mac -} // namespace base +} // namespace base::mac #pragma clang diagnostic pop
diff --git a/base/mac/launchd.h b/base/mac/launchd.h index 9e4514e8..f4f7ab6ce 100644 --- a/base/mac/launchd.h +++ b/base/mac/launchd.h
@@ -12,8 +12,7 @@ #include "base/base_export.h" -namespace base { -namespace mac { +namespace base::mac { // MessageForJob sends a single message to launchd with a simple dictionary // mapping |operation| to |job_label|, and returns the result of calling @@ -28,7 +27,6 @@ BASE_EXPORT pid_t PIDForJob(const std::string& job_label); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_LAUNCHD_H_
diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h index ad3ed21..5017b5c 100644 --- a/base/mac/mac_util.h +++ b/base/mac/mac_util.h
@@ -14,10 +14,10 @@ #include "base/base_export.h" namespace base { - class FilePath; +} -namespace mac { +namespace base::mac { // Returns an sRGB color space. The return value is a static value; do not // release it! @@ -214,7 +214,6 @@ // Returns the serial number of the macOS device. BASE_EXPORT std::string GetPlatformSerialNumber(); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_MAC_UTIL_H_
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm index 7e3d631..886de364 100644 --- a/base/mac/mac_util.mm +++ b/base/mac/mac_util.mm
@@ -30,8 +30,7 @@ #include "base/threading/scoped_blocking_call.h" #include "build/build_config.h" -namespace base { -namespace mac { +namespace base::mac { namespace { @@ -487,5 +486,4 @@ return base::SysCFStringRefToUTF8(serial_number_cfstring); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm index 86f6c34..d0c84f3 100644 --- a/base/mac/mac_util_unittest.mm +++ b/base/mac/mac_util_unittest.mm
@@ -21,8 +21,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -namespace base { -namespace mac { +namespace base::mac { namespace { @@ -313,5 +312,4 @@ } // namespace -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/objc_release_properties.h b/base/mac/objc_release_properties.h index d064cf9..4dd4812 100644 --- a/base/mac/objc_release_properties.h +++ b/base/mac/objc_release_properties.h
@@ -45,8 +45,7 @@ // properties. Distant subclasses might not expect it and over-release their // properties, so don't do that. -namespace base { -namespace mac { +namespace base::mac { namespace details { @@ -59,7 +58,6 @@ details::ReleaseProperties(self, [Self class]); } -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_OBJC_RELEASE_PROPERTIES_H_
diff --git a/base/mac/objc_release_properties.mm b/base/mac/objc_release_properties.mm index f9d19a4..8fcc9c1 100644 --- a/base/mac/objc_release_properties.mm +++ b/base/mac/objc_release_properties.mm
@@ -45,9 +45,7 @@ } // namespace -namespace base { -namespace mac { -namespace details { +namespace base::mac::details { void ReleaseProperties(id self, Class cls) { unsigned int property_count; @@ -61,6 +59,4 @@ } } -} // namespace details -} // namespace mac -} // namespace base +} // namespace base::mac::details
diff --git a/base/mac/os_crash_dumps.cc b/base/mac/os_crash_dumps.cc index d105ec1..616b9b9 100644 --- a/base/mac/os_crash_dumps.cc +++ b/base/mac/os_crash_dumps.cc
@@ -11,8 +11,7 @@ #include "base/cxx17_backports.h" #include "base/logging.h" -namespace base { -namespace mac { +namespace base::mac { namespace { @@ -57,5 +56,4 @@ } } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/os_crash_dumps.h b/base/mac/os_crash_dumps.h index 31d90fb..52ae454 100644 --- a/base/mac/os_crash_dumps.h +++ b/base/mac/os_crash_dumps.h
@@ -7,8 +7,7 @@ #include "base/base_export.h" -namespace base { -namespace mac { +namespace base::mac { // On Mac OS X, it can take a really long time for the OS crash handler to // process a Chrome crash when debugging symbols are available. This @@ -16,7 +15,6 @@ // disables Apple Crash Reporter entirely. BASE_EXPORT void DisableOSCrashDumps(); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_OS_CRASH_DUMPS_H_
diff --git a/base/mac/scoped_aedesc.h b/base/mac/scoped_aedesc.h index 61280c7..1ccc55e2 100644 --- a/base/mac/scoped_aedesc.h +++ b/base/mac/scoped_aedesc.h
@@ -7,8 +7,7 @@ #import <CoreServices/CoreServices.h> -namespace base { -namespace mac { +namespace base::mac { // The ScopedAEDesc is used to scope AppleEvent descriptors. On creation, // it will store a NULL descriptor. On destruction, it will dispose of the @@ -45,7 +44,6 @@ AEDescType desc_; }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_AEDESC_H_
diff --git a/base/mac/scoped_authorizationref.h b/base/mac/scoped_authorizationref.h index 78a864c..b3084b8 100644 --- a/base/mac/scoped_authorizationref.h +++ b/base/mac/scoped_authorizationref.h
@@ -13,8 +13,7 @@ // ScopedAuthorizationRef maintains ownership of an AuthorizationRef. It is // patterned after the unique_ptr interface. -namespace base { -namespace mac { +namespace base::mac { class BASE_EXPORT ScopedAuthorizationRef { public: @@ -84,7 +83,6 @@ AuthorizationRef authorization_; }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_AUTHORIZATIONREF_H_
diff --git a/base/mac/scoped_authorizationref.mm b/base/mac/scoped_authorizationref.mm index 68cbc1a9..dd264c1 100644 --- a/base/mac/scoped_authorizationref.mm +++ b/base/mac/scoped_authorizationref.mm
@@ -4,12 +4,10 @@ #include "base/mac/scoped_authorizationref.h" -namespace base { -namespace mac { +namespace base::mac { void ScopedAuthorizationRef::FreeInternal() { AuthorizationFree(authorization_, kAuthorizationFlagDestroyRights); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_block.h b/base/mac/scoped_block.h index 4011f9ab..8f64e57f 100644 --- a/base/mac/scoped_block.h +++ b/base/mac/scoped_block.h
@@ -13,8 +13,7 @@ #error "Cannot include base/mac/scoped_block.h in file built with ARC." #endif -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -32,7 +31,6 @@ template <typename B> using ScopedBlock = ScopedTypeRef<B, internal::ScopedBlockTraits<B>>; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_BLOCK_H_
diff --git a/base/mac/scoped_cffiledescriptorref.h b/base/mac/scoped_cffiledescriptorref.h index 923a159c..dfea944 100644 --- a/base/mac/scoped_cffiledescriptorref.h +++ b/base/mac/scoped_cffiledescriptorref.h
@@ -9,8 +9,7 @@ #include "base/scoped_generic.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -33,7 +32,6 @@ ScopedGeneric<CFFileDescriptorRef, internal::ScopedCFFileDescriptorRefTraits>; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_CFFILEDESCRIPTORREF_H_
diff --git a/base/mac/scoped_ionotificationportref.h b/base/mac/scoped_ionotificationportref.h index 93ebc98..1c4fc5e 100644 --- a/base/mac/scoped_ionotificationportref.h +++ b/base/mac/scoped_ionotificationportref.h
@@ -9,8 +9,7 @@ #include "base/scoped_generic.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -27,7 +26,6 @@ ScopedGeneric<IONotificationPortRef, internal::ScopedIONotificationPortRefTraits>; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_IONOTIFICATIONPORTREF_H_
diff --git a/base/mac/scoped_ioobject.h b/base/mac/scoped_ioobject.h index d656175..70c5b94e 100644 --- a/base/mac/scoped_ioobject.h +++ b/base/mac/scoped_ioobject.h
@@ -9,8 +9,7 @@ #include "base/mac/scoped_typeref.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -30,7 +29,6 @@ template <typename IOT> using ScopedIOObject = ScopedTypeRef<IOT, internal::ScopedIOObjectTraits<IOT>>; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_IOOBJECT_H_
diff --git a/base/mac/scoped_ioplugininterface.h b/base/mac/scoped_ioplugininterface.h index 872da8e..0e03cb44 100644 --- a/base/mac/scoped_ioplugininterface.h +++ b/base/mac/scoped_ioplugininterface.h
@@ -9,8 +9,7 @@ #include "base/mac/scoped_typeref.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -32,7 +31,6 @@ using ScopedIOPluginInterface = ScopedTypeRef<T**, internal::ScopedIOPluginInterfaceTraits<T**>>; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_IOPLUGININTERFACE_H_
diff --git a/base/mac/scoped_launch_data.h b/base/mac/scoped_launch_data.h index e7ef0a8..250e875 100644 --- a/base/mac/scoped_launch_data.h +++ b/base/mac/scoped_launch_data.h
@@ -14,8 +14,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -30,8 +29,7 @@ using ScopedLaunchData = ScopedGeneric<launch_data_t, internal::ScopedLaunchDataTraits>; -} // namespace mac -} // namespace base +} // namespace base::mac #pragma clang diagnostic pop // -Wdeprecated-declarations
diff --git a/base/mac/scoped_mach_port.cc b/base/mac/scoped_mach_port.cc index da6c20f..0a3214c 100644 --- a/base/mac/scoped_mach_port.cc +++ b/base/mac/scoped_mach_port.cc
@@ -6,8 +6,7 @@ #include "base/mac/mach_logging.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { // static @@ -72,5 +71,4 @@ return {}; } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_mach_port.h b/base/mac/scoped_mach_port.h index 04a264f..e0818f1a 100644 --- a/base/mac/scoped_mach_port.h +++ b/base/mac/scoped_mach_port.h
@@ -11,8 +11,7 @@ #include "base/scoped_generic.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace base { -namespace mac { +namespace base::mac { namespace internal { @@ -75,7 +74,6 @@ // a new scoper to manage the additional right. BASE_EXPORT ScopedMachSendRight RetainMachSendRight(mach_port_t port); -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_MACH_PORT_H_
diff --git a/base/mac/scoped_mach_vm.cc b/base/mac/scoped_mach_vm.cc index a76044d..bc82e36f 100644 --- a/base/mac/scoped_mach_vm.cc +++ b/base/mac/scoped_mach_vm.cc
@@ -6,8 +6,7 @@ #include "base/mac/mach_logging.h" -namespace base { -namespace mac { +namespace base::mac { void ScopedMachVM::reset(vm_address_t address, vm_size_t size) { DCHECK_EQ(address % PAGE_SIZE, 0u); @@ -34,5 +33,4 @@ size_ = size; } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_mach_vm.h b/base/mac/scoped_mach_vm.h index 4ef9a8b..e9fb26c 100644 --- a/base/mac/scoped_mach_vm.h +++ b/base/mac/scoped_mach_vm.h
@@ -43,8 +43,7 @@ // } // ScopedMachVM vm_owner(address, mach_vm_round_page(size)); -namespace base { -namespace mac { +namespace base::mac { class BASE_EXPORT ScopedMachVM { public: @@ -96,7 +95,6 @@ vm_size_t size_; }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_MACH_VM_H_
diff --git a/base/mac/scoped_mach_vm_unittest.cc b/base/mac/scoped_mach_vm_unittest.cc index faeccfd..ed78305 100644 --- a/base/mac/scoped_mach_vm_unittest.cc +++ b/base/mac/scoped_mach_vm_unittest.cc
@@ -17,8 +17,7 @@ // allocation will report being part of the previously-deallocated large region. // That will cause the GetRegionInfo() expectations to fail. -namespace base { -namespace mac { +namespace base::mac { namespace { void GetRegionInfo(vm_address_t* region_address, vm_size_t* region_size) { @@ -230,5 +229,4 @@ #endif // DCHECK_IS_ON() } // namespace -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_nsautorelease_pool.h b/base/mac/scoped_nsautorelease_pool.h index e737bff..58b6024 100644 --- a/base/mac/scoped_nsautorelease_pool.h +++ b/base/mac/scoped_nsautorelease_pool.h
@@ -13,8 +13,7 @@ class NSAutoreleasePool; #endif // __OBJC__ -namespace base { -namespace mac { +namespace base::mac { // ScopedNSAutoreleasePool allocates an NSAutoreleasePool when instantiated and // sends it a -drain message when destroyed. This allows an autorelease pool to @@ -41,7 +40,6 @@ NSAutoreleasePool* autorelease_pool_; }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_NSAUTORELEASE_POOL_H_
diff --git a/base/mac/scoped_nsautorelease_pool.mm b/base/mac/scoped_nsautorelease_pool.mm index 48f1038..65af53a 100644 --- a/base/mac/scoped_nsautorelease_pool.mm +++ b/base/mac/scoped_nsautorelease_pool.mm
@@ -8,8 +8,7 @@ #include "base/check.h" -namespace base { -namespace mac { +namespace base::mac { ScopedNSAutoreleasePool::ScopedNSAutoreleasePool() : autorelease_pool_([[NSAutoreleasePool alloc] init]) { @@ -28,5 +27,4 @@ DCHECK(autorelease_pool_); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_objc_class_swizzler.h b/base/mac/scoped_objc_class_swizzler.h index fe1d822..18e59aa 100644 --- a/base/mac/scoped_objc_class_swizzler.h +++ b/base/mac/scoped_objc_class_swizzler.h
@@ -9,8 +9,7 @@ #include "base/base_export.h" -namespace base { -namespace mac { +namespace base::mac { // Within a given scope, swaps method implementations of a class interface, or // between two class interfaces. The argument and return types must match. @@ -53,7 +52,6 @@ Method new_selector_impl_; }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_OBJC_CLASS_SWIZZLER_H_
diff --git a/base/mac/scoped_objc_class_swizzler.mm b/base/mac/scoped_objc_class_swizzler.mm index cfb92ba..b06a758 100644 --- a/base/mac/scoped_objc_class_swizzler.mm +++ b/base/mac/scoped_objc_class_swizzler.mm
@@ -8,8 +8,7 @@ #include "base/check_op.h" -namespace base { -namespace mac { +namespace base::mac { ScopedObjCClassSwizzler::ScopedObjCClassSwizzler(Class target, Class source, @@ -67,5 +66,4 @@ method_exchangeImplementations(old_selector_impl_, new_selector_impl_); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_objc_class_swizzler_unittest.mm b/base/mac/scoped_objc_class_swizzler_unittest.mm index 3aa5e9e..f21d5be 100644 --- a/base/mac/scoped_objc_class_swizzler_unittest.mm +++ b/base/mac/scoped_objc_class_swizzler_unittest.mm
@@ -73,8 +73,7 @@ } @end -namespace base { -namespace mac { +namespace base::mac { TEST(ObjCClassSwizzlerTest, SwizzleInstanceMethods) { base::scoped_nsobject<ObjCClassSwizzlerTestOne> object_one( @@ -155,5 +154,4 @@ EXPECT_EQ(3, [child method]); } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/mac/scoped_sending_event.h b/base/mac/scoped_sending_event.h index 61df542..71486263 100644 --- a/base/mac/scoped_sending_event.h +++ b/base/mac/scoped_sending_event.h
@@ -24,8 +24,7 @@ - (void)setHandlingSendEvent:(BOOL)handlingSendEvent; @end -namespace base { -namespace mac { +namespace base::mac { class BASE_EXPORT ScopedSendingEvent { public: @@ -43,7 +42,6 @@ BOOL handling_; // Value of -[app_ handlingSendEvent] at construction. }; -} // namespace mac -} // namespace base +} // namespace base::mac #endif // BASE_MAC_SCOPED_SENDING_EVENT_H_
diff --git a/base/mac/scoped_sending_event.mm b/base/mac/scoped_sending_event.mm index 35a3a43c..9d7c01c 100644 --- a/base/mac/scoped_sending_event.mm +++ b/base/mac/scoped_sending_event.mm
@@ -6,8 +6,7 @@ #include "base/check.h" -namespace base { -namespace mac { +namespace base::mac { ScopedSendingEvent::ScopedSendingEvent() : app_(static_cast<NSObject<CrAppControlProtocol>*>(NSApp)) { @@ -20,5 +19,4 @@ [app_ setHandlingSendEvent:handling_]; } -} // namespace mac -} // namespace base +} // namespace base::mac
diff --git a/base/memory/raw_ptr.cc b/base/memory/raw_ptr.cc index 3419330..41f8f04 100644 --- a/base/memory/raw_ptr.cc +++ b/base/memory/raw_ptr.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/memory/raw_ptr.h" +#include <cstdint> #include "base/allocator/buildflags.h" @@ -25,7 +26,7 @@ #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) CHECK(IsManagedByPartitionAllocBRPPool(address)); #endif - void* slot_start = PartitionAllocGetSlotStartInBRPPool(address); + uintptr_t slot_start = PartitionAllocGetSlotStartInBRPPool(address); PartitionRefCountPointer(slot_start)->Acquire(); } @@ -33,7 +34,7 @@ #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) CHECK(IsManagedByPartitionAllocBRPPool(address)); #endif - void* slot_start = PartitionAllocGetSlotStartInBRPPool(address); + uintptr_t slot_start = PartitionAllocGetSlotStartInBRPPool(address); if (PartitionRefCountPointer(slot_start)->Release()) PartitionAllocFreeForRefCounting(slot_start); } @@ -42,7 +43,7 @@ #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) CHECK(IsManagedByPartitionAllocBRPPool(address)); #endif - void* slot_start = PartitionAllocGetSlotStartInBRPPool(address); + uintptr_t slot_start = PartitionAllocGetSlotStartInBRPPool(address); return PartitionRefCountPointer(slot_start)->IsAlive(); }
diff --git a/base/memory/tagging.h b/base/memory/tagging.h index b67dd90..c64fee44f 100644 --- a/base/memory/tagging.h +++ b/base/memory/tagging.h
@@ -9,6 +9,7 @@ // extension. #include <stddef.h> #include <stdint.h> +#include <cstdint> #include "base/base_export.h" #include "base/compiler_specific.h" #include "build/build_config.h" @@ -69,6 +70,7 @@ // solution should be good enough for fuzzing/debug, ideally needs fixing for // async deployment on end-user devices. namespace internal { +// TODO(bartekn): void* -> uintptr_t using RemaskPtrInternalFn = void*(void* ptr); using TagMemoryRangeIncrementInternalFn = void*(void* ptr, size_t size); @@ -85,6 +87,7 @@ // Increments the tag of the memory range ptr. Useful for provable revocations // (e.g. free). Returns the pointer with the new tag. Ensures that the entire // range is set to the same tag. +// TODO(bartekn): Remove the T* variant. template <typename T> ALWAYS_INLINE T* TagMemoryRangeIncrement(T* ptr, size_t size) { #if defined(HAS_MEMORY_TAGGING) @@ -94,10 +97,15 @@ return ptr; #endif } +ALWAYS_INLINE uintptr_t TagMemoryRangeIncrement(uintptr_t ptr, size_t size) { + return reinterpret_cast<uintptr_t>( + TagMemoryRangeIncrement(reinterpret_cast<void*>(ptr), size)); +} // Randomly changes the tag of the ptr memory range. Useful for initial random // initialization. Returns the pointer with the new tag. Ensures that the entire // range is set to the same tag. +// TODO(bartekn): Remove the T* variant. template <typename T> ALWAYS_INLINE T* TagMemoryRangeRandomly(T* ptr, size_t size, @@ -109,8 +117,15 @@ return ptr; #endif } +ALWAYS_INLINE uintptr_t TagMemoryRangeRandomly(uintptr_t ptr, + size_t size, + uint64_t mask = 0u) { + return reinterpret_cast<uintptr_t>( + TagMemoryRangeRandomly(reinterpret_cast<void*>(ptr), size, mask)); +} // Gets a version of ptr that's safe to dereference. +// TODO(bartekn): Remove the T* variant. template <typename T> ALWAYS_INLINE T* RemaskPtr(T* ptr) { #if defined(HAS_MEMORY_TAGGING) @@ -119,16 +134,22 @@ return ptr; #endif } - -ALWAYS_INLINE uintptr_t UnmaskPtr(uintptr_t ptr) { -#if defined(HAS_MEMORY_TAGGING) - return ptr & kMemTagUnmask; -#else - return ptr; -#endif +// Gets a version of address that's safe to dereference, if cast to a pointer. +ALWAYS_INLINE uintptr_t RemaskPtr(uintptr_t address) { + return reinterpret_cast<uintptr_t>( + RemaskPtr(reinterpret_cast<void*>(address))); } +// Strips the tag bits off address. +ALWAYS_INLINE uintptr_t UnmaskPtr(uintptr_t address) { +#if defined(HAS_MEMORY_TAGGING) + return address & kMemTagUnmask; +#else + return address; +#endif +} // Strips the tag bits off ptr. +// TODO(bartekn): Remove the T* variant. template <typename T> ALWAYS_INLINE T* UnmaskPtr(T* ptr) { return reinterpret_cast<T*>(UnmaskPtr(reinterpret_cast<uintptr_t>(ptr)));
diff --git a/base/memory/values_equivalent.h b/base/memory/values_equivalent.h new file mode 100644 index 0000000..c63c058 --- /dev/null +++ b/base/memory/values_equivalent.h
@@ -0,0 +1,64 @@ +// Copyright 2022 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 BASE_MEMORY_VALUES_EQUIVALENT_H_ +#define BASE_MEMORY_VALUES_EQUIVALENT_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" + +namespace base { + +// Compares two pointers for equality, returns the dereferenced value comparison +// if both are non-null. +// Behaves like std::optional<T>::operator==(const std::optional<T>&) but for +// pointers. +template <typename T> +bool ValuesEquivalent(const T* a, const T* b) { + if (a == b) + return true; + if (!a || !b) + return false; + return *a == *b; +} + +// Specialize for smart pointers like std::unique_ptr and base::scoped_refptr +// that provide a T* get() method. +// Example usage: +// struct Example { +// std::unique_ptr<Child> child; +// bool operator(const Example& other) { +// return base::ValuesEquivalent(child, other.child); +// } +// }; +template <typename T, + std::enable_if_t< + std::is_pointer_v<decltype(std::declval<T>().get())>>* = nullptr> +bool ValuesEquivalent(const T& x, const T& y) { + return ValuesEquivalent(x.get(), y.get()); +} + +// Specialize for smart pointers like blink::Persistent and blink::Member that +// provide a T* Get() method. +// Example usage: +// namespace blink { +// struct Example : public GarbageCollected<Example> { +// Member<Child> child; +// bool operator(const Example& other) { +// return base::ValuesEquivalent(child, other.child); +// } +// void Trace(Visitor*) const; +// }; +// } // namespace blink +template <typename T, + std::enable_if_t< + std::is_pointer_v<decltype(std::declval<T>().Get())>>* = nullptr> +bool ValuesEquivalent(const T& x, const T& y) { + return ValuesEquivalent(x.Get(), y.Get()); +} + +} // namespace base + +#endif // BASE_MEMORY_VALUES_EQUIVALENT_H_
diff --git a/base/memory/values_equivalent_unittest.cc b/base/memory/values_equivalent_unittest.cc new file mode 100644 index 0000000..e849b62 --- /dev/null +++ b/base/memory/values_equivalent_unittest.cc
@@ -0,0 +1,97 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/values_equivalent.h" + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +TEST(ValuesEquivalentTest, Comparisons) { + int a = 1234; + int b1 = 5678; + int b2 = 5678; + + EXPECT_TRUE(ValuesEquivalent<int>(nullptr, nullptr)); + EXPECT_FALSE(ValuesEquivalent<int>(&a, nullptr)); + EXPECT_FALSE(ValuesEquivalent<int>(nullptr, &a)); + EXPECT_FALSE(ValuesEquivalent(&a, &b1)); + EXPECT_TRUE(ValuesEquivalent(&a, &a)); + EXPECT_TRUE(ValuesEquivalent(&b1, &b2)); +} + +TEST(ValuesEquivalentTest, UniquePtr) { + auto a = std::make_unique<int>(1234); + auto b1 = std::make_unique<int>(5678); + auto b2 = std::make_unique<int>(5678); + + EXPECT_TRUE(ValuesEquivalent(std::unique_ptr<int>(), std::unique_ptr<int>())); + EXPECT_FALSE(ValuesEquivalent(a, std::unique_ptr<int>())); + EXPECT_FALSE(ValuesEquivalent(std::unique_ptr<int>(), a)); + EXPECT_FALSE(ValuesEquivalent(a, b1)); + EXPECT_TRUE(ValuesEquivalent(a, a)); + EXPECT_TRUE(ValuesEquivalent(b1, b2)); +} + +TEST(ValuesEquivalentTest, ScopedRefPtr) { + struct Wrapper : public RefCounted<Wrapper> { + explicit Wrapper(int value) : value(value) {} + int value; + bool operator==(const Wrapper& other) const { return value == other.value; } + + protected: + friend class RefCounted<Wrapper>; + virtual ~Wrapper() = default; + }; + + auto a = MakeRefCounted<Wrapper>(1234); + auto b1 = MakeRefCounted<Wrapper>(5678); + auto b2 = MakeRefCounted<Wrapper>(5678); + + EXPECT_TRUE( + ValuesEquivalent(scoped_refptr<Wrapper>(), scoped_refptr<Wrapper>())); + EXPECT_FALSE(ValuesEquivalent(a, scoped_refptr<Wrapper>())); + EXPECT_FALSE(ValuesEquivalent(scoped_refptr<Wrapper>(), a)); + EXPECT_FALSE(ValuesEquivalent(a, b1)); + EXPECT_TRUE(ValuesEquivalent(a, a)); + EXPECT_TRUE(ValuesEquivalent(b1, b2)); +} + +TEST(ValuesEquivalentTest, CapitalGetPtr) { + class IntPointer { + public: + explicit IntPointer(int* pointer) : pointer_(pointer) {} + const int* Get() const { return pointer_; } + + private: + int* pointer_ = nullptr; + }; + + auto a = 1234; + auto b1 = 5678; + auto b2 = 5678; + + EXPECT_TRUE(ValuesEquivalent(IntPointer(nullptr), IntPointer(nullptr))); + EXPECT_FALSE(ValuesEquivalent(IntPointer(&a), IntPointer(nullptr))); + EXPECT_FALSE(ValuesEquivalent(IntPointer(nullptr), IntPointer(&a))); + EXPECT_FALSE(ValuesEquivalent(IntPointer(&a), IntPointer(&b1))); + EXPECT_TRUE(ValuesEquivalent(IntPointer(&a), IntPointer(&a))); + EXPECT_TRUE(ValuesEquivalent(IntPointer(&b1), IntPointer(&b2))); +} + +TEST(ValuesEquivalentTest, BypassEqualsOperator) { + struct NeverEqual { + bool operator==(const NeverEqual& other) const { return false; } + } a, b; + + ASSERT_FALSE(a == a); + ASSERT_FALSE(a == b); + + EXPECT_TRUE(ValuesEquivalent(&a, &a)); + EXPECT_FALSE(ValuesEquivalent(&a, &b)); +} + +} // namespace base
diff --git a/base/message_loop/message_pump_glib.cc b/base/message_loop/message_pump_glib.cc index 81c9ecc..1398900 100644 --- a/base/message_loop/message_pump_glib.cc +++ b/base/message_loop/message_pump_glib.cc
@@ -13,6 +13,7 @@ #include "base/numerics/safe_conversions.h" #include "base/posix/eintr_wrapper.h" #include "base/synchronization/lock.h" +#include "base/threading/platform_thread.h" namespace base {
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 5b6ad6a..63911f0 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -188,6 +188,7 @@ class SynchronousCompositorSyncCallBridge; class TextInputClientMac; class WaitForProcessesToDumpProfilingInfo; +class WebContentsImpl; class WebContentsViewMac; } // namespace content namespace cronet { @@ -449,6 +450,9 @@ friend class content::RenderProcessHostImpl; friend class content::RenderWidgetHostViewMac; // http://crbug.com/121917 friend class content::ShellPathProvider; +#if defined(OS_WIN) + friend class content::WebContentsImpl; // http://crbug.com/1262162 +#endif friend class content::WebContentsViewMac; friend class cronet::CronetPrefsManager; friend class cronet::CronetURLRequestContext;
diff --git a/base/time/time.h b/base/time/time.h index e6ba333a..c3df44b 100644 --- a/base/time/time.h +++ b/base/time/time.h
@@ -1055,7 +1055,10 @@ #if defined(OS_MAC) static TimeTicks FromMachAbsoluteTime(uint64_t mach_absolute_time); - static mach_timebase_info_data_t* MachTimebaseInfoForTesting(); + // Sets the current Mach timebase to `timebase`. Returns the old timebase. + static mach_timebase_info_data_t SetMachTimebaseInfoForTesting( + mach_timebase_info_data_t timebase); + #endif // defined(OS_MAC) #if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/base/time/time_mac.mm b/base/time/time_mac.mm index d3cea2e..fc339ce2 100644 --- a/base/time/time_mac.mm +++ b/base/time/time_mac.mm
@@ -33,7 +33,7 @@ #if defined(OS_MAC) // Returns a pointer to the initialized Mach timebase info struct. -mach_timebase_info_data_t* MachTimebaseInfoInternal() { +mach_timebase_info_data_t* MachTimebaseInfo() { static mach_timebase_info_data_t timebase_info = []() { mach_timebase_info_data_t info; kern_return_t kr = mach_timebase_info(&info); @@ -48,7 +48,7 @@ int64_t MachTimeToMicroseconds(uint64_t mach_time) { // timebase_info gives us the conversion factor between absolute time tick // units and nanoseconds. - mach_timebase_info_data_t* timebase_info = MachTimebaseInfoInternal(); + mach_timebase_info_data_t* timebase_info = MachTimebaseInfo(); // Take the fast path when the conversion is 1:1. The result will for sure fit // into an int_64 because we're going from nanoseconds to microseconds. @@ -57,22 +57,32 @@ base::Time::kNanosecondsPerMicrosecond); } - // If there isn't a 1:1 conversion, divide first to reduce the chance of - // overflow. - uint64_t microseconds = mach_time / (timebase_info->denom * - base::Time::kNanosecondsPerMicrosecond); + uint64_t microseconds = 0; + const uint64_t divisor = + timebase_info->denom * base::Time::kNanosecondsPerMicrosecond; - // Only multiply if numer is something other than unity. - if (timebase_info->numer != 1) { - CHECK(!__builtin_umulll_overflow(microseconds, timebase_info->numer, - µseconds)); - } + // Microseconds is mach_time * timebase.numer / + // (timebase.denom * kNanosecondsPerMicrosecond). Divide first to reduce + // the chance of overflow. Also stash the remainder right now, a likely + // byproduct of the division. + microseconds = mach_time / divisor; + const uint64_t mach_time_remainder = mach_time % divisor; - // Don't bother with the rollover handling that the Windows version does. On - // Intel we expect numer == denom == 1, in which case the 64-bit absolute time - // reported in nanoseconds is enough to last nearly 585 years. For M1 - // we can expect each tick to be about 42 nanoseconds which is almost - // 24,565 years of headroom. + // Now multiply, keeping an eye out for overflow. + CHECK(!__builtin_umulll_overflow(microseconds, timebase_info->numer, + µseconds)); + + // By dividing first we lose precision. Regain it by adding back the + // microseconds from the remainder, with an eye out for overflow. + uint64_t least_significant_microseconds = + (mach_time_remainder * timebase_info->numer) / divisor; + CHECK(!__builtin_uaddll_overflow(microseconds, least_significant_microseconds, + µseconds)); + + // Don't bother with the rollover handling that the Windows version does. + // The returned time in microseconds is enough for 292,277 years (starting + // from 2^63 because the returned int64_t is signed, + // 9223372036854775807 / (1e6 * 60 * 60 * 24 * 365.2425) = 292,277). return base::checked_cast<int64_t>(microseconds); } #endif // defined(OS_MAC) @@ -232,9 +242,15 @@ } // static -mach_timebase_info_data_t* TimeTicks::MachTimebaseInfoForTesting() { - return MachTimebaseInfoInternal(); +mach_timebase_info_data_t TimeTicks::SetMachTimebaseInfoForTesting( + mach_timebase_info_data_t timebase) { + mach_timebase_info_data_t orig_timebase = *MachTimebaseInfo(); + + *MachTimebaseInfo() = timebase; + + return orig_timebase; } + #endif // defined(OS_MAC) // static
diff --git a/base/time/time_mac_unittest.mm b/base/time/time_mac_unittest.mm index ed52479..5c9e8a3 100644 --- a/base/time/time_mac_unittest.mm +++ b/base/time/time_mac_unittest.mm
@@ -10,10 +10,8 @@ namespace { class ScopedTimebase { public: - ScopedTimebase(mach_timebase_info_data_t timebase) - : orig_timebase_(*base::TimeTicks::MachTimebaseInfoForTesting()) { - base::TimeTicks::MachTimebaseInfoForTesting()->numer = timebase.numer; - base::TimeTicks::MachTimebaseInfoForTesting()->denom = timebase.denom; + ScopedTimebase(mach_timebase_info_data_t timebase) { + orig_timebase_ = base::TimeTicks::SetMachTimebaseInfoForTesting(timebase); } ScopedTimebase(const ScopedTimebase&) = delete; @@ -21,7 +19,7 @@ ScopedTimebase& operator=(const ScopedTimebase&) = delete; ~ScopedTimebase() { - *base::TimeTicks::MachTimebaseInfoForTesting() = orig_timebase_; + base::TimeTicks::SetMachTimebaseInfoForTesting(orig_timebase_); } private: @@ -110,25 +108,77 @@ ScopedTimebase timebase({kArbitraryNumer, 1}); // Expect an overflow. - EXPECT_CHECK_DEATH(TimeDelta::FromMachTime(ULLONG_MAX)); + EXPECT_CHECK_DEATH( + TimeDelta::FromMachTime(std::numeric_limits<uint64_t>::max())); } // Tests that there's no overflow in MachTimeToMicroseconds even with -// ULLONG_MAX ticks on Intel. +// std::numeric_limits<uint64_t>::max() ticks on Intel. TEST(TimeMacTest, MachTimeToMicrosecondsNoOverflowIntel) { ScopedTimebase timebase(kIntelTimebase); - // Don't expect an overflow. - TimeDelta::FromMachTime(ULLONG_MAX); + // The incoming Mach time ticks are on the order of nanoseconds while the + // return result is microseconds. Even though we're passing in the largest + // tick count the result should be orders of magnitude smaller. On Intel the + // mapping from ticks to nanoseconds is 1:1 so we wouldn't ever expect an + // overflow when applying the timebase conversion. + TimeDelta::FromMachTime(std::numeric_limits<uint64_t>::max()); } // Tests that there's no overflow in MachTimeToMicroseconds even with -// ULLONG_MAX ticks on M1. +// std::numeric_limits<uint64_t>::max() ticks on M1. TEST(TimeMacTest, MachTimeToMicrosecondsNoOverflowM1) { ScopedTimebase timebase(kM1Timebase); - // Don't expect an overflow. - TimeDelta::FromMachTime(ULLONG_MAX); + // The incoming Mach time ticks are on the order of nanoseconds while the + // return result is microseconds. Even though we're passing in the largest + // tick count the result should be orders of magnitude smaller. Expect that + // FromMachTime(), when applying the timebase conversion, is smart enough to + // not multiply first and generate an overflow. + TimeDelta::FromMachTime(std::numeric_limits<uint64_t>::max()); } + +// Tests that there's no underflow in MachTimeToMicroseconds on Intel. +TEST(TimeMacTest, MachTimeToMicrosecondsNoUnderflowIntel) { + ScopedTimebase timebase(kIntelTimebase); + + // On Intel the timebase conversion is 1:1, so min ticks is one microsecond + // worth of nanoseconds. + const uint64_t kMinimumTicks = base::Time::kNanosecondsPerMicrosecond; + const uint64_t kOneMicrosecond = 1; + EXPECT_EQ(kOneMicrosecond, + TimeDelta::FromMachTime(kMinimumTicks).InMicroseconds() * 1UL); + + // If we have even one fewer tick (i.e. not enough ticks to constitute a full + // microsecond) the integer rounding should result in 0 microseconds. + const uint64_t kZeroMicroseconds = 0; + EXPECT_EQ(kZeroMicroseconds, + TimeDelta::FromMachTime(kMinimumTicks - 1).InMicroseconds() * 1UL); +} + +// Tests that there's no underflow in MachTimeToMicroseconds for M1. +TEST(TimeMacTest, MachTimeToMicrosecondsNoUnderflowM1) { + ScopedTimebase timebase(kM1Timebase); + + // Microseconds is mach_time multiplied by kM1Timebase.numer / + // (kM1Timebase.denom * base::Time::kNanosecondsPerMicrosecond). Inverting + // that should be the minimum number of ticks to get a single microsecond in + // return. If we get zero it means an underflow in the conversion. For example + // if FromMachTime() first divides mach_time by kM1Timebase.denom * + // base::Time::kNanosecondsPerMicrosecond we'll get zero back. + const uint64_t kMinimumTicks = + (kM1Timebase.denom * base::Time::kNanosecondsPerMicrosecond) / + kM1Timebase.numer; + const uint64_t kOneMicrosecond = 1; + EXPECT_EQ(kOneMicrosecond, + TimeDelta::FromMachTime(kMinimumTicks).InMicroseconds() * 1UL); + + // If we have even one fewer tick (i.e. not enough ticks to constitute a full + // microsecond) the integer rounding should result in 0 microseconds. + const uint64_t kZeroMicroseconds = 0; + EXPECT_EQ(kZeroMicroseconds, + TimeDelta::FromMachTime(kMinimumTicks - 1).InMicroseconds() * 1UL); +} + } // namespace } // namespace base
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h index f6f346b..928b4a9 100644 --- a/base/trace_event/builtin_categories.h +++ b/base/trace_event/builtin_categories.h
@@ -248,6 +248,7 @@ X(TRACE_DISABLED_BY_DEFAULT("v8.gc")) \ X(TRACE_DISABLED_BY_DEFAULT("v8.gc_stats")) \ X(TRACE_DISABLED_BY_DEFAULT("v8.ic_stats")) \ + X(TRACE_DISABLED_BY_DEFAULT("v8.inspector")) \ X(TRACE_DISABLED_BY_DEFAULT("v8.runtime")) \ X(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats")) \ X(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats_sampling")) \
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc index f4de6ee..f06564c 100644 --- a/base/trace_event/malloc_dump_provider.cc +++ b/base/trace_event/malloc_dump_provider.cc
@@ -111,7 +111,8 @@ MemoryDumpLevelOfDetail level_of_detail, size_t* total_virtual_size, size_t* resident_size, - size_t* allocated_objects_size) { + size_t* allocated_objects_size, + uint64_t* syscall_count) { MemoryDumpPartitionStatsDumper partition_stats_dumper("malloc", pmd, level_of_detail); bool is_light_dump = level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND; @@ -141,6 +142,7 @@ *total_virtual_size += partition_stats_dumper.total_resident_bytes(); *resident_size += partition_stats_dumper.total_resident_bytes(); *allocated_objects_size += partition_stats_dumper.total_active_bytes(); + *syscall_count += partition_stats_dumper.syscall_count(); } #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) @@ -172,10 +174,14 @@ size_t resident_size = 0; size_t allocated_objects_size = 0; size_t allocated_objects_count = 0; +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + uint64_t syscall_count = 0; +#endif #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) ReportPartitionAllocStats(pmd, args.level_of_detail, &total_virtual_size, - &resident_size, &allocated_objects_size); + &resident_size, &allocated_objects_size, + &syscall_count); #if OS_WIN ReportWinHeapStats(args.level_of_detail, pmd, &total_virtual_size, @@ -264,6 +270,18 @@ resident_size - allocated_objects_size); } +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + uint64_t new_syscalls = syscall_count - last_syscall_count_; + base::TimeDelta time_since_last_dump = + base::TimeTicks::Now() - last_memory_dump_time_; + uint64_t syscalls_per_minute = static_cast<uint64_t>( + (60 * new_syscalls) / time_since_last_dump.InSecondsF()); + outer_dump->AddScalar("syscalls_per_minute", "count", syscalls_per_minute); + + last_memory_dump_time_ = base::TimeTicks::Now(); + last_syscall_count_ = syscall_count; +#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + return true; } @@ -294,6 +312,7 @@ total_mmapped_bytes_ += memory_stats->total_mmapped_bytes; total_resident_bytes_ += memory_stats->total_resident_bytes; total_active_bytes_ += memory_stats->total_active_bytes; + syscall_count_ += memory_stats->syscall_count; std::string dump_name = GetPartitionDumpName(root_name_, partition_name); MemoryAllocatorDump* allocator_dump =
diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h index e01678ae..d30b2266 100644 --- a/base/trace_event/malloc_dump_provider.h +++ b/base/trace_event/malloc_dump_provider.h
@@ -9,6 +9,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/singleton.h" #include "base/synchronization/lock.h" +#include "base/time/time.h" #include "base/trace_event/memory_dump_provider.h" #include "build/build_config.h" @@ -52,8 +53,17 @@ MallocDumpProvider(); ~MallocDumpProvider() override; - bool emit_metrics_on_memory_dump_ = true; + bool emit_metrics_on_memory_dump_ + GUARDED_BY(emit_metrics_on_memory_dump_lock_) = true; base::Lock emit_metrics_on_memory_dump_lock_; + +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + // To be accurate, this requires the dump provider to be created very early, + // which is the case. The alternative would be to drop the first data point, + // which is not desirable as early process activity is highly relevant. + base::TimeTicks last_memory_dump_time_ = base::TimeTicks::Now(); + uint64_t last_syscall_count_ = 0; +#endif }; #if BUILDFLAG(USE_PARTITION_ALLOC) @@ -82,6 +92,7 @@ size_t total_mmapped_bytes() const { return total_mmapped_bytes_; } size_t total_resident_bytes() const { return total_resident_bytes_; } size_t total_active_bytes() const { return total_active_bytes_; } + uint64_t syscall_count() const { return syscall_count_; } private: const char* root_name_; @@ -90,6 +101,7 @@ size_t total_mmapped_bytes_ = 0; size_t total_resident_bytes_ = 0; size_t total_active_bytes_ = 0; + uint64_t syscall_count_ = 0; bool detailed_; };
diff --git a/base/win/.clang-tidy b/base/win/.clang-tidy index d0f8c61..ad9da24 100644 --- a/base/win/.clang-tidy +++ b/base/win/.clang-tidy
@@ -4,6 +4,7 @@ google-build-namespaces, google-readability-namespace-comments, modernize-avoid-bind, + modernize-concat-nested-namespaces, modernize-make-shared, modernize-make-unique, modernize-redundant-void-arg,
diff --git a/build/android/pylib/local/emulator/avd.py b/build/android/pylib/local/emulator/avd.py index d4b45619..6a5a49ef 100644 --- a/build/android/pylib/local/emulator/avd.py +++ b/build/android/pylib/local/emulator/avd.py
@@ -16,6 +16,7 @@ from devil.android import device_utils from devil.android.sdk import adb_wrapper +from devil.android.tools import system_app from devil.utils import cmd_helper from devil.utils import timeout_retry from py_utils import tempfile_ext @@ -37,6 +38,12 @@ # Default to swiftshader_indirect since it works for most cases. _DEFAULT_GPU_MODE = 'swiftshader_indirect' +# The snapshot name to load/save when writable_system=False. +# This is the default name used by the emulator binary. +_DEFAULT_SNAPSHOT_NAME = 'default_boot' +# The snapshot name to load/save when writable_system=True +_SYSTEM_SNAPSHOT_NAME = 'boot_with_system' + class AvdException(Exception): """Raised when this module has a problem interacting with an AVD.""" @@ -195,6 +202,8 @@ force=False, snapshot=False, keep=False, + additional_apks=None, + privileged_apk_tuples=None, cipd_json_output=None, dry_run=False): """Create an instance of the AVD CIPD package. @@ -204,7 +213,8 @@ - creates the AVD - modifies the AVD's ini files to support running chromium tests in chromium infrastructure - - optionally starts & stops the AVD for snapshotting (default no) + - optionally starts, installs additional apks and/or privileged apks, and + stops the AVD for snapshotting (default no) - By default creates and uploads an instance of the AVD CIPD package (can be turned off by dry_run flag). - optionally deletes the AVD (default yes) @@ -215,6 +225,12 @@ the CIPD package. keep: bool indicating whether to keep the AVD after creating the CIPD package. + additional_apks: a list of strings contains the paths to the APKs. These + APKs will be installed after AVD is started. + privileged_apk_tuples: a list of (apk_path, device_partition) tuples where + |apk_path| is a string containing the path to the APK, and + |device_partition| is a string indicating the system image partition on + device that contains "priv-app" directory, e.g. "/system", "/product". cipd_json_output: string path to pass to `cipd create` via -json-output. dry_run: When set to True, it will skip the CIPD package creation after creating the AVD. @@ -282,28 +298,45 @@ self._config) # Enable debug for snapshot when it is set to True debug_tags = 'init,snapshot' if snapshot else None + # Installing privileged apks requires modifying the system image. + writable_system = bool(privileged_apk_tuples) instance.Start(read_only=False, - snapshot_save=snapshot, - debug_tags=debug_tags, - gpu_mode=_DEFAULT_GPU_MODE) + writable_system=writable_system, + gpu_mode=_DEFAULT_GPU_MODE, + debug_tags=debug_tags) + + assert instance.device is not None, '`instance.device` not initialized.' # Android devices with full-disk encryption are encrypted on first boot, # and then get decrypted to continue the boot process (See details in # https://bit.ly/3agmjcM). # Wait for this step to complete since it can take a while for old OSs # like M, otherwise the avd may have "Encryption Unsuccessful" error. - device = device_utils.DeviceUtils(instance.serial) - device.WaitUntilFullyBooted(decrypt=True, timeout=180, retries=0) + instance.device.WaitUntilFullyBooted(decrypt=True, timeout=180, retries=0) + + if additional_apks: + for additional_apk in additional_apks: + instance.device.Install(additional_apk, + allow_downgrade=True, + reinstall=True) + + if privileged_apk_tuples: + system_app.InstallPrivilegedApps(instance.device, privileged_apk_tuples) # Skip network disabling on pre-N for now since the svc commands fail # on Marshmallow. - if device.build_version_sdk > 23: + if instance.device.build_version_sdk > 23: # Always disable the network to prevent built-in system apps from # updating themselves, which could take over package manager and # cause shell command timeout. # Use svc as this also works on the images with build type "user". logging.info('Disabling the network in emulator.') - device.RunShellCommand(['svc', 'wifi', 'disable'], check_return=True) - device.RunShellCommand(['svc', 'data', 'disable'], check_return=True) + instance.device.RunShellCommand(['svc', 'wifi', 'disable'], + check_return=True) + instance.device.RunShellCommand(['svc', 'data', 'disable'], + check_return=True) + + if snapshot: + instance.SaveSnapshot() instance.Stop() @@ -532,20 +565,37 @@ self._emulator_path = emulator_path self._emulator_proc = None self._emulator_serial = None + self._emulator_device = None self._sink = None + self._writable_system = False + def __str__(self): return '%s|%s' % (self._avd_name, (self._emulator_serial or id(self))) def Start(self, read_only=True, - snapshot_save=False, window=False, writable_system=False, gpu_mode=_DEFAULT_GPU_MODE, wipe_data=False, debug_tags=None): """Starts the emulator running an instance of the given AVD.""" + # Force to load system snapshot if detected. + if self.HasSystemSnapshot(): + if not writable_system: + logging.info('System snapshot found. Set "writable_system=True" ' + 'to load it properly.') + writable_system = True + if read_only: + logging.info('System snapshot found. Set "read_only=False" ' + 'to load it properly.') + read_only = False + elif writable_system: + logging.warning('Emulator will be slow to start, as ' + '"writable_system=True" but system snapshot not found.') + + self._writable_system = writable_system with tempfile_ext.TemporaryFileName() as socket_path, (contextlib.closing( socket.socket(socket.AF_UNIX))) as sock: @@ -557,14 +607,17 @@ '-report-console', 'unix:%s' % socket_path, '-no-boot-anim', + # Explicitly prevent emulator from auto-saving to snapshot on exit. + '-no-snapshot-save', + # Explicitly set the snapshot name for auto-load + '-snapshot', + self.GetSnapshotName(), ] if wipe_data: emulator_cmd.append('-wipe-data') if read_only: emulator_cmd.append('-read-only') - if not snapshot_save: - emulator_cmd.append('-no-snapshot-save') if writable_system: emulator_cmd.append('-writable-system') # Note when "--gpu-mode" is set to "host": @@ -591,8 +644,11 @@ sock.listen(1) - logging.info('Starting emulator with commands: %s', - ' '.join(emulator_cmd)) + logging.info('Starting emulator...') + logging.info( + ' With environments: %s', + ' '.join(['%s=%s' % (k, v) for k, v in emulator_env.items()])) + logging.info(' With commands: %s', ' '.join(emulator_cmd)) # TODO(jbudorick): Add support for logging emulator stdout & stderr at # higher logging levels. @@ -624,17 +680,50 @@ """Stops the emulator process.""" if self._emulator_proc: if self._emulator_proc.poll() is None: - if self._emulator_serial: - device_utils.DeviceUtils(self._emulator_serial).adb.Emu('kill') + if self.device: + self.device.adb.Emu('kill') else: self._emulator_proc.terminate() self._emulator_proc.wait() self._emulator_proc = None + self._emulator_serial = None + self._emulator_device = None if self._sink: self._sink.close() self._sink = None + def GetSnapshotName(self): + """Return the snapshot name to load/save. + + Emulator has a different snapshot process when '-writable-system' flag is + set (See https://issuetracker.google.com/issues/135857816#comment8). + + """ + if self._writable_system: + return _SYSTEM_SNAPSHOT_NAME + + return _DEFAULT_SNAPSHOT_NAME + + def HasSystemSnapshot(self): + """Check if the instance has the snapshot named _SYSTEM_SNAPSHOT_NAME.""" + snapshot_path = os.path.join(self._emulator_home, 'avd', + '%s.avd' % self._avd_name, 'snapshots', + _SYSTEM_SNAPSHOT_NAME) + return os.path.exists(snapshot_path) + + def SaveSnapshot(self): + snapshot_name = self.GetSnapshotName() + if self.device: + logging.info('Saving snapshot to %r.', snapshot_name) + self.device.adb.Emu(['avd', 'snapshot', 'save', snapshot_name]) + @property def serial(self): return self._emulator_serial + + @property + def device(self): + if not self._emulator_device and self._emulator_serial: + self._emulator_device = device_utils.DeviceUtils(self._emulator_serial) + return self._emulator_device
diff --git a/build/cipd/cipd.gni b/build/cipd/cipd.gni index e7795c1..55701a48 100644 --- a/build/cipd/cipd.gni +++ b/build/cipd/cipd.gni
@@ -123,7 +123,7 @@ } action(target_name) { script = "//build/cipd/cipd_from_file.py" - inputs = [ "//build/cipd/cipd_from_file.py" ] + inputs = [ invoker.files_file ] args = [ "--description=" + invoker.description, "--buildtype=" + invoker.buildtype,
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 5ac1748..0ee70903 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -3696,21 +3696,6 @@ _public_deps = [] _analysis_public_deps = [] - _analysis_files = [] - - if (defined(invoker.proguard_configs)) { - assert(_build_host_jar || _build_device_jar) - - # proguard_configs listed on java_library targets need to be marked - # as inputs to at least one action so that "gn analyze" will know - # about them. Although this target doesn't use them, it's a convenient spot - # to list them. - # https://crbug.com/827197 - _analysis_files = invoker.proguard_configs - _analysis_public_deps = - _non_java_deps + _srcjar_deps # For the aapt-generated - # proguard rules. - } if (_has_sources) { if (defined(invoker.enable_errorprone)) { @@ -4026,6 +4011,19 @@ # the non-analysis steps of other targets that depend on this one. group("${target_name}__impl") { public_deps = _public_deps + + # proguard_configs listed on java_library targets need to be marked + # as inputs to at least one target so that "gn analyze" will know + # about them. Although this target doesn't use them, it's a convenient spot + # to list them. + # https://crbug.com/827197 + if (compute_inputs_for_analyze && defined(invoker.proguard_configs)) { + assert(_build_host_jar || _build_device_jar) + data = invoker.proguard_configs + + # For the aapt-generated proguard rules. + deps = _non_java_deps + _srcjar_deps + } } java_lib_group("${target_name}__assetres") { @@ -4051,10 +4049,6 @@ public_deps = [] } public_deps += [ ":${target_name}__impl" ] - if (!defined(data)) { - data = [] - } - data += _analysis_files if (!defined(data_deps)) { data_deps = [] }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index e45fa2c8..e49fc28 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1540,6 +1540,40 @@ } } +# prevent_unsafe_narrowing ---------------------------------------------------- +# +# Warnings that prevent narrowing or comparisons of integer types that are +# likely to cause out-of-bound read/writes or Undefined Behaviour. In +# particular, size_t is used for memory sizes, allocation, indexing, and +# offsets. Using other integer types along with size_t produces risk of +# memory-safety bugs and thus security exploits. +# +# In order to prevent these bugs, allocation sizes were historically limited to +# sizes that can be represented within 31 bits of information, allowing `int` to +# be safely misused instead of `size_t` (https://crbug.com/169327). In order to +# support increasing the allocation limit we require strictly adherence to +# using the correct types, avoiding lossy conversions, and preventing overflow. +# To do so, enable this config and fix errors by converting types to be +# `size_t`, which is both large enough and unsigned, when dealing with memory +# sizes, allocations, indices, or offsets.In cases where type conversion is not +# possible or is superfluous, use base::strict_cast<> or base::checked_cast<> +# to convert to size_t as needed. +# See also: https://docs.google.com/document/d/14yKUwDaorqqNfgdGqHY_nck2nn02XBQcB5N0ue4fax8 +# +# To enable in a GN target, use: +# configs += [ "//build/config/compiler:prevent_unsafe_narrowing" ] + +config("prevent_unsafe_narrowing") { + if (is_clang) { + cflags = [ + "-Wshorten-64-to-32", + "-Wimplicit-int-conversion", + "-Wsign-compare", + "-Wsign-conversion", + ] + } +} + # chromium_code --------------------------------------------------------------- # # Toggles between higher and lower warnings for code that is (or isn't)
diff --git a/build/fuchsia/binary_size_differ.py b/build/fuchsia/binary_size_differ.py index 2a72e43..7a656623 100755 --- a/build/fuchsia/binary_size_differ.py +++ b/build/fuchsia/binary_size_differ.py
@@ -29,7 +29,7 @@ from binary_sizes import GetPackageSizes, ReadPackageBlobsJson from binary_sizes import PACKAGES_SIZE_FILE -_MAX_DELTA_BYTES = 16 * 1024 # 16 KiB +_MAX_DELTA_BYTES = 12 * 1024 # 12 KiB def GetPackageBlobsFromFile(blob_file_path): @@ -55,7 +55,7 @@ growth['uncompressed'][package_name] = ( after_blobs[package_name].uncompressed - before_blobs[package_name].uncompressed) - if growth['compressed'][package_name] > _MAX_DELTA_BYTES: + if growth['compressed'][package_name] >= _MAX_DELTA_BYTES: if status_code == 1: summary = 'Failed! ' status_code = 1
diff --git a/build/fuchsia/binary_size_differ_test.py b/build/fuchsia/binary_size_differ_test.py index ee2fe95..a51aa6e4 100755 --- a/build/fuchsia/binary_size_differ_test.py +++ b/build/fuchsia/binary_size_differ_test.py
@@ -108,8 +108,7 @@ other_blobs = copy.deepcopy(blobs) # Increase the limit of is_counted=false does not increase limit. - self.ChangeBlobSize(other_blobs, 'web_engine', 'meta.far', - (16 * 1024 + 1)) + self.ChangeBlobSize(other_blobs, 'web_engine', 'meta.far', (16 * 1024)) binary_sizes.WritePackageBlobsJson(after_file.name, other_blobs) growth = binary_size_differ.ComputePackageDiffs(before_file.name, after_file.name)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 782d076..07264ab 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20220105.0.1 +7.20220106.3.1
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 2d83550..07264ab 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -7.20220105.1.1 +7.20220106.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 782d076..07264ab 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20220105.0.1 +7.20220106.3.1
diff --git a/build/lacros/test_runner.py b/build/lacros/test_runner.py index fd5a1ab..4ec763f 100755 --- a/build/lacros/test_runner.py +++ b/build/lacros/test_runner.py
@@ -420,7 +420,7 @@ '--user-data-dir=%s' % tmp_ash_data_dir_name, '--enable-wayland-server', '--no-startup-window', - '--enable-features=LacrosSupport', + '--enable-features=LacrosSupport,LacrosPrimary', '--ash-ready-file-path=%s' % ash_ready_file, ] if enable_mojo_crosapi:
diff --git a/build/lacros/test_runner_test.py b/build/lacros/test_runner_test.py index d71a8bb..93b4901 100755 --- a/build/lacros/test_runner_test.py +++ b/build/lacros/test_runner_test.py
@@ -79,7 +79,8 @@ 'build/lacros/prebuilt_ash_chrome/793554/test_ash_chrome')) expected_ash_chrome_args = [ '--user-data-dir=/tmp/ash-data', '--enable-wayland-server', - '--no-startup-window', '--enable-features=LacrosSupport', + '--no-startup-window', + '--enable-features=LacrosSupport,LacrosPrimary', '--ash-ready-file-path=/tmp/ash-data/ash_ready.txt' ] if command == 'lacros_chrome_browsertests':
diff --git a/build/skia_gold_common/PRESUBMIT.py b/build/skia_gold_common/PRESUBMIT.py index fd50874..14e0904 100644 --- a/build/skia_gold_common/PRESUBMIT.py +++ b/build/skia_gold_common/PRESUBMIT.py
@@ -24,8 +24,10 @@ output_api, input_api.PresubmitLocalPath(), [r'^.+_unittest\.py$'], env=skia_gold_env, + run_on_python2=not USE_PYTHON3, skip_shebang_check=True)) - output.extend(input_api.canned_checks.RunPylint(input_api, output_api)) + output.extend( + input_api.canned_checks.RunPylint(input_api, output_api, version='2.6')) return output
diff --git a/build/skia_gold_common/output_managerless_skia_gold_session.py b/build/skia_gold_common/output_managerless_skia_gold_session.py index a74b68f..7022394 100644 --- a/build/skia_gold_common/output_managerless_skia_gold_session.py +++ b/build/skia_gold_common/output_managerless_skia_gold_session.py
@@ -28,14 +28,13 @@ # Passing True for the output manager is a bit of a hack, as we don't # actually need an output manager and just need to get past the truthy # check. - return super(OutputManagerlessSkiaGoldSession, self).RunComparison( - name=name, - png_file=png_file, - output_manager=output_manager, - inexact_matching_args=inexact_matching_args, - use_luci=use_luci, - optional_keys=optional_keys, - force_dryrun=force_dryrun) + return super().RunComparison(name=name, + png_file=png_file, + output_manager=output_manager, + inexact_matching_args=inexact_matching_args, + use_luci=use_luci, + optional_keys=optional_keys, + force_dryrun=force_dryrun) def _CreateDiffOutputDir(self, name): # Do this instead of just making a temporary directory so that it's easier
diff --git a/build/skia_gold_common/skia_gold_properties.py b/build/skia_gold_common/skia_gold_properties.py index dffed26d..069cf9e 100644 --- a/build/skia_gold_common/skia_gold_properties.py +++ b/build/skia_gold_common/skia_gold_properties.py
@@ -13,7 +13,7 @@ import os -class SkiaGoldProperties(object): +class SkiaGoldProperties(): def __init__(self, args): """Abstract class to validate and store properties related to Skia Gold.
diff --git a/build/skia_gold_common/skia_gold_session.py b/build/skia_gold_common/skia_gold_session.py index 5683b772..188209f4 100644 --- a/build/skia_gold_common/skia_gold_session.py +++ b/build/skia_gold_common/skia_gold_session.py
@@ -27,8 +27,8 @@ GOLDCTL_BINARY = os.path.join(GOLDCTL_BINARY, 'linux', 'goldctl') -class SkiaGoldSession(object): - class StatusCodes(object): +class SkiaGoldSession(): + class StatusCodes(): """Status codes for RunComparison.""" SUCCESS = 0 AUTH_FAILURE = 1 @@ -38,7 +38,7 @@ LOCAL_DIFF_FAILURE = 5 NO_OUTPUT_MANAGER = 6 - class ComparisonResults(object): + class ComparisonResults(): """Struct-like object for storing results of an image comparison.""" def __init__(self):
diff --git a/build/skia_gold_common/skia_gold_session_manager.py b/build/skia_gold_common/skia_gold_session_manager.py index d4166e1..cb1654d7 100644 --- a/build/skia_gold_common/skia_gold_session_manager.py +++ b/build/skia_gold_common/skia_gold_session_manager.py
@@ -7,7 +7,7 @@ import tempfile -class SkiaGoldSessionManager(object): +class SkiaGoldSessionManager(): def __init__(self, working_dir, gold_properties): """Abstract class to manage one or more skia_gold_session.SkiaGoldSessions.
diff --git a/build/write_buildflag_header.py b/build/write_buildflag_header.py index 47b9a03..d46cfc8 100755 --- a/build/write_buildflag_header.py +++ b/build/write_buildflag_header.py
@@ -91,13 +91,5 @@ output_file.write('\n#endif // %s\n' % options.header_guard) -if os.name == 'nt': - major, minor, build, platform, service_pack = sys.getwindowsversion() - # Windows 10 will be 6.2 on Python 2 and 10.0 on Python 3. This check - # handles both. - if major < 6 or (major == 6 and minor < 2): - raise Exception( - 'Unsupported OS. Building Chromium requires Windows 10. %s detected.' % - str(sys.getwindowsversion())) options = GetOptions() WriteHeader(options)
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 4216f35..a242013 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -306,10 +306,11 @@ virtual void SetSynchronousInputHandlerRootScrollOffset( const gfx::PointF& root_content_offset) = 0; - virtual void PinchGestureBegin() = 0; + virtual void PinchGestureBegin(const gfx::Point& anchor, + ui::ScrollInputType source) = 0; virtual void PinchGestureUpdate(float magnify_delta, const gfx::Point& anchor) = 0; - virtual void PinchGestureEnd(const gfx::Point& anchor, bool snap_to_min) = 0; + virtual void PinchGestureEnd(const gfx::Point& anchor) = 0; // Request another callback to InputHandlerClient::Animate(). virtual void SetNeedsAnimateInput() = 0;
diff --git a/cc/input/threaded_input_handler.cc b/cc/input/threaded_input_handler.cc index 06b79d447..4e899cd 100644 --- a/cc/input/threaded_input_handler.cc +++ b/cc/input/threaded_input_handler.cc
@@ -731,14 +731,37 @@ compositor_delegate_.SetNeedsFullViewportRedraw(); } -void ThreadedInputHandler::PinchGestureBegin() { +void ThreadedInputHandler::PinchGestureBegin(const gfx::Point& anchor, + ui::ScrollInputType source) { + DCHECK(source == ui::ScrollInputType::kTouchscreen || + source == ui::ScrollInputType::kWheel); + pinch_gesture_active_ = true; pinch_gesture_end_should_clear_scrolling_node_ = !CurrentlyScrollingNode(); TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode PinchGestureBegin", TRACE_EVENT_SCOPE_THREAD, "isNull", OuterViewportScrollNode() ? false : true); - ActiveTree().SetCurrentlyScrollingNode(OuterViewportScrollNode()); + + // Some unit tests don't setup viewport scroll nodes but do initiate a pinch + // zoom gesture. Ideally, those tests should either create the viewport + // scroll nodes or avoid simulating a pinch gesture. + if (OuterViewportScrollNode()) { + ActiveTree().SetCurrentlyScrollingNode(OuterViewportScrollNode()); + + ScrollStateData scroll_state_data; + scroll_state_data.position_x = anchor.x(); + scroll_state_data.position_y = anchor.y(); + scroll_state_data.is_beginning = true; + scroll_state_data.delta_granularity = + ui::ScrollGranularity::kScrollByPrecisePixel; + scroll_state_data.is_direct_manipulation = + source == ui::ScrollInputType::kTouchscreen; + ScrollState state(scroll_state_data); + + DidLatchToScroller(state, source); + } + compositor_delegate_.GetImplDeprecated() .browser_controls_manager() ->PinchBegin(); @@ -759,8 +782,12 @@ UpdateRootLayerStateForSynchronousInputHandler(); } -void ThreadedInputHandler::PinchGestureEnd(const gfx::Point& anchor, - bool snap_to_min) { +void ThreadedInputHandler::PinchGestureEnd(const gfx::Point& anchor) { + // Some tests create a pinch gesture without creating a viewport scroll node. + // In those cases, PinchGestureBegin will not latch to a scroll node. + DCHECK(latched_scroll_type_.has_value() || !CurrentlyScrollingNode()); + bool snap_to_min = latched_scroll_type_.has_value() && + latched_scroll_type_ == ui::ScrollInputType::kWheel; pinch_gesture_active_ = false; if (pinch_gesture_end_should_clear_scrolling_node_) { pinch_gesture_end_should_clear_scrolling_node_ = false; @@ -1981,6 +2008,7 @@ ->ScrollAnimationAbort(); scroll_animating_snap_target_ids_ = TargetSnapAreaElementIds(); + last_latched_scroller_ = CurrentlyScrollingNode()->element_id; latched_scroll_type_ = type; last_scroll_begin_state_ = scroll_state;
diff --git a/cc/input/threaded_input_handler.h b/cc/input/threaded_input_handler.h index d3d9e83..ff554e8 100644 --- a/cc/input/threaded_input_handler.h +++ b/cc/input/threaded_input_handler.h
@@ -73,10 +73,11 @@ void RequestUpdateForSynchronousInputHandler() override; void SetSynchronousInputHandlerRootScrollOffset( const gfx::PointF& root_content_offset) override; - void PinchGestureBegin() override; + void PinchGestureBegin(const gfx::Point& anchor, + ui::ScrollInputType source) override; void PinchGestureUpdate(float magnify_delta, const gfx::Point& anchor) override; - void PinchGestureEnd(const gfx::Point& anchor, bool snap_to_min) override; + void PinchGestureEnd(const gfx::Point& anchor) override; void SetNeedsAnimateInput() override; bool IsCurrentlyScrollingViewport() const override; EventListenerProperties GetEventListenerProperties(
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 1187a51..b0ac24a 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -715,7 +715,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f); EXPECT_EQ(active_layer()->tilings()->NumHighResTilings(), 1); @@ -778,7 +779,8 @@ InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); // Start a pinch gesture. - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); // Zoom out by a small amount. We should create a tiling at half // the scale (2/kMaxScaleRatioDuringPinch). @@ -820,7 +822,7 @@ EXPECT_NE(LOW_RESOLUTION, low_res_tiling->resolution()); // Stop a pinch gesture. - host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point(), false); + host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point()); // Ensure UpdateTiles won't remove any tilings. active_layer()->MarkAllTilingsUsed(); @@ -863,7 +865,8 @@ InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); // Start a pinch gesture. - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); // Zoom out by a small amount. We should create a tiling at half // the scale (1/kMaxScaleRatioDuringPinch). @@ -939,7 +942,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); // Changing the ideal but not creating new tilings. scale = 1.5f; @@ -962,7 +966,7 @@ 1.f * low_res_factor, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); - host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point(), false); + host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point()); // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. scale = 1.2f; @@ -2684,7 +2688,8 @@ // When we page scale up by 2.3, we get a new tiling that is a power of 2, in // this case 4. - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); float high_res_scale = 2.3f; SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale); EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale_key()); @@ -2701,7 +2706,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); float high_res_scale = 0.0001f; EXPECT_LT(high_res_scale, pending_layer()->MinimumContentsScale()); @@ -2727,7 +2733,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); float page_scale = 0.0001f; EXPECT_LT(page_scale * contents_scale, @@ -4026,7 +4033,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); // Changing the ideal but not creating new tilings. scale *= 1.5f; @@ -4039,7 +4047,7 @@ active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); - host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point(), false); + host_impl()->GetInputHandler().PinchGestureEnd(gfx::Point()); // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. scale /= 4.f; @@ -5552,7 +5560,8 @@ // input handler. InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl())); - host_impl()->GetInputHandler().PinchGestureBegin(); + host_impl()->GetInputHandler().PinchGestureBegin( + gfx::Point(), ui::ScrollInputType::kTouchscreen); // Zoom out to exactly the low res factor so that the previous high res // would be equal to the current low res (if it were possible to have one).
diff --git a/cc/metrics/average_lag_tracking_manager.cc b/cc/metrics/average_lag_tracking_manager.cc index cb3dd22b..679d126 100644 --- a/cc/metrics/average_lag_tracking_manager.cc +++ b/cc/metrics/average_lag_tracking_manager.cc
@@ -5,12 +5,37 @@ #include "cc/metrics/average_lag_tracking_manager.h" #include <algorithm> +#include <memory> #include "components/viz/common/frame_timing_details.h" #include "components/viz/common/quads/compositor_frame_metadata.h" -#include "ui/latency/latency_info.h" namespace cc { +namespace { + +void AddEventInfoFromEventMetricsList( + const EventMetrics::List& events_metrics, + std::vector<AverageLagTracker::EventInfo>* event_infos) { + for (const std::unique_ptr<EventMetrics>& event_metrics : events_metrics) { + EventMetrics::EventType type = event_metrics->type(); + if (type != EventMetrics::EventType::kFirstGestureScrollUpdate && + type != EventMetrics::EventType::kGestureScrollUpdate) { + continue; + } + + auto* scroll_update_metrics = event_metrics->AsScrollUpdate(); + DCHECK(scroll_update_metrics); + event_infos->emplace_back( + scroll_update_metrics->delta(), + scroll_update_metrics->predicted_delta(), + scroll_update_metrics->last_timestamp(), + type == EventMetrics::EventType::kFirstGestureScrollUpdate + ? AverageLagTracker::EventType::ScrollBegin + : AverageLagTracker::EventType::ScrollUpdate); + } +} + +} // namespace AverageLagTrackingManager::AverageLagTrackingManager() = default; @@ -23,34 +48,19 @@ void AverageLagTrackingManager::CollectScrollEventsFromFrame( uint32_t frame_token, - const std::vector<ui::LatencyInfo>& latency_infos) { + const EventMetricsSet& events_metrics) { std::vector<AverageLagTracker::EventInfo> event_infos; - for (const ui::LatencyInfo& latency_info : latency_infos) { - if (latency_info.source_event_type() != ui::SourceEventType::TOUCH) - continue; - - bool found_scroll_begin = latency_info.FindLatency( - ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, - nullptr); - bool found_scroll_update = latency_info.FindLatency( - ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, nullptr); - - if (!found_scroll_begin && !found_scroll_update) - continue; - - base::TimeTicks event_timestamp; - bool found_event = latency_info.FindLatency( - ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT_COMPONENT, - &event_timestamp); - DCHECK(found_event); - - event_infos.emplace_back( - latency_info.scroll_update_delta(), - latency_info.predicted_scroll_update_delta(), event_timestamp, - found_scroll_begin ? AverageLagTracker::EventType::ScrollBegin - : AverageLagTracker::EventType::ScrollUpdate); - } + // A scroll event can be handled either on the main or the compositor thread + // (not both). So, both lists of metrics from the main and the compositor + // thread might contain interesting scroll events and we should collect + // information about scroll events from both. We are not worried about + // ordering of the events at this point. If the frame is presented, events + // for the frame will be sorted and fed into `AverageLagTracker` in order. + AddEventInfoFromEventMetricsList(events_metrics.main_event_metrics, + &event_infos); + AddEventInfoFromEventMetricsList(events_metrics.impl_event_metrics, + &event_infos); if (event_infos.size() > 0) frame_token_to_info_.emplace_back(frame_token, std::move(event_infos));
diff --git a/cc/metrics/average_lag_tracking_manager.h b/cc/metrics/average_lag_tracking_manager.h index ba2e34f9..992e2ea4 100644 --- a/cc/metrics/average_lag_tracking_manager.h +++ b/cc/metrics/average_lag_tracking_manager.h
@@ -11,10 +11,7 @@ #include "base/containers/circular_deque.h" #include "cc/cc_export.h" #include "cc/metrics/average_lag_tracker.h" - -namespace ui { -class LatencyInfo; -} // namespace ui +#include "cc/metrics/event_metrics.h" namespace viz { struct FrameTimingDetails; @@ -22,7 +19,7 @@ namespace cc { -// A helper to decouple the LatencyInfos and the AverageLagTracker +// A helper to decouple the `EventMetrics` and the `AverageLagTracker`. class CC_EXPORT AverageLagTrackingManager { public: AverageLagTrackingManager(); @@ -36,7 +33,7 @@ // Adds all the eligible events in the collection |infos| to the |frame_token| // wait list. void CollectScrollEventsFromFrame(uint32_t frame_token, - const std::vector<ui::LatencyInfo>& infos); + const EventMetricsSet& events_metrics); // Sends all pending events in the |frame_token| list to the // AverageLagTracker, given its |frame_details|.
diff --git a/cc/metrics/average_lag_tracking_manager_unittest.cc b/cc/metrics/average_lag_tracking_manager_unittest.cc index c3091c7..d313bb8 100644 --- a/cc/metrics/average_lag_tracking_manager_unittest.cc +++ b/cc/metrics/average_lag_tracking_manager_unittest.cc
@@ -11,7 +11,6 @@ #include "components/viz/common/frame_timing_details.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/latency/latency_info.h" namespace cc { namespace { @@ -56,55 +55,44 @@ return; // Creates 1st frame with scroll begin. - std::vector<ui::LatencyInfo> events(gpu_swap_times[0] / scroll_rate); + int events_count = gpu_swap_times[0] / scroll_rate; + EventMetricsSet events; base::TimeTicks event_time = MillisecondsToTimeTicks(scroll_rate); - events[0] = PrepareScrollEvent(AverageLagTracker::EventType::ScrollBegin, - event_time, 0, scroll_delta); - for (size_t i = 1; i < events.size(); i++) { + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kStarted, event_time, + scroll_delta)); + for (int i = 1; i < events_count; i++) { event_time += base::Milliseconds(scroll_rate); - events[i] = PrepareScrollEvent(AverageLagTracker::EventType::ScrollUpdate, - event_time, i, scroll_delta); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, event_time, + scroll_delta)); } average_lag_tracking_manager_.CollectScrollEventsFromFrame(0, events); // Creates remaining frames. for (size_t frame = 1; frame < gpu_swap_times.size(); frame++) { int time_delta = gpu_swap_times[frame] - gpu_swap_times[frame - 1]; - events = std::vector<ui::LatencyInfo>(time_delta / scroll_rate); - for (size_t i = 0; i < events.size(); i++) { + events_count = time_delta / scroll_rate; + events.main_event_metrics.clear(); + for (int i = 0; i < events_count; i++) { event_time += base::Milliseconds(scroll_rate); - events[i] = - PrepareScrollEvent(AverageLagTracker::EventType::ScrollUpdate, - event_time, i, scroll_delta); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, event_time, + scroll_delta)); } average_lag_tracking_manager_.CollectScrollEventsFromFrame(frame, events); } } - // Prepares a ui::LatencyInfo object for a ScrollEvent. - ui::LatencyInfo PrepareScrollEvent(AverageLagTracker::EventType event_type, - base::TimeTicks event_time, - int trace_id, - float delta, - float predicted_delta = 0.0f) { - ui::LatencyInfo info; - info.set_trace_id(trace_id); - info.set_source_event_type(ui::SourceEventType::TOUCH); - - info.AddLatencyNumberWithTimestamp( - event_type == AverageLagTracker::EventType::ScrollBegin - ? ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT - : ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, - event_time); - - info.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT_COMPONENT, event_time); - - info.set_scroll_update_delta(delta); - info.set_predicted_scroll_update_delta( - predicted_delta != 0 ? predicted_delta : delta); - - return info; + // Prepares an `ScrollUpdateEventMetrics` object for a scroll-update event. + std::unique_ptr<ScrollUpdateEventMetrics> PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType scroll_update_type, + base::TimeTicks event_time, + float delta) { + const bool kScrollIsNotInertial = false; + return ScrollUpdateEventMetrics::Create( + ui::ET_GESTURE_SCROLL_UPDATE, ui::ScrollInputType::kTouchscreen, + kScrollIsNotInertial, scroll_update_type, delta, event_time); } AverageLagTrackingManager average_lag_tracking_manager_; @@ -118,7 +106,6 @@ base::HistogramTester histogram_tester; const float scroll_delta = 10.0f; - const int trace_id = 1; base::TimeTicks event_time = MillisecondsToTimeTicks(5); base::TimeTicks gpu_swap_time = MillisecondsToTimeTicks(10); @@ -129,10 +116,11 @@ event_time += base::Milliseconds(10); // 15ms gpu_swap_time += base::Milliseconds(10); // 20ms presentation_time += base::Milliseconds(10); // 23ms - ui::LatencyInfo evt = - PrepareScrollEvent(AverageLagTracker::EventType::ScrollBegin, event_time, - trace_id, scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame(frame_id, {evt}); + EventMetricsSet events; + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kStarted, event_time, + scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(frame_id, events); average_lag_tracking_manager_.DidPresentCompositorFrame( frame_id, PrepareFrameDetails(gpu_swap_time, presentation_time)); @@ -146,9 +134,12 @@ // First 50 has positive delta, others negative delta. const int sign = (i < kUpdates / 2) ? 1 : -1; - evt = PrepareScrollEvent(AverageLagTracker::EventType::ScrollUpdate, - event_time, trace_id, sign * scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame(frame_id, {evt}); + events.main_event_metrics.clear(); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, event_time, + sign * scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(frame_id, + events); average_lag_tracking_manager_.DidPresentCompositorFrame( frame_id, PrepareFrameDetails(gpu_swap_time, presentation_time)); } @@ -221,7 +212,6 @@ TEST_F(AverageLagTrackingManagerTest, OutOfOrderPresentationFeedback) { base::HistogramTester histogram_tester; - const int trace_id = 1; const float scroll_delta = 100.0f; std::vector<int> event_times = {500, 1500, 2500, 3500}; @@ -231,10 +221,11 @@ // Create a scroll-begin event. Submit frame 0 with updates from scroll-begin // event and present it successfully. No AverageLag metrics should be reported // yet. - ui::LatencyInfo scroll_begin = PrepareScrollEvent( - AverageLagTracker::EventType::ScrollBegin, - MillisecondsToTimeTicks(event_times[0]), trace_id, scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame(0, {scroll_begin}); + EventMetricsSet events; + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kStarted, + MillisecondsToTimeTicks(event_times[0]), scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(0, events); average_lag_tracking_manager_.DidPresentCompositorFrame( 0, PrepareFrameDetails(MillisecondsToTimeTicks(gpu_swap_times[0]), MillisecondsToTimeTicks(presentation_times[0]))); @@ -246,11 +237,11 @@ // Create the first scroll-update event. Submit frame 1 with updates from the // first scroll-update event, but don't present it yet. No AverageLag metrics // should be recorded. - ui::LatencyInfo scroll_update_1 = PrepareScrollEvent( - AverageLagTracker::EventType::ScrollUpdate, - MillisecondsToTimeTicks(event_times[1]), trace_id, scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame(1, - {scroll_update_1}); + events.main_event_metrics.clear(); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + MillisecondsToTimeTicks(event_times[1]), scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(1, events); histogram_tester.ExpectTotalCount( "Event.Latency.ScrollBegin.Touch.AverageLagPresentation", 0); histogram_tester.ExpectTotalCount( @@ -259,11 +250,11 @@ // Create the second scroll-update event. Submit frame 2 with updates from the // second scroll-update event, but fail to present it. No AverageLag metrics // should be reported. - ui::LatencyInfo scroll_update_2 = PrepareScrollEvent( - AverageLagTracker::EventType::ScrollUpdate, - MillisecondsToTimeTicks(event_times[2]), trace_id, scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame(2, - {scroll_update_2}); + events.main_event_metrics.clear(); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + MillisecondsToTimeTicks(event_times[2]), scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(2, events); average_lag_tracking_manager_.DidPresentCompositorFrame( 2, PrepareFailedFrameDetails()); histogram_tester.ExpectTotalCount( @@ -286,11 +277,10 @@ // third scroll-update events. Since the failure of frame 2 should not have // affected events from frame 1, AverageLag metrics for scroll-update event of // frame 1 should be reported. - ui::LatencyInfo scroll_update_3 = PrepareScrollEvent( - AverageLagTracker::EventType::ScrollUpdate, - MillisecondsToTimeTicks(event_times[3]), trace_id, scroll_delta); - average_lag_tracking_manager_.CollectScrollEventsFromFrame( - 3, {scroll_update_2, scroll_update_3}); + events.main_event_metrics.push_back(PrepareScrollUpdateEvent( + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + MillisecondsToTimeTicks(event_times[3]), scroll_delta)); + average_lag_tracking_manager_.CollectScrollEventsFromFrame(3, events); average_lag_tracking_manager_.DidPresentCompositorFrame( 3, PrepareFrameDetails(MillisecondsToTimeTicks(gpu_swap_times[3]), MillisecondsToTimeTicks(presentation_times[3])));
diff --git a/cc/metrics/dropped_frame_counter.cc b/cc/metrics/dropped_frame_counter.cc index db8d087..6a8ae92 100644 --- a/cc/metrics/dropped_frame_counter.cc +++ b/cc/metrics/dropped_frame_counter.cc
@@ -395,16 +395,8 @@ void DroppedFrameCounter::ReportFramesForUI() { DCHECK(report_for_ui_); #if BUILDFLAG(IS_CHROMEOS_ASH) - UMA_HISTOGRAM_PERCENTAGE( - "Ash.Smoothness.MaxPercentDroppedFrames_1sWindow.Uniform", - sliding_window_max_percent_dropped_); - - if (sliding_window_max_percent_dropped_ != - last_reported_metrics_.max_window) { - UMA_HISTOGRAM_PERCENTAGE("Ash.Smoothness.MaxPercentDroppedFrames_1sWindow", - sliding_window_max_percent_dropped_); - last_reported_metrics_.max_window = sliding_window_max_percent_dropped_; - } + UMA_HISTOGRAM_PERCENTAGE("Ash.Smoothness.PercentDroppedFrames_1sWindow", + sliding_window_current_percent_dropped_); #endif // BUILDFLAG(IS_CHROMEOS_ASH) } @@ -527,7 +519,7 @@ uint32_t dropped = dropped_frame_count_in_window_[SmoothnessStrategy::kDefaultStrategy] - invalidated_frames; - double percent_dropped_frame = + const double percent_dropped_frame = std::min((dropped * 100.0) / total_frames_in_window_, 100.0); sliding_window_histogram_[SmoothnessStrategy::kDefaultStrategy] .AddPercentDroppedFrame(percent_dropped_frame, count); @@ -561,6 +553,7 @@ time_max_delta_ = newest_args.frame_time - time_fcp_received_; sliding_window_max_percent_dropped_ = percent_dropped_frame; } + sliding_window_current_percent_dropped_ = percent_dropped_frame; latest_sliding_window_start_ = last_timestamp; latest_sliding_window_interval_ = remaining_oldest_args.interval;
diff --git a/cc/metrics/dropped_frame_counter.h b/cc/metrics/dropped_frame_counter.h index 38248dc..b93fc7c 100644 --- a/cc/metrics/dropped_frame_counter.h +++ b/cc/metrics/dropped_frame_counter.h
@@ -216,6 +216,7 @@ absl::optional<SortedFrameCallback> sorted_frame_callback_; bool report_for_ui_ = false; + double sliding_window_current_percent_dropped_ = 0.0; }; CC_EXPORT std::ostream& operator<<(
diff --git a/cc/metrics/dropped_frame_counter_unittest.cc b/cc/metrics/dropped_frame_counter_unittest.cc index abff734..cc48999 100644 --- a/cc/metrics/dropped_frame_counter_unittest.cc +++ b/cc/metrics/dropped_frame_counter_unittest.cc
@@ -932,12 +932,9 @@ // 4 seconds with 20% dropped frames. SimulateFrameSequence({false, false, false, false, true}, (kFps / 5) * 4); - // Exact 1 sample of changing to 20% dropped frame percentage. - histogram_tester.ExpectUniqueSample( - "Ash.Smoothness.MaxPercentDroppedFrames_1sWindow", 20, 1); - // More than 1 samples of 20% dropped frame percentage. + // Recorded more than 1 samples of 20% dropped frame percentage. EXPECT_GE(histogram_tester.GetBucketCount( - "Ash.Smoothness.MaxPercentDroppedFrames_1sWindow.Uniform", 20), + "Ash.Smoothness.PercentDroppedFrames_1sWindow", 20), 1); } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/cc/paint/skottie_resource_metadata.cc b/cc/paint/skottie_resource_metadata.cc index 3905781..be6b983 100644 --- a/cc/paint/skottie_resource_metadata.cc +++ b/cc/paint/skottie_resource_metadata.cc
@@ -52,7 +52,8 @@ } SkottieResourceIdHash HashSkottieResourceId(base::StringPiece resource_id) { - return SkottieResourceIdHash::FromUnsafeValue(base::FastHash(resource_id)); + return SkottieResourceIdHash::FromUnsafeValue( + base::PersistentHash(resource_id.data(), resource_id.length())); } } // namespace cc
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc index 8c9f8947..585ec96 100644 --- a/cc/test/layer_tree_pixel_resource_test.cc +++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -77,14 +77,13 @@ return std::make_unique<BitmapRasterBufferProvider>( host_impl->layer_tree_frame_sink()); case TestRasterType::kGpu: - case TestRasterType::kOop: EXPECT_TRUE(compositor_context_provider); EXPECT_TRUE(worker_context_provider); EXPECT_FALSE(use_software_renderer()); return std::make_unique<GpuRasterBufferProvider>( compositor_context_provider, worker_context_provider, false, gpu_raster_format, gfx::Size(), true, - /*enable_oop_rasterization=*/raster_type() == TestRasterType::kOop, + /*enable_oop_rasterization=*/true, host_impl->GetRasterQueryQueueForTesting()); case TestRasterType::kZeroCopy: EXPECT_TRUE(compositor_context_provider);
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 54b961f..951c2b6 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -46,7 +46,7 @@ return TestRasterType::kBitmap; case viz::RendererType::kSkiaVk: case viz::RendererType::kSkiaDawn: - return TestRasterType::kOop; + return TestRasterType::kGpu; default: return TestRasterType::kOneCopy; } @@ -78,11 +78,8 @@ viz::RasterInterfaceType worker_ri_type; switch (raster_type()) { - case TestRasterType::kOop: - worker_ri_type = viz::RasterInterfaceType::OOPR; - break; case TestRasterType::kGpu: - worker_ri_type = viz::RasterInterfaceType::GPU; + worker_ri_type = viz::RasterInterfaceType::OOPR; break; case TestRasterType::kOneCopy: worker_ri_type = viz::RasterInterfaceType::Software; @@ -132,7 +129,7 @@ EXPECT_EQ(use_accelerated_raster(), worker_context_provider->ContextCapabilities().gpu_rasterization); EXPECT_EQ( - raster_type() == TestRasterType::kOop, + raster_type() == TestRasterType::kGpu, worker_context_provider->ContextCapabilities().supports_oop_raster); } else { EXPECT_EQ(TestRasterType::kBitmap, raster_type());
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index de31505..62fce50 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h
@@ -127,8 +127,7 @@ TestRasterType raster_type() const { return raster_type_; } bool use_accelerated_raster() const { - return raster_type_ == TestRasterType::kGpu || - raster_type_ == TestRasterType::kOop; + return raster_type_ == TestRasterType::kGpu; } // Common CSS colors defined for tests to use.
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 1cd7fcb..84143ef51 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -251,8 +251,8 @@ return test_hooks_->PrepareToDrawOnThread(this, frame, draw_result); } - bool DrawLayers(FrameData* frame) override { - bool r = LayerTreeHostImpl::DrawLayers(frame); + absl::optional<EventMetricsSet> DrawLayers(FrameData* frame) override { + absl::optional<EventMetricsSet> r = LayerTreeHostImpl::DrawLayers(frame); test_hooks_->DrawLayersOnThread(this); return r; }
diff --git a/cc/test/test_types.cc b/cc/test/test_types.cc index eb47238..7111c49 100644 --- a/cc/test/test_types.cc +++ b/cc/test/test_types.cc
@@ -15,8 +15,6 @@ return "Bitmap"; case TestRasterType::kGpu: return "GPU"; - case TestRasterType::kOop: - return "OOP"; case TestRasterType::kOneCopy: return "OneCopy"; case TestRasterType::kZeroCopy:
diff --git a/cc/test/test_types.h b/cc/test/test_types.h index 02b36c01..b1acabd7 100644 --- a/cc/test/test_types.h +++ b/cc/test/test_types.h
@@ -33,7 +33,6 @@ enum class TestRasterType { kBitmap, kGpu, - kOop, kOneCopy, kZeroCopy, };
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index c13c064..de7dba8 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2478,7 +2478,8 @@ return metadata; } -bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { +absl::optional<EventMetricsSet> LayerTreeHostImpl::DrawLayers( + FrameData* frame) { DCHECK(CanDraw()); DCHECK_EQ(frame->has_no_damage, frame->render_passes.empty()); ResetRequiresHighResToDraw(); @@ -2492,7 +2493,7 @@ TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS); active_tree()->ResetAllChangeTracking(); - return false; + return absl::nullopt; } layer_tree_frame_sink_->set_source_frame_number( @@ -2504,9 +2505,11 @@ const viz::BeginFrameId begin_frame_ack_frame_id = compositor_frame.metadata.begin_frame_ack.frame_id; - // Collect |latency_info| information for tracking - lag_tracking_manager_.CollectScrollEventsFromFrame( - frame_token, compositor_frame.metadata.latency_info); + EventMetricsSet events_metrics( + active_tree()->TakeEventsMetrics(), + events_metrics_manager_.TakeSavedEventsMetrics()); + lag_tracking_manager_.CollectScrollEventsFromFrame(frame_token, + events_metrics); layer_tree_frame_sink_->SubmitCompositorFrame( std::move(compositor_frame), /*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders); @@ -2577,7 +2580,7 @@ client_->FrameSinksToThrottleUpdated(throttle_decider_.ids()); } - return true; + return events_metrics; } viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( @@ -5147,11 +5150,6 @@ client_->NeedsImplSideInvalidation(needs_first_draw_on_activation); } -EventMetricsSet LayerTreeHostImpl::TakeEventsMetrics() { - return EventMetricsSet(active_tree()->TakeEventsMetrics(), - events_metrics_manager_.TakeSavedEventsMetrics()); -} - base::WeakPtr<LayerTreeHostImpl> LayerTreeHostImpl::AsWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index db4cb52..600a82a 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -326,10 +326,6 @@ void RequestBeginFrameForAnimatedImages() override; void RequestInvalidationForAnimatedImages() override; - EventMetricsSet TakeEventsMetrics(); - void AppendEventsMetricsFromMainThread( - std::vector<EventMetrics> events_metrics); - base::WeakPtr<LayerTreeHostImpl> AsWeakPtr(); void set_resourceless_software_draw_for_testing() { @@ -476,13 +472,16 @@ virtual bool PrepareTiles(); - // Returns DRAW_SUCCESS unless problems occured preparing the frame, and we - // should try to avoid displaying the frame. If PrepareToDraw is called, - // DidDrawAllLayers must also be called, regardless of whether DrawLayers is - // called between the two. + // Returns `DRAW_SUCCESS` unless problems occurred preparing the frame, and we + // should try to avoid displaying the frame. If `PrepareToDraw()` is called, + // `DidDrawAllLayers()` must also be called, regardless of whether + // `DrawLayers()` is called between the two. virtual DrawResult PrepareToDraw(FrameData* frame); - virtual bool DrawLayers(FrameData* frame); - viz::CompositorFrame GenerateCompositorFrame(FrameData* frame); + + // If there is no damage, returns `absl::nullopt`; otherwise, returns set of + // `EventMetrics` for the frame. + virtual absl::optional<EventMetricsSet> DrawLayers(FrameData* frame); + // Must be called if and only if PrepareToDraw was called. void DidDrawAllLayers(const FrameData& frame); @@ -929,6 +928,8 @@ compositor_frame_reporting_controller_; private: + viz::CompositorFrame GenerateCompositorFrame(FrameData* frame); + void CollectScrollbarUpdatesForCommit( CompositorCommitData* commit_data) const;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index dec69314..2e66cb2 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -977,9 +977,10 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, LocalAndExternalPinchState) { // PinchGestureBegin/End update pinch_gesture_active() properly. EXPECT_FALSE(GetInputHandler().pinch_gesture_active()); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kTouchscreen); EXPECT_TRUE(GetInputHandler().pinch_gesture_active()); - GetInputHandler().PinchGestureEnd(gfx::Point(), false /* snap_to_min */); + GetInputHandler().PinchGestureEnd(gfx::Point()); EXPECT_FALSE(GetInputHandler().pinch_gesture_active()); // set_external_pinch_gesture_active updates pinch_gesture_active() properly. @@ -990,11 +991,12 @@ // Clearing external_pinch_gesture_active doesn't affect // pinch_gesture_active() if it was set by PinchGestureBegin(). - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kTouchscreen); EXPECT_TRUE(GetInputHandler().pinch_gesture_active()); GetInputHandler().set_external_pinch_gesture_active(false); EXPECT_TRUE(GetInputHandler().pinch_gesture_active()); - GetInputHandler().PinchGestureEnd(gfx::Point(), false /* snap_to_min */); + GetInputHandler().PinchGestureEnd(gfx::Point()); EXPECT_FALSE(GetInputHandler().pinch_gesture_active()); } @@ -3569,9 +3571,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(50, 50), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), true); + GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); GetInputHandler().ScrollEnd(); EXPECT_FALSE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); @@ -3598,9 +3601,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); gfx::Vector2d scroll_delta(0, 10); @@ -3703,9 +3707,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point(0, 0)); - GetInputHandler().PinchGestureEnd(gfx::Point(0, 0), true); + GetInputHandler().PinchGestureEnd(gfx::Point(0, 0)); GetInputHandler().ScrollEnd(); // Sanity check - we're zoomed in, starting from the origin. @@ -3827,7 +3832,8 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(250, 250), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point(250, 250)); EXPECT_POINTF_EQ(gfx::PointF(0, 0), CurrentScrollOffset(outer_scroll_layer)); @@ -3856,7 +3862,7 @@ EXPECT_POINTF_EQ(gfx::PointF(250, 250), CurrentScrollOffset(inner_scroll_layer)); - GetInputHandler().PinchGestureEnd(gfx::Point(250, 250), true); + GetInputHandler().PinchGestureEnd(gfx::Point(250, 250)); GetInputHandler().ScrollEnd(); } @@ -3882,9 +3888,9 @@ BeginState(anchor, gfx::Vector2dF(), ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(anchor, ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, anchor); - GetInputHandler().PinchGestureEnd(anchor, true); + GetInputHandler().PinchGestureEnd(anchor); GetInputHandler().ScrollEnd(); EXPECT_POINTF_EQ(gfx::PointF(250, 250), @@ -3902,9 +3908,10 @@ BeginState(anchor, gfx::Vector2dF(), ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(100, 100), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, anchor); - GetInputHandler().PinchGestureEnd(anchor, true); + GetInputHandler().PinchGestureEnd(anchor); GetInputHandler().ScrollEnd(); EXPECT_POINTF_EQ(gfx::PointF(0, 0), @@ -3922,9 +3929,9 @@ BeginState(anchor, gfx::Vector2dF(), ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(anchor, ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, anchor); - GetInputHandler().PinchGestureEnd(anchor, true); + GetInputHandler().PinchGestureEnd(anchor); GetInputHandler().ScrollEnd(); EXPECT_POINTF_EQ(gfx::PointF(50, 50), @@ -3943,9 +3950,9 @@ BeginState(anchor, gfx::Vector2dF(), ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(anchor, ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, anchor); - GetInputHandler().PinchGestureEnd(anchor, true); + GetInputHandler().PinchGestureEnd(anchor); GetInputHandler().ScrollEnd(); EXPECT_POINTF_EQ(gfx::PointF(200, 200), @@ -4158,9 +4165,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(50, 50), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), true); + GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); GetInputHandler().ScrollEnd(); EXPECT_FALSE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); @@ -4183,9 +4191,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(50, 50), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), true); + GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4211,9 +4220,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4242,10 +4252,11 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(10, 10), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); - GetInputHandler().PinchGestureEnd(gfx::Point(20, 20), true); + GetInputHandler().PinchGestureEnd(gfx::Point(20, 20)); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4273,14 +4284,15 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(10, 10), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); GetInputHandler().ScrollUpdate( UpdateState(gfx::Point(10, 10), gfx::Vector2d(-10, -10), ui::ScrollInputType::kTouchscreen) .get()); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); - GetInputHandler().PinchGestureEnd(gfx::Point(20, 20), true); + GetInputHandler().PinchGestureEnd(gfx::Point(20, 20)); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4306,7 +4318,8 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(0, 0), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point(0, 0)); GetInputHandler().PinchGestureUpdate(1, gfx::Point(0, 0)); @@ -4318,7 +4331,7 @@ ui::ScrollInputType::kTouchscreen) .get()); GetInputHandler().PinchGestureUpdate(1, gfx::Point(10, 10)); - GetInputHandler().PinchGestureEnd(gfx::Point(10, 10), true); + GetInputHandler().PinchGestureEnd(gfx::Point(10, 10)); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4355,14 +4368,15 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(10, 10), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(10, 10), gfx::Vector2dF(0, -1.001f), ui::ScrollInputType::kTouchscreen) .get()); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(10, 9)); - GetInputHandler().PinchGestureEnd(gfx::Point(10, 9), true); + GetInputHandler().PinchGestureEnd(gfx::Point(10, 9)); GetInputHandler().ScrollEnd(); std::unique_ptr<CompositorCommitData> commit_data = @@ -4442,9 +4456,10 @@ did_request_redraw_ = false; did_request_next_frame_ = false; - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(50, 50), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), true); + GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); host_impl_->ActivateSyncTree(); EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_next_frame_); @@ -4497,9 +4512,10 @@ did_request_redraw_ = false; did_request_next_frame_ = false; - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(50, 50), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), true); + GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); host_impl_->ActivateSyncTree(); EXPECT_TRUE(did_request_redraw_); EXPECT_FALSE(did_request_next_frame_); @@ -6100,9 +6116,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); { viz::CompositorFrameMetadata metadata = @@ -8070,9 +8087,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); DrawOneFrame(); @@ -8120,9 +8138,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(new_page_scale, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); DrawOneFrame(); @@ -8923,10 +8942,11 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point()); GetInputHandler().PinchGestureUpdate(.5f, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); // Scrolling should be relative to the offset as given by the delegate. @@ -10152,9 +10172,9 @@ BeginState(anchor, gfx::Vector2dF(), ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(anchor, ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_factor, anchor); - GetInputHandler().PinchGestureEnd(anchor, true); + GetInputHandler().PinchGestureEnd(anchor); EXPECT_POINTF_EQ(gfx::PointF(anchor.x() / 2, anchor.y() / 2), CurrentScrollOffset(inner_scroll_layer)); @@ -11162,7 +11182,7 @@ root_render_pass->quad_list.ElementAt(1)->visible_rect); } - EXPECT_EQ(expect_to_draw, host_impl_->DrawLayers(&frame)); + EXPECT_EQ(expect_to_draw, host_impl_->DrawLayers(&frame).has_value()); host_impl_->DidDrawAllLayers(frame); host_impl_->DidFinishImplFrame(args); } @@ -14004,18 +14024,18 @@ ui::ScrollInputType::kTouchscreen) .get()); - // Add a LatencyInfo object that will be accepted by - // AverageLagTrackingManager::CollectScrollEventsFromFrame. - ui::LatencyInfo latency_info; - latency_info.set_source_event_type(ui::SourceEventType::TOUCH); - latency_info.AddLatencyNumber( - ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT); - latency_info.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT_COMPONENT, - base::TimeTicks::Now()); - std::unique_ptr<SwapPromise> swap_promise( - new LatencyInfoSwapPromise(latency_info)); - host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); + // Add an `EventMetrics` object that will be accepted by + // `AverageLagTrackingManager::CollectScrollEventsFromFrame()`. + EventMetrics::List events_metrics; + events_metrics.push_back(ScrollUpdateEventMetrics::Create( + ui::EventType::ET_GESTURE_SCROLL_UPDATE, + ui::ScrollInputType::kTouchscreen, + /*is_inertial=*/false, + i == 0 ? ScrollUpdateEventMetrics::ScrollUpdateType::kStarted + : ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + /*delta=*/10.0f, base::TimeTicks::Now())); + host_impl_->active_tree()->AppendEventsMetricsFromMainThread( + std::move(events_metrics)); DrawFrame(); } @@ -15383,9 +15403,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(page_scale_delta, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); gfx::Vector2dF scroll_delta(0, 5); @@ -16612,9 +16633,10 @@ ui::ScrollInputType::kTouchscreen) .get(), ui::ScrollInputType::kTouchscreen); - GetInputHandler().PinchGestureBegin(); + GetInputHandler().PinchGestureBegin(gfx::Point(), + ui::ScrollInputType::kWheel); GetInputHandler().PinchGestureUpdate(2, gfx::Point()); - GetInputHandler().PinchGestureEnd(gfx::Point(), true); + GetInputHandler().PinchGestureEnd(gfx::Point()); GetInputHandler().ScrollEnd(); { RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc index 5289f95a..66259f84 100644 --- a/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -262,14 +262,16 @@ std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kGL, TestRasterType::kZeroCopy}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) - {viz::RendererType::kSkiaVk, TestRasterType::kOop}, + {viz::RendererType::kSkiaVk, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) #if BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) - {viz::RendererType::kSkiaDawn, TestRasterType::kOop}, + {viz::RendererType::kSkiaDawn, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) };
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index 8b23b6ea..fa044b3 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -32,15 +32,17 @@ std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kGL, TestRasterType::kGpu}, {viz::RendererType::kGL, TestRasterType::kOneCopy}, {viz::RendererType::kGL, TestRasterType::kZeroCopy}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, {viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) - {viz::RendererType::kSkiaVk, TestRasterType::kOop}, + {viz::RendererType::kSkiaVk, TestRasterType::kGpu}, {viz::RendererType::kSkiaVk, TestRasterType::kZeroCopy}, #endif // BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) }; @@ -573,11 +575,11 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTestWithLayerList, Test) { base::FilePath image_name = - (raster_type() == TestRasterType::kGpu) + (use_accelerated_raster()) ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png")) : base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter.png")); - if (use_skia_vulkan() && raster_type() == TestRasterType::kOop) { + if (use_skia_vulkan() && use_accelerated_raster()) { // Vulkan with OOP raster has 3 pixels errors (the circle mask shape is // slightly different). float percentage_pixels_large_error = 0.031f; // 3px / (100*100) @@ -633,11 +635,11 @@ blur->SetMaskLayer(mask); base::FilePath image_name = - (raster_type() == TestRasterType::kGpu) + (use_accelerated_raster()) ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png")) : base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter.png")); - if (use_skia_vulkan() && raster_type() == TestRasterType::kOop) { + if (use_skia_vulkan() && use_accelerated_raster()) { // Vulkan with OOP raster has 3 pixels errors (the circle mask shape is // slightly different). float percentage_pixels_large_error = 0.031f; // 3px / (100*100) @@ -871,6 +873,7 @@ MaskTestConfig const kTestConfigs[] = { MaskTestConfig{{viz::RendererType::kSoftware, TestRasterType::kBitmap}, 0}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, 0}, MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, kUseAntialiasing}, @@ -878,9 +881,14 @@ kForceShaders}, MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, kUseAntialiasing | kForceShaders}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, 0}, MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, kUseAntialiasing}, + MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, + kForceShaders}, + MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, + kUseAntialiasing | kForceShaders}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) MaskTestConfig{{viz::RendererType::kSkiaVk, TestRasterType::kZeroCopy}, 0},
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc index ca78ed1..277b3e2 100644 --- a/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -441,8 +441,10 @@ ReadbackTestConfig const kTestConfigs[] = { ReadbackTestConfig{viz::RendererType::kSoftware, TestReadBackType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kTexture}, ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kBitmap}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kTexture}, ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kBitmap}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index eb222df..49b97d0 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -222,16 +222,18 @@ std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kGL, TestRasterType::kOneCopy}, {viz::RendererType::kGL, TestRasterType::kGpu}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) - {viz::RendererType::kSkiaVk, TestRasterType::kOop}, + {viz::RendererType::kSkiaVk, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) #if BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) - {viz::RendererType::kSkiaDawn, TestRasterType::kOop}, + {viz::RendererType::kSkiaDawn, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) }; @@ -263,16 +265,18 @@ std::vector<RasterTestConfig> const kTestCasesMultiThread = { #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) +#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kGL, TestRasterType::kOneCopy}, +#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) // TODO(rivr): Switch this to one copy raster once is is supported for // Vulkan in these tests. - {viz::RendererType::kSkiaVk, TestRasterType::kOop}, + {viz::RendererType::kSkiaVk, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) #if BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) - {viz::RendererType::kSkiaDawn, TestRasterType::kOop}, + {viz::RendererType::kSkiaDawn, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_DAWN_BACKEND_TESTS) }; @@ -370,13 +374,11 @@ } }; -INSTANTIATE_TEST_SUITE_P( - All, - LayerTreeHostTilesTestPartialInvalidationLowBitDepth, - ::testing::Values( - RasterTestConfig{viz::RendererType::kSkiaGL, TestRasterType::kGpu}, - RasterTestConfig{viz::RendererType::kGL, TestRasterType::kGpu}), - ::testing::PrintToStringParamName()); +INSTANTIATE_TEST_SUITE_P(All, + LayerTreeHostTilesTestPartialInvalidationLowBitDepth, + ::testing::Values(RasterTestConfig{ + viz::RendererType::kSkiaGL, TestRasterType::kGpu}), + ::testing::PrintToStringParamName()); TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, DISABLED_PartialRaster) {
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 31add38..e3f4bcab9 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3622,9 +3622,10 @@ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { if (!sent_gesture_) { - host_impl->GetInputHandler().PinchGestureBegin(); + host_impl->GetInputHandler().PinchGestureBegin( + gfx::Point(100, 100), ui::ScrollInputType::kWheel); host_impl->GetInputHandler().PinchGestureUpdate(2, gfx::Point(100, 100)); - host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100), true); + host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100)); sent_gesture_ = true; } } @@ -7527,23 +7528,23 @@ switch (frame_) { case 2: // Pinch zoom in. - host_impl->GetInputHandler().PinchGestureBegin(); + host_impl->GetInputHandler().PinchGestureBegin( + gfx::Point(100, 100), ui::ScrollInputType::kWheel); host_impl->GetInputHandler().PinchGestureUpdate(1.5f, gfx::Point(100, 100)); - host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100), - true); + host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100)); break; case 3: // Pinch zoom back to 1.f but don't end it. - host_impl->GetInputHandler().PinchGestureBegin(); + host_impl->GetInputHandler().PinchGestureBegin( + gfx::Point(100, 100), ui::ScrollInputType::kWheel); host_impl->GetInputHandler().PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100)); break; case 4: // End the pinch, but delay tile production. playback_allowed_event_.Reset(); - host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100), - true); + host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100)); break; case 5: // Let tiles complete. @@ -7804,11 +7805,11 @@ // Delay tile production. playback_allowed_event_.Reset(); // Pinch zoom in to cause new tiles to be required. - host_impl->GetInputHandler().PinchGestureBegin(); + host_impl->GetInputHandler().PinchGestureBegin( + gfx::Point(100, 100), ui::ScrollInputType::kWheel); host_impl->GetInputHandler().PinchGestureUpdate(1.5f, gfx::Point(100, 100)); - host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100), - true); + host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100)); ++step_; break; case 2: @@ -8995,7 +8996,8 @@ // We have an active tree. Start a pinch gesture so we start recording // stats. - impl->GetInputHandler().PinchGestureBegin(); + impl->GetInputHandler().PinchGestureBegin( + gfx::Point(100, 100), ui::ScrollInputType::kTouchscreen); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { @@ -9004,7 +9006,7 @@ // We just drew a frame, stats for it should have been recorded. End the // gesture so they are flushed to the recorder. - impl->GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), false); + impl->GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); // RenewTreePriority will run when the smoothness expiration timer fires. // Synthetically do it here so the UkmManager is notified.
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc index e7f0bc1..e9247a2 100644 --- a/cc/trees/layer_tree_host_unittest_picture.cc +++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -486,9 +486,10 @@ picture->HighResTiling()->raster_transform()); // Pinch zoom in to change the scale on the active tree. - impl->GetInputHandler().PinchGestureBegin(); + impl->GetInputHandler().PinchGestureBegin( + gfx::Point(1, 1), ui::ScrollInputType::kWheel); impl->GetInputHandler().PinchGestureUpdate(2.f, gfx::Point(1, 1)); - impl->GetInputHandler().PinchGestureEnd(gfx::Point(1, 1), true); + impl->GetInputHandler().PinchGestureEnd(gfx::Point(1, 1)); } else if (picture->tilings()->num_tilings() == 1) { // If the pinch gesture caused a commit we could get here with a // pending tree.
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 2079ef6..a8e123e 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -817,11 +817,12 @@ } if (draw_frame) { - if (host_impl_->DrawLayers(&frame)) { + if (absl::optional<EventMetricsSet> events_metrics = + host_impl_->DrawLayers(&frame)) { DCHECK_NE(frame.frame_token, 0u); // Drawing implies we submitted a frame to the LayerTreeFrameSink. scheduler_->DidSubmitCompositorFrame(frame.frame_token, - host_impl_->TakeEventsMetrics(), + std::move(*events_metrics), frame.has_missing_content); } result = DRAW_SUCCESS;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index c3cd9e7..6cb63bf 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -824,11 +824,12 @@ draw_result = host_impl_->PrepareToDraw(frame); draw_frame = draw_result == DRAW_SUCCESS; if (draw_frame) { - if (host_impl_->DrawLayers(frame)) { + if (absl::optional<EventMetricsSet> events_metrics = + host_impl_->DrawLayers(frame)) { if (scheduler_on_impl_thread_) { // Drawing implies we submitted a frame to the LayerTreeFrameSink. scheduler_on_impl_thread_->DidSubmitCompositorFrame( - frame->frame_token, host_impl_->TakeEventsMetrics(), + frame->frame_token, std::move(*events_metrics), frame->has_missing_content); } single_thread_client_->DidSubmitCompositorFrame();
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 63c96c71..2a7ffbcf 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1684,6 +1684,10 @@ ] } + if (is_android) { + deps += [ "//components/crash/android:crash_android" ] + } + if (is_chromeos_ash) { public_deps += [ "//ui/lottie" ] }
diff --git a/chrome/VERSION b/chrome/VERSION index 7ca1b4c0..29b6fb8 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=99 MINOR=0 -BUILD=4809 +BUILD=4813 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 17dc634..ebec747 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -907,6 +907,7 @@ ":base_module_java", ":chrome_app_java_resources", ":chrome_java", + ":chrome_jni_headers", ":chrome_public_android_manifest", ":delegate_public_impl_java", "$google_play_services_package:google_play_services_base_java", @@ -2525,7 +2526,6 @@ "java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploadJobService.java", "java/src/org/chromium/chrome/browser/crash/FirebaseConfig.java", "java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java", - "java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java", "java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java", "java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java", @@ -3860,7 +3860,6 @@ "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java", "java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java", "java/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceImpl.java", - "java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java", "java/src/org/chromium/chrome/browser/device_dialog/ChromeBluetoothChooserAndroidDelegate.java", "java/src/org/chromium/chrome/browser/device_dialog/ChromeBluetoothScanningPromptAndroidDelegate.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index ee9f0a7f..f04b10c7 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -113,6 +113,7 @@ "junit/src/org/chromium/chrome/browser/firstrun/TosDialogBehaviorSharedPrefInvalidatorUnitTest.java", "junit/src/org/chromium/chrome/browser/fonts/FontPreloaderUnitTest.java", "junit/src/org/chromium/chrome/browser/fullscreen/BrowserControlsManagerUnitTest.java", + "junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java", "junit/src/org/chromium/chrome/browser/gcore/GoogleApiClientHelperTest.java", "junit/src/org/chromium/chrome/browser/gsa/GSAStateUnitTest.java", "junit/src/org/chromium/chrome/browser/history/HistoryAdapterAccessibilityTest.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/DirectActionsIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/DirectActionsIntegrationTest.java index 49ed5d4..cf6ae57d 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/DirectActionsIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/DirectActionsIntegrationTest.java
@@ -40,6 +40,7 @@ import org.chromium.base.Callback; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.CriteriaNotSatisfiedException; import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; @@ -310,4 +311,70 @@ onView(withId(R.id.info_box_explanation)).check(matches(not(isDisplayed()))); onView(withText("Status message from previous run")).check(doesNotExist()); } + + /** + * Regression test for b/195417125. + */ + @Test + @MediumTest + @EnableFeatures({ChromeFeatureList.DIRECT_ACTIONS, AssistantFeatures.AUTOFILL_ASSISTANT_NAME, + AssistantFeatures.AUTOFILL_ASSISTANT_DIRECT_ACTIONS_NAME}) + public void + testLastTellMessageDisplayedAfterStop() { + ArrayList<ActionProto> list = new ArrayList<>(); + list.add(ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().addChoices( + PromptProto.Choice.newBuilder().setChip( + ChipProto.newBuilder().setText("Prompt")))) + .build()); + list.add(ActionProto.newBuilder() + .setTell(TellProto.newBuilder().setMessage("Last tell message")) + .build()); + list.add(ActionProto.newBuilder().setStop(StopProto.newBuilder()).build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + SupportedScriptProto.newBuilder() + .setPath("autofill_assistant_target_website.html") + .setPresentation(PresentationProto.newBuilder().setDirectAction( + DirectActionProto.newBuilder() + .addNames("some_direct_action") + .build())) + .build(), + list); + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script)); + testService.scheduleForInjection(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mDirectActionHandler.reportAvailableDirectActions(mDirectActionReporter); + Assert.assertThat(mDirectActionReporter.getDirectActions(), + containsInAnyOrder("fetch_website_actions")); + mDirectActionHandler.performDirectAction( + "fetch_website_actions", new Bundle(), mDirectActionResultCallback); + verify(mDirectActionResultCallback) + .onResult(argThat(bundle -> bundle.getBoolean("success"))); + + mDirectActionHandler.reportAvailableDirectActions(mDirectActionReporter); + Assert.assertThat(mDirectActionReporter.getDirectActions(), + containsInAnyOrder("fetch_website_actions", "some_direct_action")); + mDirectActionHandler.performDirectAction( + "some_direct_action", new Bundle(), mDirectActionResultCallback); + }); + waitUntilViewMatchesCondition(withText("Prompt"), isDisplayed()); + onView(withText("Prompt")).perform(click()); + waitUntilViewMatchesCondition(withText("Last tell message"), isDisplayed()); + // The last tell message should still be visible (and not disappear + // immediately) after the script stops. + try { + waitUntilViewMatchesCondition(withText("Last tell message"), not(isDisplayed()), 200); + } catch (AssertionError e) { + if (e.getCause() instanceof CriteriaNotSatisfiedException) { + // This is ok, the view is still there, the test succeeds. + return; + } + throw e; + } + throw new CriteriaNotSatisfiedException( + "Expected last tell message to be visible after stop"); + } }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java index 8863735..9b1c930 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
@@ -243,7 +243,7 @@ // clang-format off TestThreadUtils.runOnUiThreadBlocking(() -> mActivityTestRule.getActivity().getCurrentTabModel().setIndex( - lastIndex, TabSelectionType.FROM_USER) + lastIndex, TabSelectionType.FROM_USER, false) ); // clang-format on } @@ -253,7 +253,7 @@ // clang-format off TestThreadUtils.runOnUiThreadBlocking(() -> mActivityTestRule.getActivity().getCurrentTabModel().setIndex( - currentIndex, TabSelectionType.FROM_USER) + currentIndex, TabSelectionType.FROM_USER, false) ); // clang-format on }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 6efd559..17f5b7d1 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -387,7 +387,7 @@ } else { mTabModelSelector.getCurrentModel().setIndex( TabModelUtils.getTabIndexById(mTabModelSelector.getCurrentModel(), tabId), - TabSelectionType.FROM_USER); + TabSelectionType.FROM_USER, false); } } @@ -575,7 +575,7 @@ mTabModelSelector.getCurrentModel().setIndex( TabModelUtils.getTabIndexById( mTabModelSelector.getCurrentModel(), tab.getId()), - TabSelectionType.FROM_USER); + TabSelectionType.FROM_USER, false); } if (sTabClosedFromMapTabClosedFromMap.containsKey(tab.getId())) { @TabClosedFrom
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index e2a2fd9..ca72b121 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -494,7 +494,8 @@ if (fixPendingReadbacks && previousTabIndex != TabModel.INVALID_TAB_INDEX) { // clang-format off TestThreadUtils.runOnUiThreadBlocking(() -> - previousTabModel.setIndex(previousTabIndex, TabSelectionType.FROM_USER) + previousTabModel.setIndex( + previousTabIndex, TabSelectionType.FROM_USER, false) ); // clang-format on } @@ -504,7 +505,7 @@ if (fixPendingReadbacks) { // clang-format off TestThreadUtils.runOnUiThreadBlocking(() -> currentTabModel.setIndex( - currentTabIndex, TabSelectionType.FROM_USER) + currentTabIndex, TabSelectionType.FROM_USER, false) ); // clang-format on }
diff --git a/chrome/android/java/res/values-night/drawables.xml b/chrome/android/java/res/values-night/drawables.xml index 25bfe05..fdc0eb2 100644 --- a/chrome/android/java/res/values-night/drawables.xml +++ b/chrome/android/java/res/values-night/drawables.xml
@@ -3,7 +3,5 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <resources> - <drawable name="badge_update">@drawable/badge_update_light</drawable> - <drawable name="ic_error_24dp_filled">@drawable/ic_error_white_24dp_filled</drawable> <drawable name="shared_clipboard_zero_state">@drawable/shared_clipboard_zero_state_dark</drawable> </resources>
diff --git a/chrome/android/java/res/values/drawables.xml b/chrome/android/java/res/values/drawables.xml index 8569b73..1eb1c4a 100644 --- a/chrome/android/java/res/values/drawables.xml +++ b/chrome/android/java/res/values/drawables.xml
@@ -6,7 +6,5 @@ <resources> <drawable name="account_picker_background">@drawable/rounded_rectangle_surface_1</drawable> <drawable name="ntp_search_box">@drawable/modern_toolbar_text_box_background</drawable> - <drawable name="badge_update">@drawable/badge_update_dark</drawable> - <drawable name="ic_error_24dp_filled">@drawable/ic_error_grey800_24dp_filled</drawable> <drawable name="shared_clipboard_zero_state">@drawable/shared_clipboard_zero_state_light</drawable> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 7a42e48..5f3d0be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1391,7 +1391,7 @@ int tabToBeClobberedIndex = TabModelUtils.getTabIndexByUrl(tabModel, url); Tab tabToBeClobbered = tabModel.getTabAt(tabToBeClobberedIndex); if (tabToBeClobbered != null) { - TabModelUtils.setIndex(tabModel, tabToBeClobberedIndex); + TabModelUtils.setIndex(tabModel, tabToBeClobberedIndex, false); tabToBeClobbered.reload(); } else { launchIntent(loadUrlParams, externalAppId, true, intent); @@ -1413,13 +1413,13 @@ tabIndex = TabModelUtils.getTabIndexById(otherModel, tabIdToBringToFront); if (tabIndex != TabModel.INVALID_TAB_INDEX) { getTabModelSelector().selectModel(otherModel.isIncognito()); - TabModelUtils.setIndex(otherModel, tabIndex); + TabModelUtils.setIndex(otherModel, tabIndex, false); } else { Log.e(TAG, "Failed to bring tab to front because it doesn't exist."); return; } } else { - TabModelUtils.setIndex(tabModel, tabIndex); + TabModelUtils.setIndex(tabModel, tabIndex, false); } break; case TabOpenType.CLOBBER_CURRENT_TAB: @@ -1448,7 +1448,8 @@ if (tab.getUrl().getSpec().equals(url) || tab.getUrl().getSpec().equals(IntentUtils.safeGetStringExtra( intent, TabOpenType.REUSE_TAB_ORIGINAL_URL_STRING))) { - tabModel.setIndex(matchingTabIndex, TabSelectionType.FROM_USER); + tabModel.setIndex( + matchingTabIndex, TabSelectionType.FROM_USER, false); tab.loadUrl(loadUrlParams); loaded = true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java b/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java index aa2505a..ce7e4968 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java
@@ -262,11 +262,11 @@ int numCode = keyCode - KeyEvent.KEYCODE_0; if (numCode > 0 && numCode <= Math.min(tabCount, 8)) { // Ctrl+1 to Ctrl+8: select tab by index - TabModelUtils.setIndex(currentTabModel, numCode - 1); + TabModelUtils.setIndex(currentTabModel, numCode - 1, false); return true; } else if (numCode == 9 && tabCount != 0) { // Ctrl+9: select last tab - TabModelUtils.setIndex(currentTabModel, tabCount - 1); + TabModelUtils.setIndex(currentTabModel, tabCount - 1, false); return true; } } @@ -277,7 +277,7 @@ case KeyEvent.KEYCODE_BUTTON_R1: if (tabSwitchingEnabled && tabCount > 1) { TabModelUtils.setIndex( - currentTabModel, (currentTabModel.index() + 1) % tabCount); + currentTabModel, (currentTabModel.index() + 1) % tabCount, false); } return true; case CTRL | SHIFT | KeyEvent.KEYCODE_TAB: @@ -285,7 +285,7 @@ case KeyEvent.KEYCODE_BUTTON_L1: if (tabSwitchingEnabled && tabCount > 1) { TabModelUtils.setIndex(currentTabModel, - (currentTabModel.index() + tabCount - 1) % tabCount); + (currentTabModel.index() + tabCount - 1) % tabCount, false); } return true; case CTRL | KeyEvent.KEYCODE_W:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelAdapter.java index 196d6ee9..b6d08636 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelAdapter.java
@@ -45,8 +45,8 @@ @Override public void tabSelected(int tab) { if (mListener != null) mListener.showTab(tab); - TabModelUtils.setIndex( - mActualTabModel, TabModelUtils.getTabIndexById(mActualTabModel, tab)); + TabModelUtils.setIndex(mActualTabModel, + TabModelUtils.getTabIndexById(mActualTabModel, tab), false); notifyDataSetChanged(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java index ebee6835..3001dc3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java
@@ -222,7 +222,7 @@ TabModel model = mTabModelSelectorSupplier.get().getModel(mTab.isIncognito()); int index = model.indexOf(mTab); if (index == TabModel.INVALID_TAB_INDEX) return; - TabModelUtils.setIndex(model, index); + TabModelUtils.setIndex(model, index, false); // Do nothing if the mActivity is visible (STOPPED is the only valid invisible state as we // explicitly check isActivityFinishingOrDestroyed above).
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ReparentingTask.java b/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ReparentingTask.java index b6a061ca..fce01ed8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ReparentingTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/tab_activity_glue/ReparentingTask.java
@@ -26,7 +26,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabDelegateFactory; -import org.chromium.chrome.browser.tab.TabImpl; +import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabReparentingParams; import org.chromium.content_public.browser.WebContents; @@ -168,7 +168,9 @@ public void finish(@NonNull Delegate delegate, @Nullable Runnable finalizeCallback) { delegate.getCompositorViewHolder().prepareForTabReparenting(); attach(delegate.getWindowAndroid(), delegate.getTabDelegateFactory()); - ((TabImpl) mTab).setIsTabStateDirty(true); + if (!mTab.isDestroyed()) { + TabStateAttributes.from(mTab).setIsTabStateDirty(true); + } if (finalizeCallback != null) finalizeCallback.run(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java index 5aeac61..7c8f299 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
@@ -35,11 +35,12 @@ import org.chromium.chrome.browser.ProductConfig; import org.chromium.chrome.browser.crash.ApplicationStatusTracker; import org.chromium.chrome.browser.crash.FirebaseConfig; -import org.chromium.chrome.browser.crash.PureJavaExceptionHandler; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.language.GlobalAppLocaleController; import org.chromium.chrome.browser.metrics.UmaUtils; +import org.chromium.components.crash.PureJavaExceptionHandler; +import org.chromium.components.crash.PureJavaExceptionHandler.JavaExceptionReporter; import org.chromium.components.embedder_support.application.FontPreloadingWorkaround; import org.chromium.components.module_installer.util.ModuleUtil; import org.chromium.components.version_info.VersionConstants; @@ -204,7 +205,13 @@ if (!isIsolatedProcess) { // Incremental install disables process isolation, so things in this block will // actually be run for incremental apks, but not normal apks. - PureJavaExceptionHandler.installHandler(); + PureJavaExceptionHandler.installHandler(() -> { + // PureJavaExceptionReporter may be in the chrome module, so load by reflection + // from there. + return (JavaExceptionReporter) SplitCompatUtils.newInstance( + SplitCompatUtils.createChromeContext(ContextUtils.getApplicationContext()), + "org.chromium.chrome.browser.crash.PureJavaExceptionReporter"); + }); } TraceEvent.end(ATTACH_BASE_CONTEXT_EVENT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java index 06ab7e38..88fae7d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
@@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.google.common.primitives.UnsignedLongs; import com.google.protobuf.InvalidProtocolBufferException; import org.chromium.base.ContextUtils; @@ -19,11 +20,17 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.commerce.shopping_list.ShoppingFeatures; import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim; import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta; import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkType; +import org.chromium.chrome.browser.power_bookmarks.ShoppingSpecifics; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.read_later.ReadingListUtils; +import org.chromium.chrome.browser.subscriptions.CommerceSubscription; +import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceFactory; +import org.chromium.chrome.browser.subscriptions.SubscriptionsManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; @@ -35,6 +42,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; /** @@ -51,6 +59,8 @@ new ArrayList<DelayedBookmarkCallback>(); private final ObserverList<BookmarkModelObserver> mObservers = new ObserverList<BookmarkModelObserver>(); + private SubscriptionsManager mSubscriptionManager; + private SubscriptionsManager.SubscriptionObserver mSubscriptionsObserver; /** * Interface for callback object for fetching bookmarks and folder hierarchy. @@ -257,9 +267,11 @@ /**@return Whether this bookmark can be moved */ public boolean isMovable() { - if (ReadingListUtils.isSwappableReadingListItem(mId)) { - return true; - } + return ReadingListUtils.isSwappableReadingListItem(mId) || isReorderable(); + } + + /**@return Whether this bookmark can be moved */ + public boolean isReorderable() { return isEditable() && mId.getType() == BookmarkType.NORMAL; } @@ -303,6 +315,25 @@ mNativeBookmarkBridge = BookmarkBridgeJni.get().init(BookmarkBridge.this, profile); mIsDoingExtensiveChanges = BookmarkBridgeJni.get().isDoingExtensiveChanges( mNativeBookmarkBridge, BookmarkBridge.this); + mSubscriptionsObserver = new SubscriptionsManager.SubscriptionObserver() { + @Override + public void onSubscribe(List<CommerceSubscription> subscriptions) {} + + @Override + public void onUnsubscribe(List<CommerceSubscription> subscriptions) { + removeExplicitShoppingSubscriptions(subscriptions); + } + }; + if (ShoppingFeatures.isShoppingListEnabled()) { + mSubscriptionManager = new CommerceSubscriptionsServiceFactory() + .getForLastUsedProfile() + .getSubscriptionsManager(); + } + } + + @VisibleForTesting + SubscriptionsManager.SubscriptionObserver getSubscriptionObserver() { + return mSubscriptionsObserver; } /** @@ -317,6 +348,10 @@ mDelayedBookmarkCallbacks.clear(); } mObservers.clear(); + + if (mSubscriptionManager != null) { + mSubscriptionManager.removeObserver(mSubscriptionsObserver); + } } /** Returns whether the bridge has been destroyed. */ @@ -618,6 +653,61 @@ } /** + * Disable price tracking for the list of subscriptions. This flips the bit in ShoppingSpecifics + * but does not actually unsubscribe from the subscription service -- this assumes that is + * already done. + * TODO(1284730): This should live somewhere other than BookmarkBridge. + * + * @param subscriptions The list of subscriptions to disable. + */ + private void removeExplicitShoppingSubscriptions(List<CommerceSubscription> subscriptions) { + if (subscriptions == null) return; + + List<BookmarkId> products = searchBookmarks("", null, PowerBookmarkType.SHOPPING, -1); + if (products == null || products.size() == 0) return; + + // Put the offer and cluster IDs into a map so they can be quickly checked. + HashSet<Long> offerIdMap = new HashSet<>(); + HashSet<Long> clusterIdMap = new HashSet<>(); + for (CommerceSubscription c : subscriptions) { + // Ensure the subscription is explicit. + if (c == null + || !c.getManagementType().equals( + CommerceSubscription.SubscriptionManagementType.USER_MANAGED)) { + continue; + } + + if (c.getTrackingIdType().equals(CommerceSubscription.TrackingIdType.OFFER_ID)) { + offerIdMap.add(UnsignedLongs.parseUnsignedLong(c.getTrackingId())); + } else if (c.getTrackingIdType().equals( + CommerceSubscription.TrackingIdType.PRODUCT_CLUSTER_ID)) { + clusterIdMap.add(UnsignedLongs.parseUnsignedLong(c.getTrackingId())); + } + } + + // Look at all the products the user has saved to find any of the above product or cluster + // IDs. + for (BookmarkId product : products) { + PowerBookmarkMeta meta = getPowerBookmarkMeta(product); + if (meta.getType() != PowerBookmarkType.SHOPPING) continue; + + ShoppingSpecifics specifics = meta.getShoppingSpecifics(); + if (offerIdMap.contains(specifics.getOfferId()) + || clusterIdMap.contains(specifics.getProductClusterId())) { + // Reset the meta using a copy of the existing one, but set the price tracking flag + // to false. + setPowerBookmarkMeta(product, + PowerBookmarkMeta.newBuilder(meta) + .setShoppingSpecifics( + ShoppingSpecifics.newBuilder(meta.getShoppingSpecifics()) + .setIsPriceTracked(false) + .build()) + .build()); + } + } + } + + /** * Gets the child of a folder at the specific position. * @param folderId Id of the parent folder * @param index Position of child among all children in folder @@ -882,6 +972,8 @@ assert title != null; assert url != null; + recordBookmarkAdded(); + if (TextUtils.isEmpty(title)) title = url.getSpec(); return BookmarkBridgeJni.get().addBookmark( mNativeBookmarkBridge, BookmarkBridge.this, parent, index, title, url); @@ -908,11 +1000,18 @@ assert title != null; assert url != null; + recordBookmarkAdded(); + if (TextUtils.isEmpty(title)) title = url.getSpec(); return BookmarkBridgeJni.get().addPowerBookmark( mNativeBookmarkBridge, this, webContents, parent, index, title, url); } + /** Record the user action for adding a bookmark. */ + private void recordBookmarkAdded() { + RecordUserAction.record("BookmarkAdded"); + } + @Deprecated // Only included until internal repository is updated. public BookmarkId addBookmark(BookmarkId parent, int index, String title, String url) { return addBookmark(parent, index, title, new GURL(url));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java index 88f3e5b..5956219 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -451,7 +451,7 @@ */ void moveUpOne(BookmarkId bookmarkId) { int pos = getPositionForBookmark(bookmarkId); - assert isOrderable(getItemByPosition(pos)); + assert isReorderable(getItemByPosition(pos)); mElements.remove(pos); mElements.add(pos - 1, BookmarkListEntry.createBookmarkEntry( @@ -465,7 +465,7 @@ */ void moveDownOne(BookmarkId bookmarkId) { int pos = getPositionForBookmark(bookmarkId); - assert isOrderable(getItemByPosition(pos)); + assert isReorderable(getItemByPosition(pos)); mElements.remove(pos); mElements.add(pos + 1, BookmarkListEntry.createBookmarkEntry( @@ -593,9 +593,9 @@ return endIndex; } - private boolean isOrderable(BookmarkListEntry entry) { + private boolean isReorderable(BookmarkListEntry entry) { return entry != null && entry.getBookmarkItem() != null - && entry.getBookmarkItem().isMovable(); + && entry.getBookmarkItem().isReorderable(); } @Override @@ -608,7 +608,7 @@ @Override @VisibleForTesting public boolean isPassivelyDraggable(ViewHolder viewHolder) { - return isOrderable(getItemByHolder(viewHolder)); + return isReorderable(getItemByHolder(viewHolder)); } @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java index 086d0ea..cab023e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
@@ -114,7 +114,7 @@ mMoreIcon.setVisibility(GONE); if (mDelegate.getDragStateDelegate().getDragActive()) { - mDragHandle.setVisibility(bookmarkItem.isMovable() ? VISIBLE : GONE); + mDragHandle.setVisibility(bookmarkItem.isReorderable() ? VISIBLE : GONE); mDragHandle.setEnabled(isItemSelected()); } else { mMoreIcon.setVisibility(bookmarkItem.isEditable() ? VISIBLE : GONE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index be37c7f..4e6f1ec6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -450,7 +450,8 @@ if (mNextTabId != Tab.INVALID_TAB_ID) { TabModel model = mTabModelSelector.getModelForTabId(mNextTabId); if (model != null) { - TabModelUtils.setIndex(model, TabModelUtils.getTabIndexById(model, mNextTabId)); + TabModelUtils.setIndex( + model, TabModelUtils.getTabIndexById(model, mNextTabId), false); } mNextTabId = Tab.INVALID_TAB_ID; }
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 7cd98e0..fbbec30 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
@@ -878,7 +878,7 @@ if (tab == null || tab.isDying()) return; int newIndex = TabModelUtils.getTabIndexById(mModel, tab.getId()); - TabModelUtils.setIndex(mModel, newIndex); + TabModelUtils.setIndex(mModel, newIndex, false); } /** @@ -1347,7 +1347,7 @@ // 4. Select this tab so that it is always in the foreground. TabModelUtils.setIndex( - mModel, TabModelUtils.getTabIndexById(mModel, mInteractingTab.getId())); + mModel, TabModelUtils.getTabIndexById(mModel, mInteractingTab.getId()), false); // 5. Fast expand to make sure this tab is visible. If tabs are not cascaded, the selected // tab will already be visible, so there's no need to fast expand to make it visible. @@ -1614,7 +1614,7 @@ private void showTabMenu(StripLayoutTab anchorTab) { // 1. Bring the anchor tab to the foreground. int tabIndex = TabModelUtils.getTabIndexById(mModel, anchorTab.getId()); - TabModelUtils.setIndex(mModel, tabIndex); + TabModelUtils.setIndex(mModel, tabIndex, false); // 2. Anchor the popupMenu to the view associated with the tab View tabView = TabModelUtils.getCurrentTab(mModel).getView();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java index 31ed155..dbf31ec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java
@@ -24,6 +24,7 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; import org.chromium.components.crash.CrashKeys; +import org.chromium.components.crash.PureJavaExceptionHandler; import org.chromium.components.version_info.VersionInfo; import java.io.File;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java index 4b0f219..644bf4d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser.customtabs.features.toolbar; import android.app.Activity; +import android.content.res.ColorStateList; +import androidx.annotation.ColorInt; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -16,11 +18,15 @@ import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar.CustomTabTabObserver; import org.chromium.chrome.browser.dependency_injection.ActivityScope; +import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; import org.chromium.chrome.browser.toolbar.ToolbarManager; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; +import org.chromium.ui.util.ColorUtils; import org.chromium.url.GURL; import java.lang.annotation.Retention; @@ -160,14 +166,20 @@ if (mToolbarManager == null) return; mToolbarManager.setShouldUpdateToolbarPrimaryColor(true); - mToolbarManager.onThemeColorChanged(computeColor(), false); + final Tab tab = mTabProvider.getTab(); + final @ToolbarColorType int toolbarColorType = + computeToolbarColorType(mIntentDataProvider, mUseTabThemeColor, tab); + final @ColorInt int color = computeColor(tab, toolbarColorType); + final @BrandedColorScheme int brandedColorScheme = + computeBrandedColorScheme(toolbarColorType, color); + final ColorStateList tint = + ThemeUtils.getThemedToolbarIconTint(mActivity, brandedColorScheme); + mToolbarManager.onThemeColorChanged(color, false); + mToolbarManager.onTintChanged(tint, brandedColorScheme); mToolbarManager.setShouldUpdateToolbarPrimaryColor(false); } - private int computeColor() { - Tab tab = mTabProvider.getTab(); - @ToolbarColorType - int toolbarColorType = computeToolbarColorType(mIntentDataProvider, mUseTabThemeColor, tab); + private @ColorInt int computeColor(Tab tab, @ToolbarColorType int toolbarColorType) { switch (toolbarColorType) { case ToolbarColorType.THEME_COLOR: return mTopUiThemeColorProvider.calculateColor(tab, tab.getThemeColor()); @@ -179,6 +191,23 @@ return getDefaultColor(); } + private @BrandedColorScheme int computeBrandedColorScheme( + @ToolbarColorType int toolbarColorType, @ColorInt int toolbarColor) { + switch (toolbarColorType) { + case ToolbarColorType.THEME_COLOR: + return OmniboxResourceProvider.getBrandedColorScheme( + mActivity, mIntentDataProvider.isIncognito(), toolbarColor); + case ToolbarColorType.DEFAULT_COLOR: + return mIntentDataProvider.isIncognito() ? BrandedColorScheme.INCOGNITO + : BrandedColorScheme.APP_DEFAULT; + case ToolbarColorType.INTENT_TOOLBAR_COLOR: + return ColorUtils.shouldUseLightForegroundOnBackground(toolbarColor) + ? BrandedColorScheme.DARK_BRANDED_THEME + : BrandedColorScheme.LIGHT_BRANDED_THEME; + } + return BrandedColorScheme.APP_DEFAULT; + } + private int getDefaultColor() { return ChromeColors.getDefaultThemeColor(mActivity, mIntentDataProvider.isIncognito()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 78c793c0..604a4e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -8,7 +8,6 @@ import android.os.Build; import android.os.Bundle; import android.os.SystemClock; -import android.text.TextUtils; import android.view.View; import android.view.ViewTreeObserver.OnPreDrawListener; @@ -479,9 +478,6 @@ if (mFreProperties.getBoolean(OPEN_ADVANCED_SYNC_SETTINGS)) { recordFreProgressHistogram(MobileFreProgress.SYNC_CONSENT_SETTINGS_LINK_CLICK); } - recordFreProgressHistogram(TextUtils.isEmpty(mResultSyncConsentAccountName) - ? MobileFreProgress.SYNC_CONSENT_DISMISSED - : MobileFreProgress.SYNC_CONSENT_ACCEPTED); FirstRunFlowSequencer.markFlowAsCompleted(mResultSyncConsentAccountName, mFreProperties.getBoolean(OPEN_ADVANCED_SYNC_SETTINGS)); @@ -541,12 +537,14 @@ public void refuseSync() { mResultSyncConsentAccountName = null; mFreProperties.putBoolean(OPEN_ADVANCED_SYNC_SETTINGS, false); + recordFreProgressHistogram(MobileFreProgress.SYNC_CONSENT_DISMISSED); } @Override public void acceptSync(String accountName, boolean openSettings) { mResultSyncConsentAccountName = accountName; mFreProperties.putBoolean(OPEN_ADVANCED_SYNC_SETTINGS, openSettings); + recordFreProgressHistogram(MobileFreProgress.SYNC_CONSENT_ACCEPTED); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java index 1af3b73..851b7e79 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
@@ -357,9 +357,14 @@ * @param controlsHidden {@code true} if the controls are now hidden. */ private void maybeEnterFullscreenFromPendingState(boolean controlsHidden) { - if (!controlsHidden) return; - if (mTab != null && mPendingFullscreenOptions != null) { - enterFullscreen(mTab, mPendingFullscreenOptions); + if (!controlsHidden || mTab == null) return; + if (mPendingFullscreenOptions != null) { + if (mPendingFullscreenOptions.canceled()) { + // Restore browser controls if the fullscreen process got canceled. + TabBrowserControlsConstraintsHelper.update(mTab, BrowserControlsState.SHOWN, true); + } else { + enterFullscreen(mTab, mPendingFullscreenOptions); + } mPendingFullscreenOptions = null; } } @@ -375,7 +380,7 @@ } else { assert mPendingFullscreenOptions != null : "No content previously set to fullscreen."; - mPendingFullscreenOptions = null; + mPendingFullscreenOptions.setCanceled(); } mWebContentsInFullscreen = null; mContentViewInFullscreen = null; @@ -639,4 +644,8 @@ if (mActiveTabObserver != null) mActiveTabObserver.destroy(); if (mTabFullscreenObserver != null) mTabFullscreenObserver.destroy(); } + + void setTabForTesting(Tab tab) { + mTab = tab; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java index 3f4fb8a6..0a3da97 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
@@ -229,6 +229,7 @@ R.string.accessibility_toolbar_btn_menu_update; mMenuUiState.buttonState.darkBadgeIcon = R.drawable.badge_update_dark; mMenuUiState.buttonState.lightBadgeIcon = R.drawable.badge_update_light; + mMenuUiState.buttonState.adaptiveBadgeIcon = R.drawable.badge_update; } mMenuUiState.itemState = new MenuItemState(); @@ -258,6 +259,7 @@ mMenuUiState.buttonState.darkBadgeIcon = R.drawable.ic_error_grey800_24dp_filled; mMenuUiState.buttonState.lightBadgeIcon = R.drawable.ic_error_white_24dp_filled; + mMenuUiState.buttonState.adaptiveBadgeIcon = R.drawable.ic_error_24dp_filled; } mMenuUiState.itemState = new MenuItemState();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java index 8c8ea35d..243e7f6b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -60,7 +60,6 @@ */ public static void shareDirectly( @NonNull ShareParams params, @NonNull ComponentName component) { - recordShareSource(ShareSourceAndroid.DIRECT_SHARE); Intent intent = getShareLinkIntent(params); intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); @@ -79,6 +78,7 @@ ComponentName component = getLastShareComponentName(); if (component == null) return; assert params.getCallback() == null; + recordShareSource(ShareSourceAndroid.DIRECT_SHARE); shareDirectly(params, component); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java index e7311b6..d3be7da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tab; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; import org.chromium.base.UserData; @@ -184,6 +185,11 @@ return mVisibilityDelegate == null ? BrowserControlsState.BOTH : mVisibilityDelegate.get(); } + @VisibleForTesting + public static void setForTesting(Tab tab, TabBrowserControlsConstraintsHelper helper) { + tab.getUserDataHost().setUserData(USER_DATA_KEY, helper); + } + @NativeMethods interface Natives { long init(TabBrowserControlsConstraintsHelper caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 1aac96f..e6ef840 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -135,9 +135,6 @@ private boolean mIsClosing; private boolean mIsShowingErrorPage; - /** Whether or not the TabState has changed. */ - private boolean mIsTabStateDirty = true; - /** * Saves how this tab was launched (from a link, external app, etc) so that * we can determine the different circumstances in which it should be @@ -419,7 +416,7 @@ @Override public void freezeNativePage() { if (mNativePage == null || mNativePage.isFrozen() - || mNativePage.getView().getParent() == null) { + || mNativePage.getView().getParent() != null) { return; } mNativePage = FrozenNativePage.freeze(mNativePage); @@ -785,18 +782,6 @@ return !(activity instanceof ChromeActivity); } - /** - * @return Whether the TabState representing this Tab has been updated. - */ - public boolean isTabStateDirty() { - return mIsTabStateDirty; - } - - @Override - public void setIsTabStateDirty(boolean isDirty) { - mIsTabStateDirty = isDirty; - } - @Override public void setIsTabSaveEnabled(boolean isTabSaveEnabled) { mIsTabSaveEnabledSupplier.set(isTabSaveEnabled); @@ -1058,7 +1043,6 @@ * @param url URL that was loaded. */ void didFinishPageLoad(GURL url) { - mIsTabStateDirty = true; updateTitle(); for (TabObserver observer : mObservers) observer.onPageLoadFinished(this, url); @@ -1119,7 +1103,6 @@ * Called when navigation entries were removed. */ void notifyNavigationEntriesDeleted() { - mIsTabStateDirty = true; for (TabObserver observer : mObservers) observer.onNavigationEntriesDeleted(this); } @@ -1215,7 +1198,6 @@ void updateTitle(String title) { if (TextUtils.equals(CriticalPersistedTabData.from(this).getTitle(), title)) return; - mIsTabStateDirty = true; CriticalPersistedTabData.from(this).setTitle(title); notifyPageTitleChanged(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index acbc4424..562656b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -334,7 +334,9 @@ if (!navigation.hasCommitted()) return; if (navigation.isInPrimaryMainFrame()) { - mTab.setIsTabStateDirty(true); + if (!mTab.isDestroyed()) { + TabStateAttributes.from(mTab).setIsTabStateDirty(true); + } mTab.updateTitle(); mTab.handleDidFinishNavigation(navigation.getUrl(), navigation.pageTransition()); mTab.setIsShowingErrorPage(navigation.isErrorPage()); @@ -378,7 +380,9 @@ @Override public void navigationEntriesChanged() { - mTab.setIsTabStateDirty(true); + if (!mTab.isDestroyed()) { + TabStateAttributes.from(mTab).setIsTabStateDirty(true); + } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java index 584af53..93f322f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -144,7 +144,7 @@ if (hasValidTab() && mIndex == INVALID_TAB_INDEX) { // Actually select the first tab if it is the active model, otherwise just set mIndex. if (isActiveModel()) { - TabModelUtils.setIndex(this, 0); + TabModelUtils.setIndex(this, 0, false); } else { mIndex = 0; } @@ -212,7 +212,7 @@ for (TabModelObserver obs : mObservers) obs.didAddTab(tab, type, creationState); // setIndex takes care of making sure the appropriate model is active. - if (selectTab) setIndex(newIndex, TabSelectionType.FROM_NEW); + if (selectTab) setIndex(newIndex, TabSelectionType.FROM_NEW, false); } finally { TraceEvent.end("TabModelImpl.addTab"); } @@ -347,7 +347,7 @@ // If we're the active model call setIndex to actually select this tab, otherwise just // set mIndex but don't kick off everything that happens when calling setIndex(). if (activeModel) { - TabModelUtils.setIndex(this, insertIndex); + TabModelUtils.setIndex(this, insertIndex, false); } else { mIndex = insertIndex; } @@ -532,7 +532,7 @@ // This function is complex and its behavior depends on persisted state, including mIndex. @Override - public void setIndex(int i, final @TabSelectionType int type) { + public void setIndex(int i, final @TabSelectionType int type, boolean skipLoadingTab) { try { TraceEvent.begin("TabModelImpl.setIndex"); int lastId = getLastId(type); @@ -549,7 +549,7 @@ Tab tab = TabModelUtils.getCurrentTab(this); - mModelDelegate.requestToShowTab(tab, type); + if (!skipLoadingTab || tab == null) mModelDelegate.requestToShowTab(tab, type); if (tab != null) { for (TabModelObserver obs : mObservers) obs.didSelectTab(tab, type, lastId); @@ -636,7 +636,7 @@ if (nextIsIncognito != isIncognito()) mIndex = indexOf(adjacentTabInModel); TabModel nextModel = mModelDelegate.getModel(nextIsIncognito); - nextModel.setIndex(nextTabIndex, selectionType); + nextModel.setIndex(nextTabIndex, selectionType, false); } else { mIndex = nextTabIndex; } @@ -873,7 +873,7 @@ // then try to restore the tab from the native tab restore service. mRecentlyClosedBridge.openRecentlyClosedTab(); // If there is only one tab, select it. - if (getCount() == 1) setIndex(0, TabSelectionType.FROM_NEW); + if (getCount() == 1) setIndex(0, TabSelectionType.FROM_NEW, false); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java index c947c2e..3b7fb7e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -97,7 +97,7 @@ */ @CalledByNative private void setIndex(int index) { - TabModelUtils.setIndex(this, index); + TabModelUtils.setIndex(this, index, false); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java index 637f70f..995dc86 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -195,7 +195,7 @@ super.selectModel(incognito); TabModel newModel = getCurrentModel(); if (oldModel != newModel) { - TabModelUtils.setIndex(newModel, newModel.index()); + TabModelUtils.setIndex(newModel, newModel.index(), false); // Make the call to notifyDataSetChanged() after any delayed events // have had a chance to fire. Otherwise, this may result in some
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index 5e0f633..393785a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -41,9 +41,9 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabIdManager; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabState; +import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tab.TabStateExtractor; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData; import org.chromium.chrome.browser.tab.state.FilePersistedTabDataStorage; @@ -130,6 +130,9 @@ new TabModelSelectorTabObserver(mTabModelSelector) { @Override public void onNavigationEntriesDeleted(Tab tab) { + if (!tab.isDestroyed()) { + TabStateAttributes.from(tab).setIsTabStateDirty(true); + } addTabToSaveQueue(tab); } @@ -142,6 +145,20 @@ public void onRootIdChanged(Tab tab, int newRootId) { addTabToSaveQueue(tab); } + + @Override + public void onPageLoadFinished(Tab tab, GURL url) { + if (!tab.isDestroyed()) { + TabStateAttributes.from(tab).setIsTabStateDirty(true); + } + } + + @Override + public void onTitleUpdated(Tab tab) { + if (!tab.isDestroyed()) { + TabStateAttributes.from(tab).setIsTabStateDirty(true); + } + } }; mTabModelObserver = new TabModelObserver() { @@ -717,7 +734,8 @@ boolean wasIncognitoTabModelSelected = mTabModelSelector.isIncognitoSelected(); int selectedModelTabCount = mTabModelSelector.getCurrentModel().getCount(); - TabModelUtils.setIndex(model, TabModelUtils.getTabIndexById(model, tabId)); + // TODO(hanxi): Sets the correct value for skipLoadingTab. + TabModelUtils.setIndex(model, TabModelUtils.getTabIndexById(model, tabId), false); boolean isIncognitoTabModelSelected = mTabModelSelector.isIncognitoSelected(); // Setting the index will cause the tab's model to be selected. Set it back to the model @@ -807,8 +825,8 @@ } private void addTabToSaveQueueIfApplicable(Tab tab) { - if (tab == null) return; - if (mTabsToSave.contains(tab) || !((TabImpl) tab).isTabStateDirty() + if (tab == null || tab.isDestroyed()) return; + if (mTabsToSave.contains(tab) || !TabStateAttributes.from(tab).isTabStateDirty() || isTabUrlContentScheme(tab)) { return; } @@ -1249,7 +1267,9 @@ protected void onPostExecute(Void v) { if (mDestroyed || isCancelled()) return; if (mStateSaved) { - ((TabImpl) mTab).setIsTabStateDirty(false); + if (!mTab.isDestroyed()) { + TabStateAttributes.from(mTab).setIsTabStateDirty(false); + } mTab.setIsTabSaveEnabled(isCriticalPersistedTabDataEnabled()); } mSaveTabTask = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java index 56f14422..f0d145cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java
@@ -5,12 +5,15 @@ package org.chromium.chrome.browser.toolbar; import android.content.Context; +import android.content.res.ColorStateList; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider.IncognitoStateObserver; import org.chromium.chrome.browser.theme.ThemeColorProvider; +import org.chromium.chrome.browser.theme.ThemeUtils; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; /** A ThemeColorProvider for the app theme (incognito or standard theming). */ @@ -91,6 +94,12 @@ updatePrimaryColor( shouldUseIncognitoBackground ? mIncognitoPrimaryColor : mStandardPrimaryColor, false); + final @BrandedColorScheme int brandedColorScheme = shouldUseIncognitoBackground + ? BrandedColorScheme.INCOGNITO + : BrandedColorScheme.APP_DEFAULT; + final ColorStateList iconTint = + ThemeUtils.getThemedToolbarIconTint(mActivityContext, brandedColorScheme); + updateTint(iconTint, brandedColorScheme); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 1be1aae..706c01b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -138,6 +138,7 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.browser.ui.system.StatusBarColorController; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.browser.vr.VrModuleProvider; @@ -1656,8 +1657,12 @@ } @Override - public void onTintChanged(ColorStateList tint, boolean useLight) { + public void onTintChanged(ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { updateBookmarkButtonStatus(); + + if (mShouldUpdateToolbarPrimaryColor) { + mCustomTabThemeColorProvider.setTint(tint, brandedColorScheme); + } } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ActivityTabProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ActivityTabProviderTest.java index 9e924e2..f93b6db 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ActivityTabProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ActivityTabProviderTest.java
@@ -175,7 +175,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { // Select the original tab without switching layouts. mActivity.getTabModelSelector().getCurrentModel().setIndex( - 0, TabSelectionType.FROM_USER); + 0, TabSelectionType.FROM_USER, false); }); mActivityTabChangedHelper.waitForCallback(callCount);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 69cffe1..234825c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -1096,7 +1096,7 @@ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { - TabModelUtils.setIndex(tabModel, tabModel.indexOf(tab)); + TabModelUtils.setIndex(tabModel, tabModel.indexOf(tab), false); } }); pageLoadedCallbacks[i].waitForCallback(0);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java index 2d07783b5..bc8e8a3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
@@ -22,7 +22,11 @@ import org.chromium.base.test.util.RequiresRestart; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta; +import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkType; +import org.chromium.chrome.browser.power_bookmarks.ShoppingSpecifics; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.subscriptions.CommerceSubscription; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeBrowserTestRule; import org.chromium.chrome.test.util.BookmarkTestUtil; @@ -368,4 +372,39 @@ "https://www.google.com/", readingListItem.getUrl().getValidSpecOrEmpty()); Assert.assertEquals("a", readingListItem.getTitle()); } + + @Test + @SmallTest + @UiThreadTest + @Feature({"Bookmark"}) + @Features.EnableFeatures({ChromeFeatureList.SHOPPING_LIST}) + public void testProductUnsubscribeUpdatesBookmark() { + BookmarkId bookmark = + mBookmarkBridge.addBookmark(mMobileNode, 0, "a", new GURL("http://a.com")); + verifyBookmark(bookmark, "a", "http://a.com/", false, mMobileNode); + + long offerId = 12345L; + ShoppingSpecifics specifics = + ShoppingSpecifics.newBuilder().setIsPriceTracked(true).setOfferId(offerId).build(); + PowerBookmarkMeta meta = PowerBookmarkMeta.newBuilder() + .setType(PowerBookmarkType.SHOPPING) + .setShoppingSpecifics(specifics) + .build(); + mBookmarkBridge.setPowerBookmarkMeta(bookmark, meta); + + // Check that the price is tracked prior to sending an unsubscribe event. + PowerBookmarkMeta originalMeta = mBookmarkBridge.getPowerBookmarkMeta(bookmark); + Assert.assertTrue(originalMeta.getShoppingSpecifics().getIsPriceTracked()); + + ArrayList<CommerceSubscription> subscriptions = new ArrayList<>(); + subscriptions.add(new CommerceSubscription( + CommerceSubscription.CommerceSubscriptionType.PRICE_TRACK, Long.toString(offerId), + CommerceSubscription.SubscriptionManagementType.USER_MANAGED, + CommerceSubscription.TrackingIdType.OFFER_ID)); + mBookmarkBridge.getSubscriptionObserver().onUnsubscribe(subscriptions); + + // The product with the unsubscribed ID should no longer be price tracked. + PowerBookmarkMeta updatedMeta = mBookmarkBridge.getPowerBookmarkMeta(bookmark); + Assert.assertFalse(updatedMeta.getShoppingSpecifics().getIsPriceTracked()); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index a0ae671..9774c4c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -193,10 +193,10 @@ mTabModelSelector = new MockTabModelSelector(standardTabCount, incognitoTabCount, this); if (standardIndexSelected != TabModel.INVALID_TAB_INDEX) { - TabModelUtils.setIndex(mTabModelSelector.getModel(false), standardIndexSelected); + TabModelUtils.setIndex(mTabModelSelector.getModel(false), standardIndexSelected, false); } if (incognitoIndexSelected != TabModel.INVALID_TAB_INDEX) { - TabModelUtils.setIndex(mTabModelSelector.getModel(true), incognitoIndexSelected); + TabModelUtils.setIndex(mTabModelSelector.getModel(true), incognitoIndexSelected, false); } mTabModelSelector.selectModel(incognitoSelected); Assert.assertNotNull(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java index 455af84..673d68c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -117,7 +117,8 @@ @Override public void run() { TabModelUtils.setIndex( - sActivityTestRule.getActivity().getTabModelSelector().getModel(false), 0); + sActivityTestRule.getActivity().getTabModelSelector().getModel(false), 0, + false); } }); InstrumentationRegistry.getInstrumentation().waitForIdleSync();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 413569d..45ab0b33 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -1983,7 +1983,7 @@ TabModelUtils.getCurrentTab(sActivityTestRule.getActivity().getCurrentTabModel()); TestThreadUtils.runOnUiThreadBlocking(() -> { - TabModelUtils.setIndex(sActivityTestRule.getActivity().getCurrentTabModel(), 0); + TabModelUtils.setIndex(sActivityTestRule.getActivity().getCurrentTabModel(), 0, false); }); triggerResolve("states");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 655f1d5..3bd461e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -116,6 +116,7 @@ import org.chromium.chrome.browser.toolbar.menu_button.MenuButton; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -418,8 +419,10 @@ } MenuButton menuButtonView = toolbarView.findViewById(R.id.menu_button_wrapper); - assertEquals(menuButtonView.getUseLightDrawablesForTesting(), - ColorUtils.shouldUseLightForegroundOnBackground(expectedColor)); + assertEquals(ColorUtils.shouldUseLightForegroundOnBackground(expectedColor) + ? BrandedColorScheme.DARK_BRANDED_THEME + : BrandedColorScheme.LIGHT_BRANDED_THEME, + menuButtonView.getBrandedColorSchemeForTesting()); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java index 5b56c39..9409793 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
@@ -399,7 +399,7 @@ final int count = model.getCount(); InstrumentationRegistry.getInstrumentation().runOnMainSync( - () -> TabModelUtils.setIndex(model, count - 2)); + () -> TabModelUtils.setIndex(model, count - 2, false)); CriteriaHelper.pollUiThread(() -> { Tab tab = mDownloadTestRule.getActivity().getActivityTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java index 90b11c48..07afa05 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -86,7 +86,7 @@ import org.chromium.content_public.common.ContentUrlConstants; import java.util.ArrayList; -import java.util.BitSet; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -105,8 +105,8 @@ private static final String FOO_URL = "https://foo.com"; private static final long ACTIVITY_WAIT_LONG_MS = TimeUnit.SECONDS.toMillis(10); private static final String TEST_ENROLLMENT_TOKEN = "enrollment-token"; - private static final String FRE_PROGRESS_MAIN_INTENT_HISTOGRAM = - "MobileFre.Progress.MainIntent"; + private static final String FRE_PROGRESS_VIEW_INTENT_HISTOGRAM = + "MobileFre.Progress.ViewIntent"; @Rule public MultiActivityTestRule mTestRule = new MultiActivityTestRule(); @@ -681,14 +681,10 @@ waitForActivity(ChromeTabbedActivity.class); - checkRecordedProgressSteps(BitSet.valueOf(new long[] { - MobileFreProgress.STARTED, - MobileFreProgress.WELCOME_SHOWN, - MobileFreProgress.DATA_SAVER_SHOWN, - MobileFreProgress.SYNC_CONSENT_SHOWN, - MobileFreProgress.SYNC_CONSENT_ACCEPTED, - MobileFreProgress.DEFAULT_SEARCH_ENGINE_SHOWN, - })); + checkRecordedProgressSteps(Arrays.asList(new Integer[] {MobileFreProgress.STARTED, + MobileFreProgress.WELCOME_SHOWN, MobileFreProgress.DATA_SAVER_SHOWN, + MobileFreProgress.SYNC_CONSENT_SHOWN, MobileFreProgress.SYNC_CONSENT_DISMISSED, + MobileFreProgress.DEFAULT_SEARCH_ENGINE_SHOWN})); } @Test @@ -704,27 +700,24 @@ waitForActivity(ChromeTabbedActivity.class); - checkRecordedProgressSteps(BitSet.valueOf(new long[] { - MobileFreProgress.STARTED, - MobileFreProgress.WELCOME_SHOWN, - MobileFreProgress.SYNC_CONSENT_DISMISSED, - })); + checkRecordedProgressSteps(Arrays.asList( + new Integer[] {MobileFreProgress.STARTED, MobileFreProgress.WELCOME_SHOWN})); } - private void checkRecordedProgressSteps(BitSet bucketsRecorded) { + private void checkRecordedProgressSteps(List<Integer> bucketsRecorded) { for (int bucket = MobileFreProgress.STARTED; bucket < MobileFreProgress.MAX; ++bucket) { int recordedValue = RecordHistogram.getHistogramValueCountForTesting( - FRE_PROGRESS_MAIN_INTENT_HISTOGRAM, bucket); - if (bucketsRecorded.get(bucket)) { + FRE_PROGRESS_VIEW_INTENT_HISTOGRAM, bucket); + if (bucketsRecorded.contains(bucket)) { Assert.assertEquals( String.format( "Histogram <%s>, bucket <%d> should be recorded exactly once.", - FRE_PROGRESS_MAIN_INTENT_HISTOGRAM, bucket), + FRE_PROGRESS_VIEW_INTENT_HISTOGRAM, bucket), 1, recordedValue); } else { Assert.assertEquals( String.format("Histogram <%s>, bucket <%d> should not be recorded.", - FRE_PROGRESS_MAIN_INTENT_HISTOGRAM, bucket), + FRE_PROGRESS_VIEW_INTENT_HISTOGRAM, bucket), 0, recordedValue); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java index f7c430ca..9df0e6b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
@@ -141,7 +141,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { tabModel.cancelTabClosure(tab.getId()); int tabIndex = TabModelUtils.getTabIndexById(tabModel, tab.getId()); - TabModelUtils.setIndex(tabModel, tabIndex); + TabModelUtils.setIndex(tabModel, tabIndex, false); }); Assert.assertFalse(tab.isHidden()); Assert.assertFalse(tab.isClosing());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarTest.java index 26f5336..f157a28d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarTest.java
@@ -15,7 +15,7 @@ import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.Matchers.not; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; @@ -205,7 +205,7 @@ }; doAnswer(logoAnswer) .when(mSearchEngineLogoUtils) - .getSearchEngineLogo(any(), anyBoolean(), any(), any(), any()); + .getSearchEngineLogo(any(), anyInt(), any(), any(), any()); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java index 6052c7d..b2db8a69 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java
@@ -16,9 +16,12 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.view.ContextThemeWrapper; import androidx.test.filters.SmallTest; +import com.google.android.material.color.MaterialColors; + import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -48,6 +51,7 @@ import org.chromium.chrome.browser.omnibox.status.StatusProperties.StatusIconResource; import org.chromium.chrome.browser.omnibox.status.StatusView.IconTransitionType; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.embedder_support.util.UrlConstants; @@ -65,6 +69,7 @@ @Batch(Batch.UNIT_TESTS) @EnableFeatures(ChromeFeatureList.SEARCH_ENGINE_PROMO_EXISTING_DEVICE) public final class StatusMediatorUnitTest { + private static final String TAG = "StatusMediatorUnitTest"; private static final String TEST_SEARCH_URL = "https://www.test.com"; @Rule @@ -107,7 +112,8 @@ public void setUp() { MockitoAnnotations.initMocks(this); NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - mContext = ContextUtils.getApplicationContext(); + mContext = new ContextThemeWrapper( + ContextUtils.getApplicationContext(), R.style.Theme_BrowserUI_DayNight); mResources = mContext.getResources(); mWindowAndroid = TestThreadUtils.runOnUiThreadBlockingNoException(() -> new WindowAndroid(mContext)); @@ -130,7 +136,7 @@ doAnswer(logoAnswer) .when(mSearchEngineLogoUtils) .getSearchEngineLogo( - eq(mResources), /* inNightMode= */ eq(false), any(), any(), any()); + eq(mResources), eq(BrandedColorScheme.APP_DEFAULT), any(), any(), any()); mBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); setupStatusMediator(/* isTablet= */ false); @@ -432,26 +438,26 @@ R.string.location_bar_paint_preview_page_status, mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES)); Assert.assertEquals("Incorrect color for paint preview status text", - R.color.locationbar_status_preview_color_light, - mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); - mMediator.setUseDarkColors(true); + MaterialColors.getColor(mContext, R.attr.colorPrimary, TAG), + mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR)); + mMediator.setBrandedColorScheme(BrandedColorScheme.LIGHT_BRANDED_THEME); Assert.assertEquals("Incorrect color for paint preview status text", - R.color.locationbar_status_preview_color, - mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); + mContext.getColor(R.color.locationbar_status_preview_color_dark), + mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR)); // When only offline is enabled, it should be shown. mMediator.setPageIsPaintPreview(false); - mMediator.setUseDarkColors(false); + mMediator.setBrandedColorScheme(BrandedColorScheme.DARK_BRANDED_THEME); Assert.assertEquals("Incorrect text for offline page status text", R.string.location_bar_verbose_status_offline, mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES)); Assert.assertEquals("Incorrect color for offline page status text", - R.color.locationbar_status_offline_color_light, - mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); - mMediator.setUseDarkColors(true); + mContext.getColor(R.color.locationbar_status_offline_color_light), + mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR)); + mMediator.setBrandedColorScheme(BrandedColorScheme.LIGHT_BRANDED_THEME); Assert.assertEquals("Incorrect color for offline page status text", - R.color.locationbar_status_offline_color, - mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); + mContext.getColor(R.color.locationbar_status_offline_color_dark), + mModel.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR)); } @Test @@ -467,7 +473,7 @@ mMediator.onTemplateURLServiceChanged(); verify(mSearchEngineLogoUtils, times(3)) .getSearchEngineLogo( - eq(mResources), /* inNightMode= */ eq(false), any(), any(), any()); + eq(mResources), eq(BrandedColorScheme.APP_DEFAULT), any(), any(), any()); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java index 432a417..a9fce94 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java
@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.omnibox.suggestions.base.SuggestionDrawableState; import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties.SuggestionIcon; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.favicon.LargeIconBridge; import org.chromium.components.favicon.LargeIconBridge.LargeIconCallback; import org.chromium.components.omnibox.AutocompleteMatch; @@ -144,13 +145,18 @@ mProcessor.populateModel(mSuggestion, mModel, 0); } - /** Create URL suggestion for test. */ - private void createUrlSuggestion(int type, String title) { - mSuggestion = createSuggestionBuilder(type, title).setIsSearch(false).build(); + /** Create URL suggestion with supplied text and target URL for test. */ + private void createUrlSuggestion(int type, String title, GURL url) { + mSuggestion = createSuggestionBuilder(type, title).setIsSearch(false).setUrl(url).build(); mModel = mProcessor.createModel(); mProcessor.populateModel(mSuggestion, mModel, 0); } + /** Create URL suggestion for test. */ + private void createUrlSuggestion(int type, String title) { + createUrlSuggestion(type, title, GURL.emptyGURL()); + } + /** Create switch to tab suggestion for test. */ private void createSwitchToTabSuggestion(int type, String title) { mSuggestion = createSuggestionBuilder(type, title).setHasTabMatch(true).build(); @@ -396,4 +402,20 @@ createUrlSuggestion(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, ""); Assert.assertEquals(mModel.get(SuggestionViewProperties.ALLOW_WRAP_AROUND), false); } + + @Test + @SmallTest + @UiThreadTest + public void internalUrlSuggestions_doNotPresentInternalScheme() { + mProcessor.onNativeInitialized(); + // chrome://newtab and such should have no URL in the suggestions list. + createUrlSuggestion(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "", + new GURL(UrlConstants.NTP_NON_NATIVE_URL)); + Assert.assertNull(mModel.get(SuggestionViewProperties.TEXT_LINE_2_TEXT)); + + // Similarly, internal (eg. chrome-intenal://) URLs should not be shown. + createUrlSuggestion( + OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "", new GURL(UrlConstants.DOWNLOADS_URL)); + Assert.assertNull(mModel.get(SuggestionViewProperties.TEXT_LINE_2_TEXT)); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreatorTest.java index fcfefef..aa0e8af 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreatorTest.java
@@ -89,8 +89,8 @@ @Override public void run() { TestThreadUtils.runOnUiThreadBlocking(() -> { - TabModelUtils.setIndex( - sActivityTestRule.getActivity().getCurrentTabModel(), indexOf(bgTab)); + TabModelUtils.setIndex(sActivityTestRule.getActivity().getCurrentTabModel(), + indexOf(bgTab), false); }); } });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java index 565cac067..254f778 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java
@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabState; +import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabModelSelectorMetadata; import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabRestoreDetails; import org.chromium.components.embedder_support.util.UrlConstants; @@ -136,7 +137,7 @@ TabImpl emptyNtpTab = mock(TabImpl.class); when(emptyNtpTab.getUrl()).thenReturn(new GURL(UrlConstants.NTP_URL)); - when(emptyNtpTab.isTabStateDirty()).thenReturn(true); + TabStateAttributes.from(emptyNtpTab).setIsTabStateDirty(true); when(emptyNtpTab.canGoBack()).thenReturn(false); when(emptyNtpTab.canGoForward()).thenReturn(false); @@ -145,7 +146,7 @@ TabImpl ntpWithBackNavTab = mock(TabImpl.class); when(ntpWithBackNavTab.getUrl()).thenReturn(new GURL(UrlConstants.NTP_URL)); - when(ntpWithBackNavTab.isTabStateDirty()).thenReturn(true); + TabStateAttributes.from(ntpWithBackNavTab).setIsTabStateDirty(true); when(ntpWithBackNavTab.canGoBack()).thenReturn(true); when(ntpWithBackNavTab.canGoForward()).thenReturn(false); @@ -154,7 +155,7 @@ TabImpl ntpWithForwardNavTab = mock(TabImpl.class); when(ntpWithForwardNavTab.getUrl()).thenReturn(new GURL(UrlConstants.NTP_URL)); - when(ntpWithForwardNavTab.isTabStateDirty()).thenReturn(true); + TabStateAttributes.from(ntpWithForwardNavTab).setIsTabStateDirty(true); when(ntpWithForwardNavTab.canGoBack()).thenReturn(false); when(ntpWithForwardNavTab.canGoForward()).thenReturn(true); @@ -163,7 +164,7 @@ TabImpl ntpWithAllTheNavsTab = mock(TabImpl.class); when(ntpWithAllTheNavsTab.getUrl()).thenReturn(new GURL(UrlConstants.NTP_URL)); - when(ntpWithAllTheNavsTab.isTabStateDirty()).thenReturn(true); + TabStateAttributes.from(ntpWithAllTheNavsTab).setIsTabStateDirty(true); when(ntpWithAllTheNavsTab.canGoBack()).thenReturn(true); when(ntpWithAllTheNavsTab.canGoForward()).thenReturn(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicyTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicyTest.java index 9a80058..49a0672 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicyTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicyTest.java
@@ -140,8 +140,8 @@ for (int tabId : incognitoTabIds) { addTabToSaveQueue(store, incognitoTabModel, incognitoTabModel.addTab(tabId)); } - TabModelUtils.setIndex(normalTabModel, 0); - TabModelUtils.setIndex(incognitoTabModel, 0); + TabModelUtils.setIndex(normalTabModel, 0, false); + TabModelUtils.setIndex(incognitoTabModel, 0, false); }); callbackSignal.waitForCallback(callCount); return orchestrator;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java index f2c50ace..76fa88a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -107,7 +107,7 @@ private void selectTabOnUiThread(final TabModel model, final Tab tab) { TestThreadUtils.runOnUiThreadBlocking( - () -> { model.setIndex(model.indexOf(tab), TabSelectionType.FROM_USER); }); + () -> { model.setIndex(model.indexOf(tab), TabSelectionType.FROM_USER, false); }); } private void closeTabOnUiThread(final TabModel model, final Tab tab, final boolean undoable)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java index 0890562ea..0da5378 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java
@@ -160,7 +160,7 @@ mActivityTestRule.getActivity().getTabModelSelector().selectModel(/*incognito=*/ toIncognito); mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().setIndex( - 0, TabSelectionType.FROM_USER); + 0, TabSelectionType.FROM_USER, false); }); assertEquals(toIncognito, locationBarModel.isIncognito());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java index c3069c8..80a9b13 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java
@@ -180,7 +180,7 @@ doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(STARTING_FQDN); TestThreadUtils.runOnUiThreadBlocking(() -> { mActivity.getTabModelSelector().getCurrentModel().setIndex( - originalTabIndex, TabSelectionType.FROM_USER); + originalTabIndex, TabSelectionType.FROM_USER, false); }); waitForSuspendedTabToShow(mTab, STARTING_FQDN); } @@ -311,7 +311,7 @@ mPageViewObserver.notifySiteSuspensionChanged(STARTING_FQDN, false); doReturn(false).when(mSuspensionTracker).isWebsiteSuspended(STARTING_FQDN); mActivity.getTabModelSelector().getCurrentModel().setIndex( - originalTabIndex, TabSelectionType.FROM_USER); + originalTabIndex, TabSelectionType.FROM_USER, false); }); assertSuspendedTabHidden(mTab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java index c9120b39..ec602250 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
@@ -232,7 +232,7 @@ assertEquals("The bottom sheet should be hidden.", SheetState.HIDDEN, mSheetController.getSheetState()); mActivity.getTabModelSelector().getCurrentModel().setIndex( - 0, TabSelectionType.FROM_USER); + 0, TabSelectionType.FROM_USER, false); }); setTabSwitcherState(false); @@ -312,7 +312,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mActivity.getTabModelSelector().getCurrentModel().setIndex( - originalTabIndex, TabSelectionType.FROM_USER); + originalTabIndex, TabSelectionType.FROM_USER, false); }); // Request content be shown again.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/LaunchesWithColorSchemeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/LaunchesWithColorSchemeTest.java index adf71d2..f5806765 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/LaunchesWithColorSchemeTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/LaunchesWithColorSchemeTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.customtabs; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -28,6 +29,7 @@ import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.toolbar.menu_button.MenuButton; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.ui.display.DisplayAndroidManager; /** @@ -70,7 +72,8 @@ assertTrue(activity.getNightModeStateProviderForTesting().isInNightMode()); MenuButton menuButtonView = activity.findViewById(R.id.menu_button_wrapper); - assertTrue(menuButtonView.getUseLightDrawablesForTesting()); + assertEquals(BrandedColorScheme.APP_DEFAULT, + menuButtonView.getBrandedColorSchemeForTesting()); }); } @@ -85,7 +88,8 @@ assertFalse(activity.getNightModeStateProviderForTesting().isInNightMode()); MenuButton menuButtonView = activity.findViewById(R.id.menu_button_wrapper); - assertFalse(menuButtonView.getUseLightDrawablesForTesting()); + assertEquals(BrandedColorScheme.APP_DEFAULT, + menuButtonView.getBrandedColorSchemeForTesting()); }); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java new file mode 100644 index 0000000..fda1880 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java
@@ -0,0 +1,88 @@ +// 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.chrome.browser.fullscreen; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.app.Activity; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.UserDataHost; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.cc.input.BrowserControlsState; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabAttributes; +import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; +import org.chromium.chrome.test.util.browser.Features; + +/** + * Unit tests for {@link FullscreenHtmlApiHandler}. + */ +@RunWith(BaseRobolectricTestRunner.class) +public class FullscreenHtmlApiHandlerUnitTest { + @Rule + public TestRule mProcessor = new Features.JUnitProcessor(); + + @Mock + private Activity mActivity; + @Mock + private TabAttributes mTabAttributes; + @Mock + private TabBrowserControlsConstraintsHelper mTabBrowserControlsConstraintsHelper; + @Mock + private Tab mTab; + + private FullscreenHtmlApiHandler mFullscreenHtmlApiHandler; + private ObservableSupplierImpl<Boolean> mAreControlsHidden; + private UserDataHost mHost; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mHost = new UserDataHost(); + doReturn(mHost).when(mTab).getUserDataHost(); + + mAreControlsHidden = new ObservableSupplierImpl<Boolean>(); + mFullscreenHtmlApiHandler = + new FullscreenHtmlApiHandler(mActivity, mAreControlsHidden, false); + } + + @Test + public void testFullscreenRequestCanceledAtPendingState() { + // avoid calling GestureListenerManager/SelectionPopupController + doReturn(null).when(mTab).getWebContents(); + doReturn(true).when(mTab).isUserInteractable(); + + // Fullscreen process stops at pending state since controls are not hidden. + mAreControlsHidden.set(false); + mFullscreenHtmlApiHandler.setTabForTesting(mTab); + FullscreenOptions fullscreenOptions = new FullscreenOptions(false); + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + + // Exit is invoked unexpectedly before the controls get hidden. Fullscreen process should be + // marked as canceled. + mFullscreenHtmlApiHandler.exitPersistentFullscreenMode(); + assertTrue("Fullscreen request should have been canceled", fullscreenOptions.canceled()); + + // Controls are hidden afterwards. Since the fullscreen request was canceled, we should + // restore the controls. + TabBrowserControlsConstraintsHelper.setForTesting( + mTab, mTabBrowserControlsConstraintsHelper); + mAreControlsHidden.set(true); + verify(mTabBrowserControlsConstraintsHelper, times(1)) + .update(BrowserControlsState.SHOWN, true); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUnitTest.java index 2b4d7dd..ccf2a54 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUnitTest.java
@@ -5,15 +5,19 @@ package org.chromium.chrome.browser.tab; import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.app.Activity; import android.content.Context; +import android.view.View; import androidx.test.filters.SmallTest; @@ -27,10 +31,14 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.JniMocker; +import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabDataObserver; +import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; import java.lang.ref.WeakReference; @@ -48,6 +56,9 @@ @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); + @Rule + public JniMocker mocker = new JniMocker(); + @Mock private WindowAndroid mWindowAndroid; @Mock @@ -66,6 +77,20 @@ private CriticalPersistedTabData mCriticalPersistedTabData; @Mock private CriticalPersistedTabDataObserver mCriticalPersistedTabDataObserver; + @Mock + private NativePage mNativePage; + @Mock + private TabDelegateFactory mDelegateFactory; + @Mock + private TabWebContentsDelegateAndroid mTabWebContentsDelegateAndroid; + @Mock + private WebContents mWebContents; + @Mock + private View mNativePageView; + @Mock + private ChromeActivity mChromeActivity; + @Mock + TabImpl.Natives mNativeMock; private TabImpl mTab; @@ -94,20 +119,59 @@ verify(mCriticalPersistedTabDataObserver).onRootIdChanged(mTab, TAB2_ID); assertThat(CriticalPersistedTabData.from(mTab).getRootId(), equalTo(TAB2_ID)); - assertThat(mTab.isTabStateDirty(), equalTo(true)); + assertThat(TabStateAttributes.from(mTab).isTabStateDirty(), equalTo(true)); } @Test @SmallTest public void testSetRootIdWithoutChange() { assertThat(CriticalPersistedTabData.from(mTab).getRootId(), equalTo(TAB1_ID)); - mTab.setIsTabStateDirty(false); + TabStateAttributes.from(mTab).setIsTabStateDirty(false); CriticalPersistedTabData.from(mTab).setRootId(TAB1_ID); verify(mCriticalPersistedTabDataObserver, never()) .onRootIdChanged(any(Tab.class), anyInt()); assertThat(CriticalPersistedTabData.from(mTab).getRootId(), equalTo(TAB1_ID)); - assertThat(mTab.isTabStateDirty(), equalTo(false)); + assertThat(TabStateAttributes.from(mTab).isTabStateDirty(), equalTo(false)); + } + + @Test + @SmallTest + public void testFreezeDetachedNativePage() { + mocker.mock(TabImplJni.TEST_HOOKS, mNativeMock); + + doReturn(mTabWebContentsDelegateAndroid) + .when(mDelegateFactory) + .createWebContentsDelegate(any(Tab.class)); + doReturn(mNativePage) + .when(mDelegateFactory) + .createNativePage(any(String.class), anyObject(), any(Tab.class)); + doReturn(false).when(mNativePage).isFrozen(); + doReturn(mNativePageView).when(mNativePage).getView(); + doReturn(mWindowAndroid).when(mWebContents).getTopLevelNativeWindow(); + doReturn(mChromeActivity).when(mWeakReferenceContext).get(); + + mTab = new TabImpl(TAB1_ID, false, null, null) { + @Override + void updateWindowAndroid(WindowAndroid windowAndroid) {} + @Override + public WebContents getWebContents() { + return mWebContents; + } + @Override + public boolean isNativePage() { + return true; + } + @Override + void pushNativePageStateToNavigationEntry() {} + }; + mTab.updateAttachment(mWindowAndroid, mDelegateFactory); + + // A valid, non-null NativeFrozenPage object should be instantiated when a Tab is + // told to freeze its native page in a currently detached state. + assertEquals(mTab.getNativePage(), mNativePage); + mTab.freezeNativePage(); + assertNotEquals(mTab.getNativePage(), mNativePage); } }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 6710a03..13141ad 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -192,6 +192,10 @@ ] } + if (is_android) { + deps += [ "//components/crash/android:crash_android" ] + } + if (is_mac) { sources += [ "chrome_main_mac.mm" ]
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 9fd13c88..fd1477e 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -139,10 +139,10 @@ #if defined(OS_ANDROID) #include "base/android/java_exception_reporter.h" #include "base/android/library_loader/library_loader_hooks.h" -#include "chrome/browser/android/crash/pure_java_exception_handler.h" #include "chrome/browser/android/metrics/uma_session_stats.h" #include "chrome/browser/flags/android/chrome_feature_list.h" #include "chrome/common/chrome_descriptors.h" +#include "components/crash/android/pure_java_exception_handler.h" #include "components/power_scheduler/power_scheduler.h" #include "net/android/network_change_notifier_factory_android.h" #else // defined(OS_ANDROID)
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 3094f434..c1a0c200 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3662,10 +3662,10 @@ <message name="IDS_HATS_DONE_BUTTON_LABEL" desc="Label used for the done button at the end of survey"> Done </message> - <message name="IDS_ARC_CHILD_TRANSITION_TITLE" desc="Title of the toast shown when the user tries to activate ARC app and transition from child to regular user or from regular to child user is not completed."> + <message name="IDS_ARC_CHILD_TRANSITION_TITLE" desc="Title of the notification shown when the user tries to activate ARC app and transition from child to regular user or from regular to child user is not completed."> Action not available </message> - <message name="IDS_ARC_CHILD_TRANSITION_MESSAGE" desc="Message of the toast shown when the user tries to activate ARC app and transition from child to regular user or from regular to child user is not completed."> + <message name="IDS_ARC_CHILD_TRANSITION_MESSAGE" desc="Message of the notification shown when the user tries to activate ARC app and transition from child to regular user or from regular to child user is not completed."> Please try again in a few moments </message> <message name="IDS_ARC_DATA_REMOVAL_CONFIRMATION_HEADING" desc="Heading text in the content area of the confirmation for data removal in case ARC comes to wrong state.">
diff --git a/chrome/app/extensions_strings.grdp b/chrome/app/extensions_strings.grdp index 5a4a804..8f97c2c 100644 --- a/chrome/app/extensions_strings.grdp +++ b/chrome/app/extensions_strings.grdp
@@ -367,6 +367,12 @@ <message name="IDS_EXTENSIONS_SEARCH" desc="The text displayed in the search box on the chrome://extensions page."> Search extensions </message> + <message name="IDS_EXTENSIONS_SITE_PERMISSIONS" desc="The text for the link to manage site permissions for extensions."> + Site permissions + </message> + <message name="IDS_EXTENSIONS_SITE_PERMISSIONS_PAGE_TITLE" desc="The title for the extensions site permissions management page."> + Site permissions + </message> <message name="IDS_EXTENSIONS_EDIT_SHORTCUT" desc="The label for a button to edit the shortcut."> Edit shortcut </message>
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS.png.sha1 new file mode 100644 index 0000000..f9b784c0 --- /dev/null +++ b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS.png.sha1
@@ -0,0 +1 @@ +73895c70242caef087fbe3053218c8835a07d105 \ No newline at end of file
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS_PAGE_TITLE.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS_PAGE_TITLE.png.sha1 new file mode 100644 index 0000000..f9b784c0 --- /dev/null +++ b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_SITE_PERMISSIONS_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@ +73895c70242caef087fbe3053218c8835a07d105 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index ddb60e1..b07dd1c 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -2040,6 +2040,12 @@ <message name="IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_FORGET_A11Y_LABEL" desc="Bluetooth device details page: Accessibility label for button that forgets the Bluetooth device when clicked."> Forget <ph name="DEVICE_NAME">$1<ex>Beats</ex></ph> </message> + <message name="IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED" desc="Bluetooth device details page: Message displayed for devices that are currently connected that will disconnect automatically when turned off or not used."> + Device will disconnect automatically when it's turned off or isn't being used + </message> + <message name="IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED" desc="Bluetooth device details page: Message displayed for devices that are currently disconnected that will connect automatically when turned on and used."> + Device will connect automatically when it's turned on and is being used + </message> <message name="IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_NAME" desc="Bluetooth device details page: label informing user the text below is the device name."> Device name </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED.png.sha1 new file mode 100644 index 0000000..30fe9efd --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED.png.sha1
@@ -0,0 +1 @@ +4cbb879fe959ebadd9460227ce07ea48ba0ff0b2 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED.png.sha1 new file mode 100644 index 0000000..462abc5 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED.png.sha1
@@ -0,0 +1 @@ +9199ecc97012de42a284f57eaa6a4de96b6560a5 \ No newline at end of file
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb index f68f299..1f4d3d6 100644 --- a/chrome/app/resources/generated_resources_af.xtb +++ b/chrome/app/resources/generated_resources_af.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">Hierdie tipe lêer kan jou rekenaar beskadig. Wil jy <ph name="FILE_NAME" /> in elk geval hou?</translation> <translation id="3918972485393593704">Gee besonderhede by Google aan</translation> <translation id="3919145445993746351">Skakel sinkronisering aan om jou uitbreidings op al jou rekenaars te kry</translation> +<translation id="3919229493046408863">Skakel kennisgewing af wanneer toestelle in die omtrek is</translation> <translation id="3919798653937160644">Bladsye wat jy in hierdie venster bekyk, sal nie in die blaaiergeskiedenis verskyn nie en sal nie ander spore, soos webkoekies, op die rekenaar agterlaat nadat jy alle oop gasvensters toegemaak het nie. Enige lêers wat jy aflaai, sal egter bewaar word.</translation> <translation id="3920504717067627103">Sertifikaatbeleide</translation> <translation id="392089482157167418">Aktiveer ChromeVox (gesproke terugvoering)</translation> @@ -5936,6 +5937,7 @@ <translation id="7167486101654761064">Maak altyd hierdie tipe lêers oop</translation> <translation id="716810439572026343">Laai tans <ph name="FILE_NAME" /> af</translation> <translation id="7168109975831002660">Minimum lettertipegrootte</translation> +<translation id="7169122689956315694">Skakel kennisgewing aan wanneer toestelle in die omtrek is</translation> <translation id="7170236477717446850">Profielprent</translation> <translation id="7171000599584840888">Voeg profiel by …</translation> <translation id="7171259390164035663">Moenie inskryf nie</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 4f4d292..7ce8fe4 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -2892,6 +2892,7 @@ <translation id="3916445069167113093">هذا النوع من الملفات قد يلحق الضرر بالكمبيوتر. هل تريد الاحتفاظ بـ <ph name="FILE_NAME" /> على أيّ حال؟</translation> <translation id="3918972485393593704">إبلاغ Google بالتفاصيل</translation> <translation id="3919145445993746351">للحصول على الإضافات على جميع أجهزة الكمبيوتر، يُرجى تفعيل المزامنة</translation> +<translation id="3919229493046408863">إيقاف الإشعارات عندما تكون الأجهزة قريبة</translation> <translation id="3919798653937160644">لن تظهر في سجلّ المتصفّح الصفحات التي تعرضها في هذه النافذة، ولن تترك أي آثار أخرى في الكمبيوتر، مثل ملفات تعريف الارتباط، بعد إغلاق جميع النوافذ المفتوحة في وضع الضيف، علمًا أنه سيتم الاحتفاظ بأي ملفات يتم تنزيلها.</translation> <translation id="3920504717067627103">سياسات الشهادة</translation> <translation id="392089482157167418">تفعيل ChromeVox (التعليقات المنطوقة)</translation> @@ -5923,6 +5924,7 @@ <translation id="7167486101654761064">فت&ح هذا النوع من الملفّات دائمًا</translation> <translation id="716810439572026343">جارٍ تنزيل <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">الحد الأدنى لحجم الخط</translation> +<translation id="7169122689956315694">تفعيل الإشعارات عندما تكون الأجهزة قريبة</translation> <translation id="7170236477717446850">صورة الملف الشخصي</translation> <translation id="7171000599584840888">إضافة ملف شخصي...</translation> <translation id="7171259390164035663">عدم التسجيل</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb index 5fb8659d..3007b323 100644 --- a/chrome/app/resources/generated_resources_az.xtb +++ b/chrome/app/resources/generated_resources_az.xtb
@@ -2884,6 +2884,7 @@ <translation id="3916445069167113093">Bu fayl növü kompüterinizi zədələyə bilər. <ph name="FILE_NAME" /> faylını yenə də saxlamaq istəyirsiniz?</translation> <translation id="3918972485393593704">Detalları Google'a bildirin</translation> <translation id="3919145445993746351">Artırmaları bütün kompüterlərdə əldə etmək üçün sinxronizasiyanı aktiv edin</translation> +<translation id="3919229493046408863">Cihazlar yaxınlıqda olduqda bildirişi deaktiv edin</translation> <translation id="3919798653937160644">Bu pəncərədə baxdığınız səhifələr brauzer tarixçəsində görünməyəcək və bütün Qonaq səhifələrini qapadandan sonra, kuki kimi digər izlər buraxmayacaq. Lakin, endirmiş olduğunuz bütün fayllar qalacaq.</translation> <translation id="3920504717067627103">Sertifikat siyasəti</translation> <translation id="392089482157167418">ChromeVox'u (şifahi geri əlaqə) aktiv edin</translation> @@ -5913,6 +5914,7 @@ <translation id="7167486101654761064">Bu növ faylları hər zaman açın</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> yüklənir</translation> <translation id="7168109975831002660">Minimum şrift ölçüsü</translation> +<translation id="7169122689956315694">Cihazlar yaxınlıqda olduqda bildirişi aktiv edin</translation> <translation id="7170236477717446850">Profil şəkli</translation> <translation id="7171000599584840888">Profil əlavə edin...</translation> <translation id="7171259390164035663">Qeydiyyatdan keçirməyin</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index fa393d6c..b2d62931 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -2898,6 +2898,7 @@ <translation id="3916445069167113093">Този тип файл може да навреди на компютъра ви. Искате ли да запазите „<ph name="FILE_NAME" />“ въпреки това?</translation> <translation id="3918972485393593704">Изпращане на подробностите до Google</translation> <translation id="3919145445993746351">За да получите разширенията си на всичките си компютри, включете синхронизирането</translation> +<translation id="3919229493046408863">Изключване на известията от устройства в близост</translation> <translation id="3919798653937160644">Преглежданите от вас страници в този прозорец няма да се показват в историята на браузъра и няма да оставят на компютъра други следи, като „бисквитки“, след като затворите всички прозорци в режим на гост. Изтеглените от вас файлове обаче ще бъдат запазени.</translation> <translation id="3920504717067627103">Правила за сертификата</translation> <translation id="392089482157167418">Активиране на ChromeVox (обратна връзка с говор)</translation> @@ -5933,6 +5934,7 @@ <translation id="7167486101654761064">&Файловете от този тип да се отварят винаги</translation> <translation id="716810439572026343">„<ph name="FILE_NAME" />“ се изтегля</translation> <translation id="7168109975831002660">Минимален размер на шрифта</translation> +<translation id="7169122689956315694">Включване на известията от устройства в близост</translation> <translation id="7170236477717446850">Снимка на потребителския профил</translation> <translation id="7171000599584840888">Добавяне на потребителски профил...</translation> <translation id="7171259390164035663">Без регистриране</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index 320915e..c8e51bd 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -2,7 +2,7 @@ <!DOCTYPE translationbundle> <translationbundle lang="eu"> <translation id="1001033507375626788">Zurekin partekatuta dago sarea</translation> -<translation id="1001307489511021749">Aplikazioak, ezarpenak eta pertsonalizatzeko beste aukera batzuk sinkronizatu egingo dira Chrome OS-eko eta Google-ko kontuan saioa hasita daukaten gailu guztien artean.</translation> +<translation id="1001307489511021749">Aplikazioak, ezarpenak eta pertsonalizatzeko beste aukera batzuk sinkronizatu egingo dira Chrome OS-ko eta Google-ko kontuan saioa hasita daukaten gailu guztien artean.</translation> <translation id="1003088604756913841">Ireki esteka <ph name="APP" /> aplikazioaren beste leiho batean</translation> <translation id="100323615638474026">USB bidezko gailua (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation> <translation id="1004218526896219317">Webgunerako sarbidea</translation> @@ -640,7 +640,7 @@ <translation id="1637350598157233081">Pasahitza gailu honetan gorde da</translation> <translation id="1637765355341780467">Arazoren bat izan da profila irekitzean. Baliteke eginbide batzuk erabilgarri ez egotea.</translation> <translation id="1639239467298939599">Kargatzen</translation> -<translation id="163993578339087550"><ph name="SERVICE_NAME" /> zerbitzuak Chrome OS-eko gailu egoki bat erabiltzen ari zarela egiaztatu nahi du.</translation> +<translation id="163993578339087550"><ph name="SERVICE_NAME" /> zerbitzuak Chrome OS-ko gailu egoki bat erabiltzen ari zarela egiaztatu nahi du.</translation> <translation id="1640235262200048077"><ph name="IME_NAME" /> ezin da erabili Linux-erako aplikazioetan oraindik</translation> <translation id="1640283014264083726">PKCS #1 MD4, RSA enkriptatzearekin</translation> <translation id="1641113438599504367">Arakatze segurua</translation> @@ -1146,7 +1146,7 @@ <translation id="2152281589789213846">Gehitu inprimagailuak profilean</translation> <translation id="2152882202543497059"><ph name="NUMBER" /> argazki</translation> <translation id="2154484045852737596">Editatu txartela</translation> -<translation id="2154502158735983655">Chrome OS-eko gailuei buruzko informazioa eta datuak irakurri.</translation> +<translation id="2154502158735983655">Chrome OS-ko gailuei buruzko informazioa eta datuak irakurri.</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> × <ph name="HEIGHT" /> dirudi</translation> <translation id="2156294658807918600">Service worker: <ph name="SCRIPT_URL" /></translation> <translation id="2156557113115192526">Ez galdetu berriro fitxategi-formatu hau aplikazioan irekitzean: @@ -3850,7 +3850,7 @@ <translation id="496446150016900060">Sinkronizatu wifi-sareak telefonoarekin</translation> <translation id="4965808351167763748">Ziur gailu hau Hangouts Meet zerbitzuarekin erabiltzeko konfiguratu nahi duzula?</translation> <translation id="4966972803217407697">Ezkutuko moduan zaude</translation> -<translation id="496888482094675990">Fitxategiak aplikazioarekin, azkar atzituko dituzu Google Drive-n, kanpoko memorian edo Chrome OS-eko gailuan gordeta dituzun fitxategiak.</translation> +<translation id="496888482094675990">Fitxategiak aplikazioarekin, azkar atzituko dituzu Google Drive-n, kanpoko memorian edo Chrome OS-ko gailuan gordeta dituzun fitxategiak.</translation> <translation id="4971412780836297815">Ireki amaitzean</translation> <translation id="4971735654804503942">Babes bizkorrago eta proaktiboa webgune, deskarga eta luzapen kaltegarrien aurka. Pasahitzen segurtasuna urratu dela abisatzen dizu. Google-ri arakatze-datuak bidali behar zaizkio.</translation> <translation id="4972129977812092092">Editatu inprimagailua</translation> @@ -6221,7 +6221,7 @@ <translation id="7477748600276493962">Sortu orri honen QR kodea</translation> <translation id="7477793887173910789">Kontrolatu musika, bideoak eta beste</translation> <translation id="7478485216301680444">Ezin izan da instalatu aplikazio espezializatua.</translation> -<translation id="7478623944308207463">Aplikazioak eta ezarpenak Chrome OS-eko gailu guztietan sinkronizatuko dira, Google-ko kontuarekin saioa hasita badaukazu haietan. Arakatzailea sinkronizatzeko aukerak ikusteko, joan <ph name="LINK_BEGIN" />Chrome-ren ezarpenetara<ph name="LINK_END" />.</translation> +<translation id="7478623944308207463">Aplikazioak eta ezarpenak Chrome OS-ko gailu guztietan sinkronizatuko dira, Google-ko kontuarekin saioa hasita badaukazu haietan. Arakatzailea sinkronizatzeko aukerak ikusteko, joan <ph name="LINK_BEGIN" />Chrome-ren ezarpenetara<ph name="LINK_END" />.</translation> <translation id="7478658909253570368">Ez eman serieko ataketara konektatzeko baimena webguneei</translation> <translation id="7479221278376295180">Memoriaren erabilerari buruzko informazio orokorra</translation> <translation id="747981547666531654"><ph name="FIRST_DEVICE" /> eta <ph name="SECOND_DEVICE" /> izeneko Bluetooth bidezko gailuetara konektatuta</translation> @@ -6577,7 +6577,7 @@ <translation id="7826254698725248775">Gailu-identifikatzailea gatazkatsua da.</translation> <translation id="7826790948326204519"><ph name="BEGIN_H3" />Arazketa-eginbideak<ph name="END_H3" /> <ph name="BR" /> - Chrome OS-eko gailuan arazketa-eginbideak gai ditzakezu, gailuan kode pertsonalizatuak instalatzeko eta probatzeko. Horri esker, honako hauek egin ahalko dituzu:<ph name="BR" /> + Chrome OS-ko gailuan arazketa-eginbideak gai ditzakezu, gailuan kode pertsonalizatuak instalatzeko eta probatzeko. Horri esker, honako hauek egin ahalko dituzu:<ph name="BR" /> <ph name="BEGIN_LIST" /> <ph name="LIST_ITEM" />Roofts egiaztapena kendu, sistema eragilearen fitxategiak aldatu ahal izateko. <ph name="LIST_ITEM" />Gailurako SSH sarbidea gaitu, probako gako estandarrak erabilita, gailua atzitzeko tresnak (adibidez, <ph name="BEGIN_CODE" />"cros flash"<ph name="END_CODE" />) erabili ahal izateko. @@ -7056,7 +7056,7 @@ <translation id="8284279544186306258"><ph name="WEBSITE_1" /> webguneak</translation> <translation id="8284326494547611709">Azpitituluak</translation> <translation id="8286036467436129157">Hasi saioa</translation> -<translation id="8287902281644548111">Bilatu API deiaren edo URLaren arabera</translation> +<translation id="8287902281644548111">Bilatu APIa abiarazteko eskaeraren edo URLaren arabera</translation> <translation id="8288032458496410887">Desinstalatu <ph name="APP" />…</translation> <translation id="8289128870594824098">Diskoaren tamaina</translation> <translation id="8289509909262565712">Ongi etorri <ph name="DEVICE_OS" /> sistemara</translation> @@ -7889,7 +7889,7 @@ <ph name="LIST_ITEM" />Chrome-ren Konexioen diagnostikoak exekutatu. <ph name="END_LIST" /></translation> <translation id="916607977885256133">Pantaila txiki gainjarria</translation> -<translation id="9166813363879986425">Gordetako hobespenak eta jarduerak prest egongo dira Chrome OS-eko gailuetan Google-ko kontuarekin saioa hasten duzunean. Zer sinkronizatu nahi duzun aukeratzeko, joan Ezarpenak atalera.</translation> +<translation id="9166813363879986425">Gordetako hobespenak eta jarduerak prest egongo dira Chrome OS-ko gailuetan Google-ko kontuarekin saioa hasten duzunean. Zer sinkronizatu nahi duzun aukeratzeko, joan Ezarpenak atalera.</translation> <translation id="9167063903968449027">Erakutsi irakurketa-zerrenda</translation> <translation id="9167450455589251456">Ez da onartzen profila</translation> <translation id="9168436347345867845">Geroago</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 5787b984..9609b08 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -2898,6 +2898,7 @@ <translation id="3916445069167113093">این نوع فایل میتواند به رایانهٔ شما آسیب برساند. آیا با این وجود میخواهید <ph name="FILE_NAME" /> را نگه دارید؟</translation> <translation id="3918972485393593704">گزارش جزئیات به Google</translation> <translation id="3919145445993746351">برای دریافت افزونهها در همه رایانههایتان، همگامسازی را روشن کنید</translation> +<translation id="3919229493046408863">خاموش کردن اعلان وقتی دستگاهها دراطراف هستند</translation> <translation id="3919798653937160644">صفحههایی که در این پنجره مشاهده میکنید در سابقه مرورگر نشان داده نمیشوند و بعد از بسته شدن همه پنجرههای باز «مهمان»، هیچ رد دیگری (مثلاً کوکی) از خودشان در رایانه بهجای نمیگذارند. با این وجود، فایلهایی که بارگیری میکنید حفظ خواهند.</translation> <translation id="3920504717067627103">سیاست مربوط به گواهی</translation> <translation id="392089482157167418">فعال کردن ChromeVox (بازخورد گفتاری)</translation> @@ -5932,6 +5933,7 @@ <translation id="7167486101654761064">&همیشه این نوع فایلها باز شوند</translation> <translation id="716810439572026343">در حال بارگیری <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">حداقل اندازه قلم</translation> +<translation id="7169122689956315694">روشن کردن اعلان وقتی دستگاهها دراطراف هستند</translation> <translation id="7170236477717446850">عکس نمایه</translation> <translation id="7171000599584840888">افزودن نمایه…</translation> <translation id="7171259390164035663">ثبتنام نشود</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index 6d4343b9..c089ee1 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -2887,6 +2887,7 @@ <translation id="3916445069167113093">Ce type de fichier risque d'endommager votre ordinateur. Voulez-vous vraiment enregistrer <ph name="FILE_NAME" /> ?</translation> <translation id="3918972485393593704">Envoyer les informations à Google</translation> <translation id="3919145445993746351">Pour synchroniser vos extensions sur tous vos ordinateurs, activez la synchronisation</translation> +<translation id="3919229493046408863">Désactiver la notification en cas d'appareils à proximité</translation> <translation id="3919798653937160644">Les pages que vous consultez dans cette fenêtre ne sont pas consignées dans l'historique du navigateur et ne laissent aucune autre trace sur votre ordinateur (des cookies, par exemple), une fois que vous avez fermé toutes les fenêtres Invité ouvertes. Tous les fichiers téléchargés sont toutefois conservés.</translation> <translation id="3920504717067627103">Stratégies de certificat</translation> <translation id="392089482157167418">Activer ChromeVox (commentaires audio)</translation> @@ -5921,6 +5922,7 @@ <translation id="7167486101654761064">&Toujours ouvrir les fichiers de ce type</translation> <translation id="716810439572026343">Téléchargement de "<ph name="FILE_NAME" />"</translation> <translation id="7168109975831002660">Taille de police minimale</translation> +<translation id="7169122689956315694">Activer la notification en cas d'appareils à proximité</translation> <translation id="7170236477717446850">Photo de profil</translation> <translation id="7171000599584840888">Ajouter un profil…</translation> <translation id="7171259390164035663">Ne pas enregistrer</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index d0dc922..34a158f 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -2884,6 +2884,7 @@ <translation id="3916445069167113093">આ પ્રકારની ફાઇલ તમારા કમ્પ્યુટરને નુકસાન પહોંચાડી શકે છે. શું તમે તો પણ <ph name="FILE_NAME" /> ને રાખવા માગો છો?</translation> <translation id="3918972485393593704">Googleને વિગતોની જાણ કરો</translation> <translation id="3919145445993746351">તમારા બધા કમ્પ્યુટર પર તમારા એક્સ્ટેંશન મેળવવા માટે સિંક કરવાનું ચાલુ કરો</translation> +<translation id="3919229493046408863">ડિવાઇસ આસપાસ હોય ત્યારે નોટિફિકેશન બંધ કરો</translation> <translation id="3919798653937160644">આ વિન્ડોમાં તમે જે પેજ જોઈ રહ્યાં છો એ બ્રાઉઝર ઇતિહાસમાં દેખાશે નહીં અને તમે ખોલેલી બધી અતિથિ વિન્ડો બંધ કરી દો પછી, તે કમ્પ્યુટર પર કુકી જેવા કોઈ બીજા ટ્રેસ છોડશે નહીં. જોકે, તમે ડાઉનલોડ કરશો એ કોઈપણ ફાઇલ જાળવવામાં આવશે.</translation> <translation id="3920504717067627103">પ્રમાણપત્ર પૉલિસીઓ</translation> <translation id="392089482157167418">ChromeVox ચાલુ કરો (બોલાયેલો પ્રતિસાદ)</translation> @@ -5919,6 +5920,7 @@ <translation id="7167486101654761064">આ પ્રકારની ફાઇલો &હંમેશાં ખોલો</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> ડાઉનલોડ કરી રહ્યાં છે</translation> <translation id="7168109975831002660">ન્યૂનતમ ફોન્ટ કદ</translation> +<translation id="7169122689956315694">ડિવાઇસ આસપાસ હોય ત્યારે નોટિફિકેશન ચાલુ કરો</translation> <translation id="7170236477717446850">પ્રોફાઇલ ચિત્ર</translation> <translation id="7171000599584840888">પ્રોફાઇલ ઉમેરો...</translation> <translation id="7171259390164035663">નોંધણી કરાવશો નહીં</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index e06f21a1..e2d7da2b 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">Jenis file ini dapat membahayakan komputer Anda. Apakah Anda ingin tetap menyimpan <ph name="FILE_NAME" />?</translation> <translation id="3918972485393593704">Laporkan detail ke Google</translation> <translation id="3919145445993746351">Untuk dapat mengakses ekstensi Anda di semua komputer, aktifkan sinkronisasi</translation> +<translation id="3919229493046408863">Nonaktifkan notifikasi saat perangkat berada di sekitar</translation> <translation id="3919798653937160644">Halaman yang Anda lihat di jendela ini tidak akan muncul di histori browser dan tidak akan meninggalkan jejak lain, seperti cookie, di komputer setelah Anda menutup semua jendela Tamu yang terbuka. Namun, file apa pun yang Anda download akan tersimpan.</translation> <translation id="3920504717067627103">Kebijakan Sertifikat</translation> <translation id="392089482157167418">Aktifkan ChromeVox (respons lisan)</translation> @@ -5935,6 +5936,7 @@ <translation id="7167486101654761064">Sel&alu buka file jenis ini</translation> <translation id="716810439572026343">Mendownload <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Ukuran font minimal</translation> +<translation id="7169122689956315694">Aktifkan notifikasi saat perangkat berada di sekitar</translation> <translation id="7170236477717446850">Gambar profil</translation> <translation id="7171000599584840888">Tambahkan Profil ...</translation> <translation id="7171259390164035663">Jangan daftar</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb index c5435c0..70ebf4c 100644 --- a/chrome/app/resources/generated_resources_is.xtb +++ b/chrome/app/resources/generated_resources_is.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">Þessi gerð skráar getur skaðað tölvuna þína. Viltu samt halda <ph name="FILE_NAME" />?</translation> <translation id="3918972485393593704">Tilkynna upplýsingar til Google</translation> <translation id="3919145445993746351">Kveiktu á samstillingu til að fá viðbæturnar þínar í allar tölvurnar þínar</translation> +<translation id="3919229493046408863">Slökkva á tilkynningu þegar tæki eru nálæg</translation> <translation id="3919798653937160644">Síður sem þú skoðar í þessum glugga munu ekki birtast í vafraferlinum eða skilja eftir sig önnur ummerki í tölvunni, s.s. fótspor, þegar þú lokar öllum gestagluggum. Allar skrár sem þú sækir verða þó enn til staðar.</translation> <translation id="3920504717067627103">Vottorðastefnur</translation> <translation id="392089482157167418">Virkja ChromeVox (raddsvörun)</translation> @@ -5935,6 +5936,7 @@ <translation id="7167486101654761064">Opna &alltaf skrár af þessari tegund</translation> <translation id="716810439572026343">Sækir <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Lágmarksleturstærð</translation> +<translation id="7169122689956315694">Kveikja á tilkynningu þegar tæki eru nálæg</translation> <translation id="7170236477717446850">Prófílmynd</translation> <translation id="7171000599584840888">Bæta prófíl við...</translation> <translation id="7171259390164035663">Ekki skrá</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 621292b1..d84a821a 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -7947,7 +7947,7 @@ <translation id="932327136139879170">Home page</translation> <translation id="932508678520956232">Impossibile inizializzare la stampa.</translation> <translation id="933427034780221291">{NUM_FILES,plural, =1{Il file è troppo grande per essere sottoposto a un controllo di sicurezza. La dimensione massima dei file che puoi caricare è di 50 MB.}one{Alcuni di questi file sono troppo grandi per essere sottoposti a un controllo di sicurezza. La dimensione massima dei file che puoi caricare è di 50 MB.}other{Alcuni di questi file sono troppo grandi per essere sottoposti a un controllo di sicurezza. La dimensione massima dei file che puoi caricare è di 50 MB.}}</translation> -<translation id="93343527085570547">Visita la <ph name="BEGIN_LINK1" />pagina del Centro Assistenza<ph name="END_LINK1" /> per richiedere modifiche ai contenuti per motivi legali. Alcune informazioni sull'account e sul sistema potrebbero essere inviate a Google, che le userà per risolvere problemi tecnici e migliorare i suoi servizi nel rispetto delle sue <ph name="BEGIN_LINK2" />Norme sulla privacy<ph name="END_LINK2" /> e dei suoi <ph name="BEGIN_LINK3" />Termini di servizio<ph name="END_LINK3" />.</translation> +<translation id="93343527085570547">Vai alla <ph name="BEGIN_LINK1" />Guida di approfondimento legale<ph name="END_LINK1" /> per richiedere modifiche ai contenuti per motivi legali. Alcune informazioni sull'account e sul sistema potrebbero essere inviate a Google, che le userà per risolvere problemi tecnici e migliorare i suoi servizi nel rispetto delle sue <ph name="BEGIN_LINK2" />Norme sulla privacy<ph name="END_LINK2" /> e dei suoi <ph name="BEGIN_LINK3" />Termini di servizio<ph name="END_LINK3" />.</translation> <translation id="93393615658292258">Solo password</translation> <translation id="934244546219308557">Assegna un nome a questo gruppo</translation> <translation id="934503638756687833">Se necessario verranno rimossi anche elementi non elencati qui. Leggi ulteriori informazioni sulla <a href="<ph name="URL" />">protezione da software indesiderato</a> nel whitepaper sulla privacy di Chrome.</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb index 0ce02d8..bb7d1b9 100644 --- a/chrome/app/resources/generated_resources_km.xtb +++ b/chrome/app/resources/generated_resources_km.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">ឯកសារប្រភេទនេះអាចប៉ះពាល់ដល់កុំព្យូទ័ររបស់អ្នក។ តើអ្នកនៅចង់ទុក <ph name="FILE_NAME" /> ដែរទេ?</translation> <translation id="3918972485393593704">រាយការណ៍ព័ត៌មានលម្អិតទៅ Google</translation> <translation id="3919145445993746351">សូមបើកសមកាលកម្ម ដើម្បីទាញយកកម្មវិធីបន្ថែមរបស់អ្នកនៅលើកុំព្យូទ័រទាំងអស់របស់អ្នក</translation> +<translation id="3919229493046408863">បិទការជូនដំណឹង នៅពេលឧបករណ៍នៅជិត</translation> <translation id="3919798653937160644">ទំព័រដែលអ្នកមើលនៅក្នុងវិនដូនេះនឹងមិនបង្ហាញនៅក្នុងប្រវត្តិរុករកតាមអ៊ីនធឺណិតទេ ហើយទំព័រទាំងនោះនឹងមិនបន្សល់ទុកដានផ្សេងទៀតដូចជា ខូគីនៅលើកុំព្យូទ័រឡើយ បន្ទាប់ពីអ្នកបិទវិនដូភ្ញៀវដែលកំពុងបើកទាំងអស់។ ទោះបីជាយ៉ាងនេះក្ដី ឯកសារដែលអ្នកទាញយកនឹងត្រូវបានរក្សាទុក។</translation> <translation id="3920504717067627103">គោលការណ៍វិញ្ញាបនប័ត្រ</translation> <translation id="392089482157167418">បើកដំណើរការ ChromeVox (មតិនិយាយ)</translation> @@ -5936,6 +5937,7 @@ <translation id="7167486101654761064">បើកឯកសារប្រភេទនេះជានិច្ច</translation> <translation id="716810439572026343">កំពុងទាញយក <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">បង្រួមទំហំពុម្ពអក្សរ</translation> +<translation id="7169122689956315694">បើកការជូនដំណឹង នៅពេលឧបករណ៍នៅជិត</translation> <translation id="7170236477717446850">រូបភាពកម្រងព័ត៌មាន</translation> <translation id="7171000599584840888">បញ្ចូលកម្រងព័ត៌មាន...</translation> <translation id="7171259390164035663">កុំចុះឈ្មោះ</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index e30522b..aa2c216 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">이 형식의 파일은 컴퓨터를 손상시킬 수 있습니다. 그래도 <ph name="FILE_NAME" />을(를) 다운로드하시겠습니까?</translation> <translation id="3918972485393593704">Google에 세부정보 신고</translation> <translation id="3919145445993746351">어느 컴퓨터에서나 내 확장 프로그램을 사용하려면 동기화를 사용 설정하세요.</translation> +<translation id="3919229493046408863">기기가 주변에 있을 때 알림 끄기</translation> <translation id="3919798653937160644">이 창에서 보는 페이지는 방문 기록에 나타나지 않으며, 열려 있는 모든 게스트 창을 닫은 후 쿠키와 같은 다른 흔적을 컴퓨터에 남기지 않습니다. 하지만 다운로드한 파일은 모두 저장됩니다.</translation> <translation id="3920504717067627103">인증서 정책</translation> <translation id="392089482157167418">ChromeVox(음성 피드백) 사용</translation> @@ -5932,6 +5933,7 @@ <translation id="7167486101654761064">해당 유형의 파일 항상 열기(&A)</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> 다운로드 중</translation> <translation id="7168109975831002660">최소 글꼴 크기</translation> +<translation id="7169122689956315694">기기가 주변에 있을 때 알림 켜기</translation> <translation id="7170236477717446850">프로필 사진</translation> <translation id="7171000599584840888">프로필 추가...</translation> <translation id="7171259390164035663">등록하지 않음</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index b0c353f..8ecb3c1 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -2904,6 +2904,7 @@ <translation id="3916445069167113093">Šio tipo failai gali pažeisti kompiuterį. Ar vis tiek norite palikti <ph name="FILE_NAME" />?</translation> <translation id="3918972485393593704">Pranešti išsamią informaciją „Google“</translation> <translation id="3919145445993746351">Jei norite naudoti plėtinius visuose kompiuteriuose, įjunkite sinchronizavimą</translation> +<translation id="3919229493046408863">Išjungti pranešimus, kai įrenginiai yra netoliese</translation> <translation id="3919798653937160644">Puslapiai, kuriuos peržiūrite šiame lange, nerodomi naršyklės istorijoje. Kai uždarysite visus svečio langus, kompiuteryje neliks ir kitų jų pėdsakų, pvz., slapukų, tačiau atsisiųsti failai bus išsaugoti.</translation> <translation id="3920504717067627103">Sertifikato politika</translation> <translation id="392089482157167418">Įgalinti „ChromeVox“ (ekrano skaitymą balsu)</translation> @@ -5939,6 +5940,7 @@ <translation id="7167486101654761064">&Visada atidaryti tokio tipo failus</translation> <translation id="716810439572026343">Atsisiunčiamas <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Mažiausias šrifto dydis</translation> +<translation id="7169122689956315694">Įjungti pranešimus, kai įrenginiai yra netoliese</translation> <translation id="7170236477717446850">Profilio nuotrauka</translation> <translation id="7171000599584840888">Profilio pridėjimas...</translation> <translation id="7171259390164035663">Neužregistruoti</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index bd582d82..940240a 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -2888,6 +2888,7 @@ <translation id="3916445069167113093">Šāds faila tips var kaitēt jūsu datoram. Vai tiešām vēlaties saglabāt <ph name="FILE_NAME" />?</translation> <translation id="3918972485393593704">Nosūtīt informāciju uzņēmumam Google</translation> <translation id="3919145445993746351">Lai paplašinājumi būtu pieejami visos jūsu datoros, ieslēdziet sinhronizēšanu.</translation> +<translation id="3919229493046408863">Izslēgt paziņojumus par tuvumā esošām ierīcēm</translation> <translation id="3919798653937160644">Lapas, ko skatāt šajā logā, nebūs redzamas pārlūka vēsturē, un, kad aizvērsiet visus viesa režīmā atvērtos logus, datorā nepaliks nekādi vienumi, piemēram, sīkfaili. Tomēr visi lejupielādētie faili tiks saglabāti.</translation> <translation id="3920504717067627103">Sertifikātu politika</translation> <translation id="392089482157167418">Iespējot ChromeVox (balss komentārus)</translation> @@ -5921,6 +5922,7 @@ <translation id="7167486101654761064">Vienmēr atvērt šī veida failus</translation> <translation id="716810439572026343">Notiek faila <ph name="FILE_NAME" /> lejupielāde</translation> <translation id="7168109975831002660">Minimālais fonta lielums</translation> +<translation id="7169122689956315694">Ieslēgt paziņojumus par tuvumā esošām ierīcēm</translation> <translation id="7170236477717446850">Profila attēls</translation> <translation id="7171000599584840888">Pievienot profilu...</translation> <translation id="7171259390164035663">Nereģistrēties</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb index 4e7c3d1..2a3e14e 100644 --- a/chrome/app/resources/generated_resources_mk.xtb +++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -2902,6 +2902,7 @@ <translation id="3916445069167113093">Овој тип на датотека може да го оштети компјутерот. Дали сепак сакате да ја задржите датотеката <ph name="FILE_NAME" />?</translation> <translation id="3918972485393593704">Пријави детали во Google</translation> <translation id="3919145445993746351">За да ги добиете екстензиите на сите ваши компјутери, вклучете ја синхронизацијата</translation> +<translation id="3919229493046408863">Не добивајте известување кога има уреди во близина</translation> <translation id="3919798653937160644">Страниците што ги гледате во прозорецов нема да се појават во историјата на прелистувачот и нема да остават други траги на компјутерот, како на пр., колачиња, откако ќе ги затворите сите отворени гостински прозорци. Меѓутоа, ќе се зачуваат сите датотеки што ќе ги преземете.</translation> <translation id="3920504717067627103">Правила на сертификати</translation> <translation id="392089482157167418">Овозможи ChromeVox (говорни повратни информации)</translation> @@ -5936,6 +5937,7 @@ <translation id="7167486101654761064">&Секогаш отворај датотеки од овој тип</translation> <translation id="716810439572026343">Се презема <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Минимална големина на фонт</translation> +<translation id="7169122689956315694">Добивајте известување кога има уреди во близина</translation> <translation id="7170236477717446850">Профилна слика</translation> <translation id="7171000599584840888">Додајте профил…</translation> <translation id="7171259390164035663">Не регистрирај</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb index cc54cc8..116a72ab 100644 --- a/chrome/app/resources/generated_resources_my.xtb +++ b/chrome/app/resources/generated_resources_my.xtb
@@ -2899,6 +2899,7 @@ <translation id="3916445069167113093">ဒီိဖိုင် ပုံစံက သင့် ကွန်ပျူတာကို အန္တရာယ်ပြုနိုင်သည်။ သင်သည် ဘယ်လိုပဲဖြစ်ဖြစ် <ph name="FILE_NAME" />ကို သိမ်းထားလိုပါသလား?</translation> <translation id="3918972485393593704">အသေးစိတ်ကို Google သို့ အကြောင်းကြားပါ</translation> <translation id="3919145445993746351">သင်၏နောက်ဆက်တွဲများကို သင့်ကွန်ပျူတာအားလုံးတွင် ရယူနိုင်ရန် စင့်ခ်လုပ်ခြင်းကို ဖွင့်ပါ</translation> +<translation id="3919229493046408863">အနီးတစ်ဝိုက်တွင် စက်များရှိပါက အကြောင်းကြားချက်ကို ပိတ်ပါ</translation> <translation id="3919798653937160644">ဤဝင်းဒိုးတွင်ကြည့်သည့် စာမျက်နှာများကို ကြည့်ရှုခြင်းမှတ်တမ်းတွင် ပြမည်မဟုတ်ပါ။ ထို့ပြင် ဖွင့်ထားသော ‘ဧည့်သည်ဝင်းဒိုး’ အားလုံးကို ပိတ်လိုက်ပြီးနောက် ကွန်ပျူတာတွင် ၎င်းတို့က ကွတ်ကီးများကဲ့သို့ အခြားသဲလွန်စများ ချန်ခဲ့မည်မဟုတ်ပါ။ သို့သော် သင်ဒေါင်းလုဒ်လုပ်သော ဖိုင်များကိုမူ သိမ်းထားပါမည်။</translation> <translation id="3920504717067627103">လက်မှတ်ဆိုင်ရာ မူဝါဒများ</translation> <translation id="392089482157167418">ChromeVox ကို ဖွင့်ထားရန်(နှုတ်ပြော အကြံပြုချက်)</translation> @@ -5930,6 +5931,7 @@ <translation id="7167486101654761064">&ဒီပုံစံ ဖိုင်များကို အမြဲတမ်း ဖွင့်ရန်</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> အား ဒေါင်းလုပ်ရယူနေစဉ်</translation> <translation id="7168109975831002660">အနည်းဆုံး ဖွန့် ဆိုက်</translation> +<translation id="7169122689956315694">အနီးတစ်ဝိုက်တွင် စက်များရှိပါက အကြောင်းကြားချက်ကို ဖွင့်ပါ</translation> <translation id="7170236477717446850">ပရိုဖိုင် ပုံ</translation> <translation id="7171000599584840888">ပရိုဖိုင် ထည့်ရန်...</translation> <translation id="7171259390164035663">စာရင်းမသွင်းရန်</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index 884279d..fb1a404 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -1054,6 +1054,7 @@ <translation id="204914487372604757">Opprett snarvei</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2053312383184521053">Data om hviletilstand</translation> +<translation id="2054240652864153171">Vil du slette nettstedsdata for <ph name="SITE_NAME" /> som er partisjonert på <ph name="PARTITION_SITE_NAME" />?</translation> <translation id="2055585478631012616">Du blir logget av disse nettstedene – inkludert i åpne faner</translation> <translation id="205560151218727633">Google Assistent-logo</translation> <translation id="2058456167109518507">Enhet oppdaget</translation> @@ -2399,6 +2400,7 @@ <translation id="3433621910545056227">Beklager. Systemet kunne ikke oppdage enhetens attributtlås for installasjonstid.</translation> <translation id="3434107140712555581"><ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="3434272557872943250">Hvis du har slått på innstillingen for annen nett- og appaktivitet for barnet ditt, kan disse dataene bli lagret i barnets Google-konto. Finn ut mer om disse innstillingene og hvordan du justerer dem, på families.google.com.</translation> +<translation id="3434512374684753970">Lyd og video</translation> <translation id="3435688026795609344">«<ph name="EXTENSION_NAME" />» ber om <ph name="CODE_TYPE" /></translation> <translation id="3435738964857648380">Sikkerhet</translation> <translation id="343578350365773421">Tom for papir</translation> @@ -2845,6 +2847,7 @@ <translation id="3873423927483480833">Vis PIN-koder</translation> <translation id="3873915545594852654">Det oppsto et problem med ARC++.</translation> <translation id="3874164307099183178">Slå på Google-assistenten</translation> +<translation id="3875783148670536197">Vis meg hvordan</translation> <translation id="3875815154304214043"><ph name="APP_NAME" /> er konfigurert til å åpnes i en ny nettleserfane. Støttede linker åpnes også i nettleseren. <ph name="BEGIN_LINK_LEARN_MORE" />Finn ut mer<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="3877075909000773256">Nærdelingsinnstillinger for enheten til <ph name="USER_NAME" />, som deles under kontoen <ph name="USER_EMAIL" />.</translation> <translation id="3879748587602334249">Nedlastingsbehandling</translation> @@ -4477,6 +4480,7 @@ <translation id="562935524653278697">Administratoren din har slått av synkronisering av bokmerker, logg, passord og andre innstillinger du har.</translation> <translation id="5631017369956619646">CPU-bruk</translation> <translation id="5632059346822207074">Nettstedet ber om tillatelse. Trykk på Ctrl + Frem for å svare</translation> +<translation id="5632485077360054581">Vis meg hvordan</translation> <translation id="5632566673632479864">Kontoen din (<ph name="EMAIL" />) er ikke tillatt som primærkonto lenger. Siden denne kontoen administreres av <ph name="DOMAIN" />, slettes bokmerkene, loggen, passordene og andre innstillinger du har, fra denne enheten.</translation> <translation id="5632592977009207922">Laster ned, <ph name="PERCENT_REMAINING" /> % gjenstår</translation> <translation id="563371367637259496">Mobil</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb index 165fb6a5..d7cfc96 100644 --- a/chrome/app/resources/generated_resources_or.xtb +++ b/chrome/app/resources/generated_resources_or.xtb
@@ -2884,6 +2884,7 @@ <translation id="3916445069167113093">ଏହି ପ୍ରକାର ଫାଇଲ୍ ଆପଣଙ୍କର କମ୍ପ୍ୟୁଟରକୁ କ୍ଷତି କରିପାରେ। ଯେକୌଣସି ମତେ ଆପଣ <ph name="FILE_NAME" /> ରଖିବାକୁ ଚାହୁଁଛନ୍ତି କି?</translation> <translation id="3918972485393593704">Googleକୁ ବିବରଣୀ ରିପୋର୍ଟ କରନ୍ତୁ</translation> <translation id="3919145445993746351">ଆପଣଙ୍କର ସମସ୍ତ କମ୍ପ୍ୟୁଟର୍ରେ ଆପଣଙ୍କର ଏକ୍ସଟେନ୍ସନ୍ ପାଇବା ପାଇଁ, ସିଙ୍କ୍ ଚାଲୁ କରନ୍ତୁ</translation> +<translation id="3919229493046408863">ଡିଭାଇସଗୁଡ଼ିକ ଆଖପାଖରେ ଥିବା ସମୟରେ ବିଜ୍ଞପ୍ତି ବନ୍ଦ କରନ୍ତୁ</translation> <translation id="3919798653937160644">ଏହି ୱିଣ୍ଡୋରେ ଆପଣ ଦେଖୁଥିବା ପୃଷ୍ଠାଗୁଡ଼ିକ ବ୍ରାଉଜର୍ ଇତିହାସରେ ଦେଖାଯିବ ନାହିଁ ଏବଂ କମ୍ପ୍ୟୁଟରରେ ଖୋଲାଥିବା ସମସ୍ତ ଅତିଥି ୱିଣ୍ଡୋକୁ ଆପଣ ବନ୍ଦ କରିବା ପରେ ସେଗୁଡ଼ିକ କୁକୀ ପରି ଅନ୍ୟ ଟ୍ରେସ୍ ଛାଡ଼ିବ ନାହିଁ। କିନ୍ତୁ, ଆପଣ ଡାଉନଲୋଡ୍ କରିଥିବା ଯେ କୌଣସି ଫାଇଲକୁ ସଂରକ୍ଷିତ ରଖାଯିବ।</translation> <translation id="3920504717067627103">ସାର୍ଟିଫିକେଟ୍ ନୀତିଗୁଡ଼ିକ</translation> <translation id="392089482157167418">ChromeVox ସକ୍ଷମ କରନ୍ତୁ (କଥିତ ମତାମତ)</translation> @@ -5919,6 +5920,7 @@ <translation id="7167486101654761064">&ସର୍ବଦା ଏହି ପ୍ରକାରର ଫାଇଲଗୁଡିକୁ ଖୋଲନ୍ତୁ</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> ଡାଉନ୍ଲୋଡ୍ ହେଉଛି</translation> <translation id="7168109975831002660">ସର୍ବନିମ୍ନ ଫଣ୍ଟ ଆକାର</translation> +<translation id="7169122689956315694">ଡିଭାଇସଗୁଡ଼ିକ ଆଖପାଖରେ ଥିବା ସମୟରେ ବିଜ୍ଞପ୍ତି ଚାଲୁ କରନ୍ତୁ</translation> <translation id="7170236477717446850">ପ୍ରୋଫାଇଲ୍ ଛବି</translation> <translation id="7171000599584840888">ପ୍ରୋଫାଇଲ୍ ଯୋଗ କରନ୍ତୁ...</translation> <translation id="7171259390164035663">ପଞ୍ଜିକରଣ କରନ୍ତୁ ନାହିଁ</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb index ba47b0c..9d19f16 100644 --- a/chrome/app/resources/generated_resources_si.xtb +++ b/chrome/app/resources/generated_resources_si.xtb
@@ -2890,6 +2890,7 @@ <translation id="3916445069167113093">මෙම වර්ගයේ ගොනු ඔබේ පරිගණකයට හානි කල හැක. ඔබට <ph name="FILE_NAME" /> තබා ගැනීමට අවශ්යද?</translation> <translation id="3918972485393593704">Google වෙත විස්තර වාර්තා කරන්න</translation> <translation id="3919145445993746351">ඔබේ පරිගණක සියල්ලෙහිම ඔබේ දිගු ලබා ගැනීමට, සමමුහූර්තය සක්රීය කරන්න</translation> +<translation id="3919229493046408863">උපාංග අවට ඇති විට දැනුම්දීම් ක්රියාවිරහිත කරන්න</translation> <translation id="3919798653937160644">මෙම කවුළුව තුළ ඔබ නරඹන පිටු බ්රවුස් කිරීමේ ඉතිහාසය තුළ නොපෙන්වනු ඇති අතර ඔබ සියලු විවෘත ආගන්තුක කවුළු වැසීමෙන් පසුව ඒවා කුකි වැනි වෙනත් හෝඩුවාවල් පරිගණකයේ නොතබනු ඇත. කෙසේ වෙතත්, ඔබ බාගන්නා ඕනෑම ගොනුවක් සංරක්ෂණය කරනු ඇත.</translation> <translation id="3920504717067627103">සහතික ප්රතිපත්ති</translation> <translation id="392089482157167418">ChromeVox සක්රීයකරන්න (කථික ප්රතිචාර feedback)</translation> @@ -5922,6 +5923,7 @@ <translation id="7167486101654761064">මෙම වර්ගය සඳහා සැමවිටම ගොනු විවෘත කරන්න (&A)</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> බාගනිමින්</translation> <translation id="7168109975831002660">අවම අකුරු ප්රමාණය</translation> +<translation id="7169122689956315694">උපාංග අවට ඇති විට දැනුම්දීම් ක්රියාවිරහිත කරන්න</translation> <translation id="7170236477717446850">පැතිකඩ පින්තූරය</translation> <translation id="7171000599584840888">පැතිකඩ එක් කරන්න...</translation> <translation id="7171259390164035663">ඇතුළත් නොවන්න</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index baf6904..85ac340e 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">Den här typen av fil kan skada datorn. Vill du behålla <ph name="FILE_NAME" /> ändå?</translation> <translation id="3918972485393593704">Rapportera informationen till Google</translation> <translation id="3919145445993746351">Aktivera synkronisering om du vill ha tilläggen på alla dina datorer</translation> +<translation id="3919229493046408863">Inaktivera avisering när det finns enheter i närheten</translation> <translation id="3919798653937160644">Sidorna som du visar i det här fönstret visas inte i webbläsarhistoriken och lämnar inga andra spår, till exempel cookies, på datorn när du har stängt alla öppna gästfönster. Filer som du laddar ned kommer dock att sparas.</translation> <translation id="3920504717067627103">Certifikatpolicyer</translation> <translation id="392089482157167418">Aktivera ChromeVox (talad feedback)</translation> @@ -5935,6 +5936,7 @@ <translation id="7167486101654761064">Öppna &alltid filer av denna typ</translation> <translation id="716810439572026343">Laddar ned <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Minsta teckenstorlek</translation> +<translation id="7169122689956315694">Aktivera avisering när det finns enheter i närheten</translation> <translation id="7170236477717446850">Profilbild</translation> <translation id="7171000599584840888">Lägg till profil …</translation> <translation id="7171259390164035663">Registrera dig inte</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index 3ea8103..356e9ea 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -2884,6 +2884,7 @@ <translation id="3916445069167113093">Bu türden bir dosya bilgisayarınıza zarar verebilir. <ph name="FILE_NAME" /> adlı dosyayı yine de saklamak istiyor musunuz?</translation> <translation id="3918972485393593704">Ayrıntıları Google'a bildir</translation> <translation id="3919145445993746351">Uzantıları tüm bilgisayarlarınızda almak için senkronizasyonu açın</translation> +<translation id="3919229493046408863">Cihazlar yakındayken bildirimi kapatın</translation> <translation id="3919798653937160644">Bu pencerede görüntülediğiniz sayfalar, tarama geçmişinde görünmez ve açık olan tüm Misafir pencerelerini kapattığınızda bilgisayarda çerez gibi başka izler bırakmaz. Ancak indirdiğiniz dosyalar saklanır.</translation> <translation id="3920504717067627103">Sertifika Politikaları</translation> <translation id="392089482157167418">ChromeVox'u (sesli geri bildirim) etkinleştir</translation> @@ -5918,6 +5919,7 @@ <translation id="7167486101654761064">&Bu tür dosyaları her zaman aç</translation> <translation id="716810439572026343"><ph name="FILE_NAME" /> indiriliyor</translation> <translation id="7168109975831002660">Minimum yazı tipi boyutu</translation> +<translation id="7169122689956315694">Cihazlar yakındayken bildirimi açın</translation> <translation id="7170236477717446850">Profil resmi</translation> <translation id="7171000599584840888">Profil Ekle...</translation> <translation id="7171259390164035663">Kaydolma</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index 7dac691..149bf67e 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -2901,6 +2901,7 @@ <translation id="3916445069167113093">Loại tệp này có thể gây hại cho máy tính của bạn. Bạn có muốn giữ tệp <ph name="FILE_NAME" /> không?</translation> <translation id="3918972485393593704">Báo cáo chi tiết cho Google</translation> <translation id="3919145445993746351">Để có các tiện ích trên tất cả các máy tính, hãy bật tính năng đồng bộ hóa</translation> +<translation id="3919229493046408863">Tắt thông báo khi có thiết bị ở gần</translation> <translation id="3919798653937160644">Những trang bạn xem trong cửa sổ này sẽ không xuất hiện trong nhật ký duyệt web của trình duyệt, cũng như không để lại dấu vết khác (chẳng hạn như cookie) trên máy tính sau khi bạn đóng tất cả cửa sổ Khách đang mở. Tuy nhiên, hệ thống vẫn sẽ lưu giữ mọi tệp mà bạn tải xuống.</translation> <translation id="3920504717067627103">Chính sách Chứng chỉ</translation> <translation id="392089482157167418">Bật ChromeVox (phản hồi bằng giọng nói)</translation> @@ -5935,6 +5936,7 @@ <translation id="7167486101654761064">&Luôn mở loại tệp này</translation> <translation id="716810439572026343">Đang tải xuống <ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Kích thước phông chữ tối thiểu</translation> +<translation id="7169122689956315694">Bật thông báo khi có thiết bị ở gần</translation> <translation id="7170236477717446850">Ảnh hồ sơ</translation> <translation id="7171000599584840888">Thêm hồ sơ...</translation> <translation id="7171259390164035663">Không đăng ký</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb index 78ac42b..be616d5d 100644 --- a/chrome/app/resources/generated_resources_zu.xtb +++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -2900,6 +2900,7 @@ <translation id="3916445069167113093">Lolu hlobo lwefayela lungalimaza ikhompyutha yakho. Ingabe ufuna ukugcina i-<ph name="FILE_NAME" /> noma kunjalo?</translation> <translation id="3918972485393593704">Bika imininingwane ku-Google</translation> <translation id="3919145445993746351">Ukuze uthole izandiso zakho kuwo wonke amakhompyutha akho, vula ukuvumelanisa</translation> +<translation id="3919229493046408863">Vala isaziso uma amadivayisi aseduze</translation> <translation id="3919798653937160644">Amakhasi owabuka kuleli windi ngeke avele kumlando wesiphequluli futhi ngeke aze ashiye okunye ukulandelelwa, okufana namakhukhi, kukhompyutha ngemuva kokuthi uvale wonke amawindi wesihambeli. Noma yimaphi amafayela owalandayo azogcinwa, noma kunjalo.</translation> <translation id="3920504717067627103">Izinqubomgomo zesitifiketi</translation> <translation id="392089482157167418">Nika amandla i-ChromeVox (inkulumo ekhulunywayo)</translation> @@ -5936,6 +5937,7 @@ <translation id="7167486101654761064">&Hlala uvule amafayela walolu hlobo</translation> <translation id="716810439572026343">Ilanda i-<ph name="FILE_NAME" /></translation> <translation id="7168109975831002660">Usayizi omncane wefonti</translation> +<translation id="7169122689956315694">Vula isaziso uma amadivayisi aseduze</translation> <translation id="7170236477717446850">Isithombe sephrofayela</translation> <translation id="7171000599584840888">Engeza iphrofayela...</translation> <translation id="7171259390164035663">Ungahbalisi</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index bc7b1ad0..cefe418 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -726,17 +726,14 @@ <message name="IDS_SETTINGS_PASSWORD_ROW_FEDERATED_MORE_ACTIONS" desc="The ARIA (accessibility) message for the More Actions button, which sits in every row of the password list. For this row does not include a password, only information of the account. It opens a menu with a list of actions, which apply to the account presented on this row."> More actions, saved account for <ph name="USERNAME">$1<ex>example@gmail.com</ex></ph> on <ph name="DOMAIN">$2<ex>www.google.com</ex></ph> </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_LABEL" desc="Label for the trusted vault encryption banner in settings."> - Trusted vault + <message name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_LABEL" desc="Label for the on-device encryption banner in settings."> + On-device encryption </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN" desc="Sub-label for the trusted vault encryption banner in settings, when the user is being offered to opt in."> - Opt in to trusted vault + <message name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN" desc="Sub-label for the on-device encryption banner in settings, when the user is being offered to opt in."> + Encrypt passwords on your device before they‘re saved to Google Password Manager </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN" desc="Sub-label for the trusted vault encryption banner in settings, when the user is already opted in."> - You are opted in to trusted vault + <message name="IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN" desc="Sub-label for the on-device encryption banner in settings, when the user is already opted in."> + Your password are encrypted on your device before they‘re saved to Google Password Manager </message> <message name="IDS_SETTINGS_PASSWORD_SHOW_PASSWORD_A11Y" desc="The ARIA (accessibility) message for the 'Show Password' button, which sits in every row of the password list. For this row does not include a password, only information of the account. Reveals password when clicked."> Show password for <ph name="USERNAME">$1<ex>example@gmail.com</ex></ph> on <ph name="DOMAIN">$2<ex>www.google.com</ex></ph>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_LABEL.png.sha1 new file mode 100644 index 0000000..fdf2ccd --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_LABEL.png.sha1
@@ -0,0 +1 @@ +d5480fb7ac6f87fea116024a821ad4a49c1f8fa0 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1 new file mode 100644 index 0000000..fdf2ccd --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1
@@ -0,0 +1 @@ +d5480fb7ac6f87fea116024a821ad4a49c1f8fa0 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1 new file mode 100644 index 0000000..2a11878 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1
@@ -0,0 +1 @@ +27104462c1dfd56d0bff3576689e2ed601514e8e \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 6536b2c..6cd5a905 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2734,8 +2734,6 @@ "android/contextualsearch/unhandled_tap_web_contents_observer.cc", "android/contextualsearch/unhandled_tap_web_contents_observer.h", "android/cookies/cookies_fetcher_util.cc", - "android/crash/pure_java_exception_handler.cc", - "android/crash/pure_java_exception_handler.h", "android/customtabs/client_data_header_web_contents_observer.cc", "android/customtabs/client_data_header_web_contents_observer.h", "android/customtabs/custom_tabs_connection.cc", @@ -5786,6 +5784,8 @@ "enterprise/connectors/device_trust/browser/browser_device_trust_connector_service.h", "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.cc", "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.h", + "enterprise/remote_commands/rotate_attestation_credential_job.cc", + "enterprise/remote_commands/rotate_attestation_credential_job.h", ] public_deps += [ "//chrome/browser/enterprise/connectors/device_trust/attestation/common/proto:attestation_ca_proto",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 817e55d..3b1a657 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -657,14 +657,6 @@ switches::kDisableGpuRasterization, ""}, }; -const FeatureEntry::Choice kEnableOopRasterizationChoices[] = { - {flags_ui::kGenericExperimentChoiceDefault, "", ""}, - {flags_ui::kGenericExperimentChoiceEnabled, - switches::kEnableOopRasterization, ""}, - {flags_ui::kGenericExperimentChoiceDisabled, - switches::kDisableOopRasterization, ""}, -}; - const FeatureEntry::Choice kExtensionContentVerificationChoices[] = { {flags_ui::kGenericExperimentChoiceDefault, "", ""}, {flag_descriptions::kExtensionContentVerificationBootstrap, @@ -755,6 +747,28 @@ }; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_NACL) +// Note: This needs to be kept in sync with parsing in +// content/common/zygote/zygote_communication_linux.cc +const FeatureEntry::Choice kVerboseLoggingInNaclChoices[] = { + {flag_descriptions::kVerboseLoggingInNaclChoiceDefault, "", ""}, + {flag_descriptions::kVerboseLoggingInNaclChoiceLow, + switches::kVerboseLoggingInNacl, switches::kVerboseLoggingInNaclChoiceLow}, + {flag_descriptions::kVerboseLoggingInNaclChoiceMedium, + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceMedium}, + {flag_descriptions::kVerboseLoggingInNaclChoiceHigh, + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceHigh}, + {flag_descriptions::kVerboseLoggingInNaclChoiceHighest, + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceHighest}, + {flag_descriptions::kVerboseLoggingInNaclChoiceDisabled, + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceDisabled}, +}; +#endif // ENABLE_NACL + const FeatureEntry::Choice kEnableUseZoomForDSFChoices[] = { {flag_descriptions::kEnableUseZoomForDsfChoiceDefault, "", ""}, {flag_descriptions::kEnableUseZoomForDsfChoiceEnabled, @@ -2655,14 +2669,17 @@ const FeatureEntry::FeatureParam kQuickDim120s[] = {{"quick_dim_ms", "120000"}}; -const FeatureEntry::FeatureParam kQuickDim30s[] = {{"quick_dim_ms", "30000"}}; +const FeatureEntry::FeatureParam kQuickDim45s[] = {{"quick_dim_ms", "45000"}}; + +const FeatureEntry::FeatureParam kQuickDim10s[] = {{"quick_dim_ms", "10000"}}; const FeatureEntry::FeatureParam kQuickDimInstantly[] = { {"quick_dim_ms", "1000"}}; const FeatureEntry::FeatureVariation kQuickDimVariations[] = { {"QuickDim120s", kQuickDim120s, base::size(kQuickDim120s), nullptr}, - {"QuickDim30s", kQuickDim30s, base::size(kQuickDim30s), nullptr}, + {"QuickDim45s", kQuickDim45s, base::size(kQuickDim45s), nullptr}, + {"QuickDim10s", kQuickDim10s, base::size(kQuickDim10s), nullptr}, {"QuickDimInstantly", kQuickDimInstantly, base::size(kQuickDimInstantly), nullptr}}; #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -2800,6 +2817,9 @@ {"enable-nacl", flag_descriptions::kNaclName, flag_descriptions::kNaclDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableNaCl)}, + {"verbose-logging-in-nacl", flag_descriptions::kVerboseLoggingInNaclName, + flag_descriptions::kVerboseLoggingInNaclDescription, kOsAll, + MULTI_VALUE_TYPE(kVerboseLoggingInNaclChoices)}, #endif // ENABLE_NACL #if BUILDFLAG(ENABLE_EXTENSIONS) {"extensions-on-chrome-urls", @@ -2989,9 +3009,6 @@ {"enable-gpu-rasterization", flag_descriptions::kGpuRasterizationName, flag_descriptions::kGpuRasterizationDescription, kOsAll, MULTI_VALUE_TYPE(kEnableGpuRasterizationChoices)}, - {"enable-oop-rasterization", flag_descriptions::kOopRasterizationName, - flag_descriptions::kOopRasterizationDescription, kOsAll, - MULTI_VALUE_TYPE(kEnableOopRasterizationChoices)}, {"enable-oop-rasterization-ddl", flag_descriptions::kOopRasterizationDDLName, flag_descriptions::kOopRasterizationDDLDescription, kOsAll, @@ -4225,8 +4242,8 @@ flag_descriptions::kExperimentalAccessibilityDictationExtensionName, flag_descriptions::kExperimentalAccessibilityDictationExtensionDescription, kOsCrOS, - SINGLE_VALUE_TYPE( - ::switches::kEnableExperimentalAccessibilityDictationExtension)}, + FEATURE_VALUE_TYPE( + features::kExperimentalAccessibilityDictationExtension)}, {"enable-experimental-accessibility-dictation-offline", flag_descriptions::kExperimentalAccessibilityDictationOfflineName, flag_descriptions::kExperimentalAccessibilityDictationOfflineDescription, @@ -5663,13 +5680,6 @@ flag_descriptions::kFileHandlingIconsDescription, kOsDesktop, FEATURE_VALUE_TYPE(blink::features::kFileHandlingIcons)}, -#if BUILDFLAG(IS_CHROMEOS_ASH) - {"enable-assistant-launcher-integration", - flag_descriptions::kEnableAssistantLauncherIntegrationName, - flag_descriptions::kEnableAssistantLauncherIntegrationDescription, kOsCrOS, - FEATURE_VALUE_TYPE(app_list_features::kEnableAssistantSearch)}, -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - {"strict-origin-isolation", flag_descriptions::kStrictOriginIsolationName, flag_descriptions::kStrictOriginIsolationDescription, kOsAll, FEATURE_VALUE_TYPE(features::kStrictOriginIsolation)}, @@ -6616,7 +6626,7 @@ {"enable-bluetooth-spp-in-serial-api", flag_descriptions::kEnableBluetoothSerialPortProfileInSerialApiName, flag_descriptions::kEnableBluetoothSerialPortProfileInSerialApiDescription, - kOsAll, + kOsDesktop, SINGLE_VALUE_TYPE(switches::kEnableBluetoothSerialPortProfileInSerialApi)}, {"add-passwords-in-settings", @@ -6970,15 +6980,17 @@ flag_descriptions::kSendTabToSelfManageDevicesLinkDescription, kOsAll, FEATURE_VALUE_TYPE(send_tab_to_self::kSendTabToSelfManageDevicesLink)}, +#if defined(OS_ANDROID) {"send-tab-to-self-v2", flag_descriptions::kSendTabToSelfV2Name, - flag_descriptions::kSendTabToSelfV2Description, kOsAll, + flag_descriptions::kSendTabToSelfV2Description, kOsAndroid, FEATURE_VALUE_TYPE(send_tab_to_self::kSendTabToSelfV2)}, +#endif // defined(OS_ANDROID) #if defined(OS_WIN) {"raw-audio-capture", flag_descriptions::kRawAudioCaptureName, flag_descriptions::kRawAudioCaptureDescription, kOsWin, FEATURE_VALUE_TYPE(media::kWasapiRawAudioCapture)}, -#endif // defined(OS_MAC) +#endif // defined(OS_WIN) {"enable-managed-configuration-web-api", flag_descriptions::kEnableManagedConfigurationWebApiName, @@ -7759,7 +7771,7 @@ #if defined(OS_CHROMEOS) {"link-capturing-ui-update", flag_descriptions::kLinkCapturingUiUpdateName, flag_descriptions::kLinkCapturingUiUpdateDescription, kOsCrOS, - FEATURE_VALUE_TYPE(features::kLinkCapturingUiUpdate)} + FEATURE_VALUE_TYPE(features::kLinkCapturingUiUpdate)}, #endif #if defined(OS_ANDROID) @@ -7772,9 +7784,16 @@ {"use-ulp-languages-in-chrome", flag_descriptions::kUseULPLanguagesInChromeName, flag_descriptions::kUseULPLanguagesInChromeDescription, kOsAndroid, - FEATURE_VALUE_TYPE(language::kUseULPLanguagesInChrome)} + FEATURE_VALUE_TYPE(language::kUseULPLanguagesInChrome)}, #endif + {"autofill-enable-update-virtual-card-enrollment", + flag_descriptions::kAutofillEnableUpdateVirtualCardEnrollmentName, + flag_descriptions::kAutofillEnableUpdateVirtualCardEnrollmentDescription, + kOsAll, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillEnableUpdateVirtualCardEnrollment)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc index b4d7a75..efc4a13 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/ash/accessibility/magnification_manager.h" #include "chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 9afb89f..fbaf3452 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -442,8 +442,13 @@ SetOverlayState(OverlayState::HIDDEN); SetSpinPoodle(false); - Java_AssistantModel_setVisible(AttachCurrentThread(), GetModel(), false); - DestroySelf(); + if (!ui_delegate_->NeedsUI()) { + Java_AssistantModel_setVisible(AttachCurrentThread(), GetModel(), + false); + DestroySelf(); + } else if (ui_delegate_->IsTabSelected()) { + ShowContentAndExpandBottomSheet(); + } return; case AutofillAssistantState::INACTIVE: @@ -807,7 +812,8 @@ if (!has_close_or_cancel) { base::android::ScopedJavaLocalRef<jobject> jcancel_chip; - if (ui_delegate_->GetState() == AutofillAssistantState::STOPPED) { + if (ui_delegate_->GetState() == AutofillAssistantState::STOPPED || + ui_delegate_->GetState() == AutofillAssistantState::TRACKING) { jcancel_chip = Java_AutofillAssistantUiController_createCloseButton( env, java_object_, ICON_CLEAR, ConvertUTF8ToJavaString(env, ""), /* disabled= */ false, /* sticky= */ true, /* visible=*/true,
diff --git a/chrome/browser/android/crash/pure_java_exception_handler.h b/chrome/browser/android/crash/pure_java_exception_handler.h deleted file mode 100644 index f6db1db..0000000 --- a/chrome/browser/android/crash/pure_java_exception_handler.h +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ANDROID_CRASH_PURE_JAVA_EXCEPTION_HANDLER_H_ -#define CHROME_BROWSER_ANDROID_CRASH_PURE_JAVA_EXCEPTION_HANDLER_H_ - -void UninstallPureJavaExceptionHandler(); - -#endif // CHROME_BROWSER_ANDROID_CRASH_PURE_JAVA_EXCEPTION_HANDLER_H_
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc index 68aa480..e71857c 100644 --- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc +++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
@@ -168,7 +168,7 @@ } void OomInterventionTabHelper::PrimaryPageChanged(content::Page& page) { - if (!page.GetMainDocument().IsDocumentOnLoadCompletedInMainFrame()) + if (!page.GetMainDocument().IsDocumentOnLoadCompletedInPrimaryMainFrame()) return; if (IsLastVisibleWebContents(web_contents())) StartMonitoringIfNeeded(); @@ -184,10 +184,7 @@ } } -void OomInterventionTabHelper::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { - if (!render_frame_host->GetPage().IsPrimary()) - return; +void OomInterventionTabHelper::DocumentOnLoadCompletedInPrimaryMainFrame() { if (IsLastVisibleWebContents(web_contents())) StartMonitoringIfNeeded(); } @@ -236,7 +233,7 @@ if (near_oom_detected_time_) return; - if (!web_contents()->IsDocumentOnLoadCompletedInMainFrame()) + if (!web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame()) return; auto* config = OomInterventionConfig::GetInstance();
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h index f34f223..ce9b10e 100644 --- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h +++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
@@ -63,8 +63,7 @@ content::NavigationHandle* navigation_handle) override; void PrimaryPageChanged(content::Page& page) override; void OnVisibilityChanged(content::Visibility visibility) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; // CrashDumpManager::Observer: void OnCrashDumpProcessed(
diff --git a/chrome/browser/android/search_permissions/search_permissions_service.cc b/chrome/browser/android/search_permissions/search_permissions_service.cc index 3a2d5b0f..186d784 100644 --- a/chrome/browser/android/search_permissions/search_permissions_service.cc +++ b/chrome/browser/android/search_permissions/search_permissions_service.cc
@@ -226,6 +226,7 @@ } SearchPermissionsService::PrefValue SearchPermissionsService::GetDSEPref() { + // TODO(crbug.com/1187061): Refactor this to remove base::DictionaryValue. const base::DictionaryValue* dict = &base::Value::AsDictionaryValue( *pref_service_->GetDictionary(prefs::kDSEPermissionsSettings));
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc index 5cf22d72..17276df2 100644 --- a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc +++ b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
@@ -401,7 +401,7 @@ base::WrapRefCounted(this))); return; } - FALLTHROUGH; + [[fallthrough]]; case IconType::kUncompressed: if (icon_type_ == apps::IconType::kUncompressed) { // For uncompressed icon, apply the resize and pad effect. @@ -412,7 +412,7 @@ icon_effects_ &= ~apps::IconEffects::kCrOsStandardBackground; icon_effects_ &= ~apps::IconEffects::kCrOsStandardMask; } - FALLTHROUGH; + [[fallthrough]]; case IconType::kStandard: { // If |icon_effects| are requested, we must always load the // uncompressed image to apply the icon effects, and then re-encode the @@ -475,9 +475,9 @@ base::WrapRefCounted(this))); return; } - FALLTHROUGH; + [[fallthrough]]; case IconType::kUncompressed: - FALLTHROUGH; + [[fallthrough]]; case IconType::kStandard: // If |icon_effects| are requested, we must always load the // uncompressed image to apply the icon effects, and then re-encode @@ -563,9 +563,9 @@ CompleteWithCompressed(std::vector<uint8_t>(data.begin(), data.end())); return; } - FALLTHROUGH; + [[fallthrough]]; case IconType::kUncompressed: - FALLTHROUGH; + [[fallthrough]]; case IconType::kStandard: { // For compressed icons with |icon_effects|, or for uncompressed // icons, we load the uncompressed image, apply the icon effects, and
diff --git a/chrome/browser/apps/app_service/browser_app_launcher.cc b/chrome/browser/apps/app_service/browser_app_launcher.cc index c09d894..e0fb659 100644 --- a/chrome/browser/apps/app_service/browser_app_launcher.cc +++ b/chrome/browser/apps/app_service/browser_app_launcher.cc
@@ -38,7 +38,7 @@ const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension( params.app_id); - if (!extension || extension->from_bookmark()) { + if (!extension) { #if BUILDFLAG(IS_CHROMEOS_ASH) AppLaunchParams params_for_restore(params.app_id, params.container, params.disposition, params.launch_source, @@ -87,8 +87,6 @@ #endif } - DCHECK(!extension->from_bookmark()); - #if BUILDFLAG(IS_CHROMEOS_ASH) // If the restore id is available, save the launch parameters to the full // restore file. @@ -138,7 +136,7 @@ const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension( app_id); - if (!extension || extension->from_bookmark()) { + if (!extension) { web_app_launch_manager_.LaunchApplication( app_id, command_line, current_directory, url_handler_launch_url, protocol_handler_launch_url, launch_files, std::move(callback));
diff --git a/chrome/browser/apps/app_service/media_access_browsertest.cc b/chrome/browser/apps/app_service/media_access_browsertest.cc index 4807bb0..7e1afa9 100644 --- a/chrome/browser/apps/app_service/media_access_browsertest.cc +++ b/chrome/browser/apps/app_service/media_access_browsertest.cc
@@ -288,7 +288,7 @@ // Request accessing the camera for |web_contents|. MediaRequestChangeForWebContent( - web_contents, web_contents->GetURL(), + web_contents, web_contents->GetLastCommittedURL(), blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE, content::MEDIA_REQUEST_STATE_DONE); @@ -297,7 +297,7 @@ // Request accessing the microphone for |web_contents|. MediaRequestChangeForWebContent( - web_contents, web_contents->GetURL(), + web_contents, web_contents->GetLastCommittedURL(), blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE, content::MEDIA_REQUEST_STATE_DONE); @@ -306,7 +306,7 @@ // Stop accessing the microphone for |web_contents|. MediaRequestChangeForWebContent( - web_contents, web_contents->GetURL(), + web_contents, web_contents->GetLastCommittedURL(), blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE, content::MEDIA_REQUEST_STATE_CLOSING); @@ -315,7 +315,7 @@ // Stop accessing the camera for |web_contents|. MediaRequestChangeForWebContent( - web_contents, web_contents->GetURL(), + web_contents, web_contents->GetLastCommittedURL(), blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE, content::MEDIA_REQUEST_STATE_CLOSING);
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc index 1102741..035743e 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.cc +++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -93,9 +93,9 @@ switch (icon_type) { case apps::IconType::kCompressed: - FALLTHROUGH; + [[fallthrough]]; case apps::IconType::kUncompressed: - FALLTHROUGH; + [[fallthrough]]; case apps::IconType::kStandard: { iv->uncompressed = icon->is_adaptive_icon()
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps.cc b/chrome/browser/apps/app_service/publishers/extension_apps.cc index f84cbdd..b889f96 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps.cc
@@ -32,7 +32,7 @@ return false; } - return !extension->from_bookmark(); + return true; } bool ExtensionApps::ShouldShownInLauncher(
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc index b8c6889..63691b5a 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -120,25 +120,6 @@ } } -// static -void ExtensionAppsChromeOs::RecordUninstallCanceledAction( - Profile* profile, - const std::string& app_id) { - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension( - app_id); - if (!extension) { - return; - } - - if (extension->from_bookmark()) { - UMA_HISTOGRAM_ENUMERATION( - "Webapp.UninstallDialogAction", - extensions::ExtensionUninstallDialog::CLOSE_ACTION_CANCELED, - extensions::ExtensionUninstallDialog::CLOSE_ACTION_LAST); - } -} - void ExtensionAppsChromeOs::Shutdown() { if (arc_prefs_) { arc_prefs_->RemoveObserver(this); @@ -510,7 +491,8 @@ } absl::optional<web_app::AppId> web_app_id = - web_app::FindInstalledAppWithUrlInScope(profile(), web_contents->GetURL(), + web_app::FindInstalledAppWithUrlInScope(profile(), + web_contents->GetVisibleURL(), /*window_only=*/false); if (web_app_id.has_value()) { // WebAppsChromeOs is responsible for |app_id|. @@ -523,7 +505,7 @@ DCHECK(registry); const extensions::ExtensionSet& extensions = registry->enabled_extensions(); const extensions::Extension* extension = - extensions.GetAppByURL(web_contents->GetURL()); + extensions.GetAppByURL(web_contents->GetVisibleURL()); if (extension && Accepts(extension)) { app_id = extension->id(); } @@ -726,7 +708,7 @@ if (!extension->is_app() || IsBlocklisted(extension->id())) { return false; } - return !extension->from_bookmark(); + return true; } void ExtensionAppsChromeOs::SetShowInFields(
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h index 3012028..49723bb 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h
@@ -29,8 +29,6 @@ #include "extensions/browser/app_window/app_window_registry.h" #include "mojo/public/cpp/bindings/remote.h" -class Profile; - namespace extensions { class AppWindow; } // namespace extensions @@ -67,10 +65,6 @@ ExtensionAppsChromeOs(const ExtensionAppsChromeOs&) = delete; ExtensionAppsChromeOs& operator=(const ExtensionAppsChromeOs&) = delete; - // Record uninstall dialog action for Web apps and Chrome apps. - static void RecordUninstallCanceledAction(Profile* profile, - const std::string& app_id); - void Shutdown(); void ObserveArc();
diff --git a/chrome/browser/apps/app_service/uninstall_dialog.cc b/chrome/browser/apps/app_service/uninstall_dialog.cc index b41f722..2194e427 100644 --- a/chrome/browser/apps/app_service/uninstall_dialog.cc +++ b/chrome/browser/apps/app_service/uninstall_dialog.cc
@@ -88,11 +88,6 @@ void UninstallDialog::OnDialogClosed(bool uninstall, bool clear_site_data, bool report_abuse) { - if (!uninstall && (app_type_ == apps::mojom::AppType::kChromeApp || - app_type_ == apps::mojom::AppType::kWeb)) { - ExtensionAppsChromeOs::RecordUninstallCanceledAction(profile_, app_id_); - } - std::move(uninstall_callback_) .Run(uninstall, clear_site_data, report_abuse, this); }
diff --git a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc index 1a9860e..e0a40ff 100644 --- a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc +++ b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
@@ -55,12 +55,11 @@ } auto* registry = extensions::ExtensionRegistry::Get(profile); - const GURL url = tab->GetURL(); + const GURL url = tab->GetVisibleURL(); const extensions::Extension* extension = registry->enabled_extensions().GetAppByURL(url); - if (extension && !extension->from_bookmark() && - !extensions::LaunchesInWindow(profile, extension)) { + if (extension && !extensions::LaunchesInWindow(profile, extension)) { return extension; } return nullptr; @@ -89,7 +88,7 @@ } absl::optional<web_app::AppId> app_id = - provider->registrar().FindAppWithUrlInScope(tab->GetURL()); + provider->registrar().FindAppWithUrlInScope(tab->GetVisibleURL()); if (app_id) { const web_app::WebApp* web_app = provider->registrar().GetAppById(*app_id); @@ -148,7 +147,7 @@ const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension( app_id); - if (extension && !extension->from_bookmark()) { + if (extension) { DCHECK(extension->is_app()); web_app::WebAppTabHelper::FromWebContents(web_contents) ->SetAppId(std::string()); @@ -167,7 +166,7 @@ const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension( app_id); - if (extension && !extension->from_bookmark()) { + if (extension) { DCHECK(extension->is_app()); return true; }
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc index 4bd1a15..cab94e7 100644 --- a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc +++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
@@ -132,7 +132,8 @@ } // Compare share files. - if (share_param.files_size() != share_info->file_names.size()) { + if (share_param.files_size() != + static_cast<int>(share_info->file_names.size())) { return true; } @@ -142,7 +143,7 @@ } if (share_param.files(i).accept_size() != - share_info->file_accepts[i].size()) { + static_cast<int>(share_info->file_accepts[i].size())) { return true; }
diff --git a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc index d1d6f22..bec0cd8 100644 --- a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc +++ b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc
@@ -150,10 +150,7 @@ bool ExtensionAppShimManagerDelegate::AppIsMultiProfile( Profile* profile, const web_app::AppId& app_id) { - const Extension* extension = MaybeGetAppExtension(profile, app_id); - if (!profile || !extension) - return false; - return extension->from_bookmark(); + return false; } bool ExtensionAppShimManagerDelegate::AppUsesRemoteCocoa( @@ -165,10 +162,8 @@ if (!extension->is_hosted_app()) return false; - // The Gmail, Google Drive, and YouTube apps behave like bookmark apps. // https://crbug.com/1086824 - return extension->from_bookmark() || - extension->id() == extension_misc::kYoutubeAppId || + return extension->id() == extension_misc::kYoutubeAppId || extension->id() == extension_misc::kGoogleDriveAppId || extension->id() == extension_misc::kGmailAppId; }
diff --git a/chrome/browser/apps/platform_apps/install_chrome_app.cc b/chrome/browser/apps/platform_apps/install_chrome_app.cc index cfd81b3..58793e5 100644 --- a/chrome/browser/apps/platform_apps/install_chrome_app.cc +++ b/chrome/browser/apps/platform_apps/install_chrome_app.cc
@@ -61,7 +61,7 @@ }; void WebstoreInstallWithPromptAppsOnly::OnManifestParsed() { - if (!manifest()->HasKey(extensions::manifest_keys::kApp)) { + if (!manifest()->FindKey(extensions::manifest_keys::kApp)) { CompleteInstall(extensions::webstore_install::NOT_PERMITTED, kInstallChromeAppErrorNotAnApp); return;
diff --git a/chrome/browser/apps/platform_apps/platform_app_launch.cc b/chrome/browser/apps/platform_apps/platform_app_launch.cc index 3b48a245..c7c0af5 100644 --- a/chrome/browser/apps/platform_apps/platform_app_launch.cc +++ b/chrome/browser/apps/platform_apps/platform_app_launch.cc
@@ -84,9 +84,6 @@ if (launch_container == extensions::LaunchContainer::kLaunchContainerTab) return false; - if (app->from_bookmark()) - return false; - RecordCmdLineAppHistogram(app->GetType()); apps::AppLaunchParams params(app_id, launch_container,
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.cc b/chrome/browser/apps/platform_apps/shortcut_manager.cc index 3008355c..1ae3dda 100644 --- a/chrome/browser/apps/platform_apps/shortcut_manager.cc +++ b/chrome/browser/apps/platform_apps/shortcut_manager.cc
@@ -121,11 +121,7 @@ const Extension* extension, bool is_update, const std::string& old_name) { - // Bookmark apps are handled in - // web_app::AppShortcutManager::OnWebAppInstalled() and - // web_app::AppShortcutManager::OnWebAppManifestUpdated(). - if (!extension->is_app() || extension->from_bookmark() || - g_suppress_shortcuts_for_testing) { + if (!extension->is_app() || g_suppress_shortcuts_for_testing) { return; } @@ -144,9 +140,7 @@ content::BrowserContext* browser_context, const Extension* extension, extensions::UninstallReason reason) { - // Bookmark apps are handled in - // web_app::AppShortcutManager::OnWebAppWillBeUninstalled() - if (!extension->from_bookmark() && !g_suppress_shortcuts_for_testing) + if (!g_suppress_shortcuts_for_testing) web_app::DeleteAllShortcuts(profile_, extension); }
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc index 757e0a5..1692fcc 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -87,7 +87,6 @@ #include "extensions/common/extension_resource.h" #include "services/audio/public/cpp/sounds/sounds_manager.h" #include "ui/accessibility/accessibility_features.h" -#include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/ime/ash/extension_ime_util.h" @@ -706,7 +705,7 @@ return; if (pref_name == ash::prefs::kAccessibilityDictationEnabled && - !::switches::IsExperimentalAccessibilityDictationExtensionEnabled()) { + !::features::IsExperimentalAccessibilityDictationExtensionEnabled()) { return; } @@ -1790,7 +1789,7 @@ if (!profile_) return false; - if (!::switches::IsExperimentalAccessibilityDictationExtensionEnabled()) { + if (!::features::IsExperimentalAccessibilityDictationExtensionEnabled()) { if (!dictation_.get()) dictation_ = std::make_unique<Dictation>(profile_);
diff --git a/chrome/browser/ash/accessibility/dictation.cc b/chrome/browser/ash/accessibility/dictation.cc index f81b2c6e..aee9e7c 100644 --- a/chrome/browser/ash/accessibility/dictation.cc +++ b/chrome/browser/ash/accessibility/dictation.cc
@@ -31,7 +31,6 @@ #include "services/audio/public/cpp/sounds/sounds_manager.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/accessibility/accessibility_features.h" -#include "ui/accessibility/accessibility_switches.h" #include "ui/base/ime/ash/extension_ime_util.h" #include "ui/base/ime/ash/ime_bridge.h" #include "ui/base/ime/ash/ime_input_context_handler_interface.h" @@ -248,7 +247,7 @@ : current_state_(SPEECH_RECOGNIZER_OFF), composition_(std::make_unique<ui::CompositionText>()), profile_(profile) { - DCHECK(!switches::IsExperimentalAccessibilityDictationExtensionEnabled()); + DCHECK(!features::IsExperimentalAccessibilityDictationExtensionEnabled()); if (GetInputContext() && GetInputContext()->GetInputMethod()) GetInputContext()->GetInputMethod()->AddObserver(this); }
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc index 8d2d961..32cfe60 100644 --- a/chrome/browser/ash/accessibility/dictation_browsertest.cc +++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -38,7 +38,6 @@ #include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/accessibility/accessibility_features.h" -#include "ui/accessibility/accessibility_switches.h" #include "ui/aura/window_tree_host.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_buffer.h" @@ -676,9 +675,9 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityDictationExtension); DictationBaseTest::SetUpCommandLine(command_line); + scoped_feature_list_.InitAndEnableFeature( + ::features::kExperimentalAccessibilityDictationExtension); } void SendFinalSpeechResultAndWaitForTextAreaValue(const std::string& result, @@ -764,6 +763,7 @@ std::unique_ptr<ui::MockIMEInputContextHandler> input_context_handler_; std::unique_ptr<ui::test::EventGenerator> generator_; std::unique_ptr<ExtensionConsoleErrorObserver> console_observer_; + base::test::ScopedFeatureList scoped_feature_list_; }; INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc index cfff5ff3..6218b6c 100644 --- a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -103,7 +103,9 @@ SwapResults(&results); } - ChromeSearchResult::ResultType ResultType() override { return result_type_; } + ChromeSearchResult::ResultType ResultType() const override { + return result_type_; + } void set_count(size_t count) { count_ = count; } void set_best_match_count(size_t count) { best_match_count_ = count; }
diff --git a/chrome/browser/ash/app_mode/kiosk_app_manager.cc b/chrome/browser/ash/app_mode/kiosk_app_manager.cc index 6bbe246..f3b2cce 100644 --- a/chrome/browser/ash/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/ash/app_mode/kiosk_app_manager.cc
@@ -147,26 +147,50 @@ const char KioskAppManager::kKioskDictionaryName[] = "kiosk"; const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state"; +class GlobalManager : public KioskAppManager { + public: + GlobalManager() = default; + GlobalManager(const GlobalManager&) = delete; + GlobalManager& operator=(const GlobalManager&) = delete; + ~GlobalManager() override = default; +}; + +static_assert(sizeof(GlobalManager) == sizeof(KioskAppManager), + "Global manager is intended to provide constructor visibility to " + "absl::optional, nothing more."); + +absl::optional<GlobalManager>& GetGlobalManager() { + static base::NoDestructor<absl::optional<GlobalManager>> manager; + return *manager; +} + // static -static base::LazyInstance<KioskAppManager>::DestructorAtExit instance = - LAZY_INSTANCE_INITIALIZER; KioskAppManager* KioskAppManager::Get() { - return instance.Pointer(); + absl::optional<GlobalManager>& manager = GetGlobalManager(); + if (!manager.has_value()) + manager.emplace(); + + return &manager.value(); } // static void KioskAppManager::InitializeForTesting(Overrides* overrides) { - DCHECK(!instance.IsCreated()); + DCHECK(!GetGlobalManager().has_value()); g_test_overrides = overrides; } // static void KioskAppManager::Shutdown() { - if (!instance.IsCreated()) + if (!GetGlobalManager().has_value()) return; - instance.Pointer()->CleanUp(); + KioskAppManager::Get()->CleanUp(); + g_test_overrides = nullptr; +} +// static +void KioskAppManager::ResetForTesting() { + GetGlobalManager().reset(); g_test_overrides = nullptr; } @@ -208,8 +232,7 @@ auto_launched_with_zero_delay_ = true; } -void KioskAppManager::InitSession(Profile* profile, - const std::string& app_id) { +void KioskAppManager::InitSession(Profile* profile, const std::string& app_id) { LOG_IF(FATAL, app_session_) << "Kiosk session is already initialized."; base::CommandLine session_flags(base::CommandLine::NO_PROGRAM); @@ -453,8 +476,8 @@ policy::GetDeviceLocalAccounts(CrosSettings::Get()); // Don't insert the app if it's already in the list. - for (std::vector<policy::DeviceLocalAccount>::const_iterator - it = device_local_accounts.begin(); + for (std::vector<policy::DeviceLocalAccount>::const_iterator it = + device_local_accounts.begin(); it != device_local_accounts.end(); ++it) { if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP && it->kiosk_app_id == app_id) { @@ -465,9 +488,7 @@ // Add the new account. device_local_accounts.push_back(policy::DeviceLocalAccount( policy::DeviceLocalAccount::TYPE_KIOSK_APP, - GenerateKioskAppAccountId(app_id), - app_id, - std::string())); + GenerateKioskAppAccountId(app_id), app_id, std::string())); policy::SetDeviceLocalAccounts(service, device_local_accounts); } @@ -484,8 +505,8 @@ return; // Remove entries that match |app_id|. - for (std::vector<policy::DeviceLocalAccount>::iterator - it = device_local_accounts.begin(); + for (std::vector<policy::DeviceLocalAccount>::iterator it = + device_local_accounts.begin(); it != device_local_accounts.end(); ++it) { if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP && it->kiosk_app_id == app_id) { @@ -748,8 +769,8 @@ // Re-populates |apps_| and reuses existing KioskAppData when possible. const std::vector<policy::DeviceLocalAccount> device_local_accounts = policy::GetDeviceLocalAccounts(CrosSettings::Get()); - for (std::vector<policy::DeviceLocalAccount>::const_iterator - it = device_local_accounts.begin(); + for (std::vector<policy::DeviceLocalAccount>::const_iterator it = + device_local_accounts.begin(); it != device_local_accounts.end(); ++it) { if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) continue; @@ -793,7 +814,8 @@ } void KioskAppManager::UpdateExternalCachePrefs() { - // Request external_cache_ to download new apps and update the existing apps. + // Request external_cache_ to download new apps and update the existing + // apps. std::unique_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); for (size_t i = 0; i < apps_.size(); ++i) { base::DictionaryValue entry;
diff --git a/chrome/browser/ash/app_mode/kiosk_app_manager.h b/chrome/browser/ash/app_mode/kiosk_app_manager.h index c0e91ded..33478bd 100644 --- a/chrome/browser/ash/app_mode/kiosk_app_manager.h +++ b/chrome/browser/ash/app_mode/kiosk_app_manager.h
@@ -11,7 +11,7 @@ #include <vector> #include "base/callback_forward.h" -#include "base/lazy_instance.h" +#include "base/no_destructor.h" #include "base/time/time.h" #include "chrome/browser/ash/app_mode/kiosk_app_manager_base.h" #include "chrome/browser/ash/settings/cros_settings.h" @@ -88,7 +88,7 @@ static const char kKioskDictionaryName[]; static const char kKeyAutoLoginState[]; - // Gets the KioskAppManager instance, which is lazily created on first call. + // Gets the KioskAppManager instance, which is created on first call. static KioskAppManager* Get(); // Initializes KioskAppManager for testing, injecting the provided overrides. @@ -100,6 +100,9 @@ // Prepares for shutdown and calls CleanUp() if needed. static void Shutdown(); + // Clears the global KioskAppManager. + static void ResetForTesting(); + // Registers kiosk app entries in local state. static void RegisterPrefs(PrefRegistrySimple* registry); @@ -244,8 +247,7 @@ const std::string& required_platform_version); private: - friend struct base::LazyInstanceTraitsBase<KioskAppManager>; - friend std::default_delete<KioskAppManager>; + friend class GlobalManager; friend class KioskAppManagerTest; friend class KioskAutoLaunchViewsTest; friend class KioskTest;
diff --git a/chrome/browser/ash/app_restore/full_restore_app_launch_handler.cc b/chrome/browser/ash/app_restore/full_restore_app_launch_handler.cc index 806a4e7..cd4b37da 100644 --- a/chrome/browser/ash/app_restore/full_restore_app_launch_handler.cc +++ b/chrome/browser/ash/app_restore/full_restore_app_launch_handler.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ash/app_restore/app_restore_arc_task_handler.h" #include "chrome/browser/ash/app_restore/arc_app_launch_handler.h" #include "chrome/browser/ash/app_restore/full_restore_service.h" +#include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/login/session/user_session_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -27,6 +28,7 @@ #include "chrome/browser/sessions/session_service_log.h" #include "chrome/browser/ui/startup/startup_tab.h" #include "chrome/common/chrome_switches.h" +#include "components/app_restore/features.h" #include "components/app_restore/full_restore_read_handler.h" #include "components/app_restore/full_restore_save_handler.h" #include "extensions/common/constants.h" @@ -163,6 +165,18 @@ browser_window_count_ = window_count; } +void FullRestoreAppLaunchHandler::OnMojoDisconnected() { + observation_.Reset(); +} + +void FullRestoreAppLaunchHandler::OnStateChanged() { + if (crosapi::BrowserManager::Get()->IsRunning()) { + observation_.Reset(); + crosapi::BrowserManager::Get()->NewWindow( + /*incognito=*/false, /*should_trigger_session_restore=*/true); + } +} + void FullRestoreAppLaunchHandler::ForceLaunchBrowserForTesting() { ::full_restore::AddChromeBrowserLaunchInfoForTesting(profile()->GetPath()); UserSessionManager::GetInstance()->LaunchBrowser(profile()); @@ -223,6 +237,8 @@ this); } + MaybeRestoreLacros(); + LaunchApps(); MaybeStartSaveTimer(); @@ -314,6 +330,31 @@ app_type_name); } +void FullRestoreAppLaunchHandler::MaybeRestoreLacros() { + if (!crosapi::browser_util::IsLacrosEnabled() || + !::full_restore::features::IsFullRestoreForLacrosEnabled()) { + return; + } + + // TODO(https://crbug.com/1239984): + // 1. Modify the restore conditions, e.g. check web apps ready, etc. + // 2. Handle the migration scenario, e.g. from flag disable to enable. + // 3. Add metrics to check whether the Lacros is restored successfully. + if (!base::Contains(restore_data()->app_id_to_launch_list(), + extension_misc::kLacrosAppId)) { + return; + } + + if (crosapi::BrowserManager::Get()->IsRunning()) { + crosapi::BrowserManager::Get()->NewWindow( + /*incognito=*/false, /*should_trigger_session_restore=*/true); + return; + } + + if (!crosapi::BrowserManager::Get()->IsTerminated()) + observation_.Observe(crosapi::BrowserManager::Get()); +} + void FullRestoreAppLaunchHandler::RecordLaunchBrowserResult() { RestoreTabResult result = RestoreTabResult::kNoTabs;
diff --git a/chrome/browser/ash/app_restore/full_restore_app_launch_handler.h b/chrome/browser/ash/app_restore/full_restore_app_launch_handler.h index 90879ce9..a457b43 100644 --- a/chrome/browser/ash/app_restore/full_restore_app_launch_handler.h +++ b/chrome/browser/ash/app_restore/full_restore_app_launch_handler.h
@@ -9,6 +9,8 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/app_restore/app_launch_handler.h" +#include "chrome/browser/ash/crosapi/browser_manager.h" +#include "chrome/browser/ash/crosapi/browser_manager_observer.h" #include "chrome/browser/sessions/session_restore_observer.h" #include "components/app_restore/restore_data.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -70,7 +72,8 @@ // the notification dialog. // 3. The app is ready. class FullRestoreAppLaunchHandler : public AppLaunchHandler, - public SessionRestoreObserver { + public SessionRestoreObserver, + public crosapi::BrowserManagerObserver { public: explicit FullRestoreAppLaunchHandler(Profile* profile, bool should_init_service = false); @@ -99,6 +102,10 @@ // SessionRestoreObserver: void OnGotSession(Profile* profile, bool for_apps, int window_count) override; + // crosapi::BrowserManagerObserver: + void OnMojoDisconnected() override; + void OnStateChanged() override; + // Force launch browser for testing. void ForceLaunchBrowserForTesting(); @@ -130,6 +137,8 @@ // browsers when upgrading to the full restore version. void LaunchBrowserForFirstRunFullRestore(); + void MaybeRestoreLacros(); + // AppLaunchHandler: void RecordRestoredAppLaunch(apps::AppTypeName app_type_name) override; @@ -157,6 +166,10 @@ int browser_app_window_count_ = 0; int browser_window_count_ = 0; + base::ScopedObservation<crosapi::BrowserManager, + crosapi::BrowserManagerObserver> + observation_{this}; + base::WeakPtrFactory<FullRestoreAppLaunchHandler> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ash/app_restore/full_restore_service.cc b/chrome/browser/ash/app_restore/full_restore_service.cc index 44a220b..e7b0bad0 100644 --- a/chrome/browser/ash/app_restore/full_restore_service.cc +++ b/chrome/browser/ash/app_restore/full_restore_service.cc
@@ -24,6 +24,7 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/account_id/account_id.h" +#include "components/app_restore/features.h" #include "components/app_restore/full_restore_info.h" #include "components/app_restore/full_restore_save_handler.h" #include "components/app_restore/full_restore_utils.h" @@ -49,6 +50,18 @@ const char kRestoreSettingHistogramName[] = "Apps.RestoreSetting"; const char kRestoreInitSettingHistogramName[] = "Apps.RestoreInitSetting"; +bool IsFullRestoreAvailableForLacros() { + if (!::full_restore::features::IsFullRestoreForLacrosEnabled()) + return false; + + const user_manager::User* user = + user_manager::UserManager::Get()->GetPrimaryUser(); + DCHECK(user); + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + DCHECK(profile); + return FullRestoreServiceFactory::IsFullRestoreAvailableForProfile(profile); +} + // static FullRestoreService* FullRestoreService::GetForProfile(Profile* profile) { return static_cast<FullRestoreService*>(
diff --git a/chrome/browser/ash/app_restore/full_restore_service.h b/chrome/browser/ash/app_restore/full_restore_service.h index 7e62e599..3030e15f 100644 --- a/chrome/browser/ash/app_restore/full_restore_service.h +++ b/chrome/browser/ash/app_restore/full_restore_service.h
@@ -54,6 +54,12 @@ kMaxValue = kCloseNotByUser, }; +// Returns true if full restore is responsible for restoring/launching Lacros +// during the system startup phase when below conditions are matched: +// 1. The FullRestoreForLacros flag is enabled. +// 2. FullRestoreService can be created for the primary profile. +bool IsFullRestoreAvailableForLacros(); + // The FullRestoreService class calls AppService and Window Management // interfaces to restore the app launchings and app windows. class FullRestoreService : public KeyedService,
diff --git a/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.cc b/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.cc index 53a11a9..9b62bf5 100644 --- a/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.cc +++ b/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.cc
@@ -29,4 +29,12 @@ base::UmaHistogramExactLinear("Arc.NearbyShare.FileStreamFailure", -result, -base::File::FILE_ERROR_MAX); } + +void UpdateNearbyShareFileStreamCompleteTime( + const base::TimeDelta& elapsed_time) { + base::UmaHistogramCustomTimes("Arc.NearbyShare.FileStreamComplete.TimeDelta", + elapsed_time, + /*min=*/base::Milliseconds(1), + /*max=*/base::Minutes(30), /*buckets=*/50); +} } // namespace arc
diff --git a/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.h b/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.h index c0e995b..c8f88be 100644 --- a/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.h +++ b/chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_ASH_ARC_NEARBY_SHARE_ARC_NEARBY_SHARE_UMA_H_ #include "base/files/file.h" +#include "base/time/time.h" namespace arc { @@ -41,7 +42,7 @@ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class IOErrorResult { - kFilereaderFailed = 0, + kFileReaderFailed = 0, kDataPipeFailedWait = 1, kDataPipeUnexpectedClose = 2, kDataPipeFailedWrite = 3, @@ -60,6 +61,9 @@ void UpdateNearbyShareWindowFound(bool found); void UpdateNearbyShareFileStreamError(base::File::Error result); + +void UpdateNearbyShareFileStreamCompleteTime( + const base::TimeDelta& elapsed_time); } // namespace arc #endif // CHROME_BROWSER_ASH_ARC_NEARBY_SHARE_ARC_NEARBY_SHARE_UMA_H_
diff --git a/chrome/browser/ash/arc/nearby_share/nearby_share_session_impl.cc b/chrome/browser/ash/arc/nearby_share/nearby_share_session_impl.cc index 642a6e1..b0899bc 100644 --- a/chrome/browser/ash/arc/nearby_share/nearby_share_session_impl.cc +++ b/chrome/browser/ash/arc/nearby_share/nearby_share_session_impl.cc
@@ -18,6 +18,7 @@ #include "base/system/sys_info.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" +#include "base/time/time.h" #include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/arc/nearby_share/arc_nearby_share_uma.h"
diff --git a/chrome/browser/ash/arc/nearby_share/share_info_file_handler.cc b/chrome/browser/ash/arc/nearby_share/share_info_file_handler.cc index e6b69f3..45ee735 100644 --- a/chrome/browser/ash/arc/nearby_share/share_info_file_handler.cc +++ b/chrome/browser/ash/arc/nearby_share/share_info_file_handler.cc
@@ -331,8 +331,10 @@ (*it_stream_adapter)->StartRunner(); file_config_.paths.push_back(dest_file_path); - // TODO(b/187358883): Add UMA metrics to measure time duration of file stream - // transfers. From local testing on caroline for 1.2GB takes around 1 minute. + // Used to measure time duration of file stream transfers. For reference, + // local testing on caroline for 1.2GB takes around 1 minute. + file_streaming_started_ = base::TimeTicks::Now(); + const int64_t timeout_seconds = GetTimeoutInSecondsFromBytes(GetTotalSizeOfFiles()); const std::string timeout_message = base::StringPrintf( @@ -391,6 +393,12 @@ NotifyFileSharingCompleted(base::File::FILE_ERROR_INVALID_OPERATION); return; } + + // Update file streaming duration UMA metric if transfer was successful. + const base::TimeDelta file_streaming_duration = + base::TimeTicks::Now() - file_streaming_started_; + UpdateNearbyShareFileStreamCompleteTime(file_streaming_duration); + DVLOG(1) << "OnFileStreamReadCompleted: Completed streaming all files"; NotifyFileSharingCompleted(base::File::FILE_OK); }
diff --git a/chrome/browser/ash/arc/nearby_share/share_info_file_handler.h b/chrome/browser/ash/arc/nearby_share/share_info_file_handler.h index d1314698..e28b5ff 100644 --- a/chrome/browser/ash/arc/nearby_share/share_info_file_handler.h +++ b/chrome/browser/ash/arc/nearby_share/share_info_file_handler.h
@@ -13,6 +13,7 @@ #include "ash/components/arc/mojom/nearby_share.mojom.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "chrome/browser/ash/arc/nearby_share/share_info_file_stream_adapter.h" #include "content/public/browser/browser_thread.h" @@ -181,6 +182,9 @@ // Timeout timer for asynchronous file streaming tasks. base::OneShotTimer file_streaming_timer_; + // Time when the file streaming is started. + base::TimeTicks file_streaming_started_; + // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<ShareInfoFileHandler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ash/arc/nearby_share/share_info_file_stream_adapter.cc b/chrome/browser/ash/arc/nearby_share/share_info_file_stream_adapter.cc index 1289983..18be7ef4 100644 --- a/chrome/browser/ash/arc/nearby_share/share_info_file_stream_adapter.cc +++ b/chrome/browser/ash/arc/nearby_share/share_info_file_stream_adapter.cc
@@ -103,7 +103,7 @@ url_, offset_, bytes_remaining_, base::Time()); if (!stream_reader_) { LOG(ERROR) << "Failed to create FileStreamReader."; - UpdateNearbyShareIOFail(IOErrorResult::kFilereaderFailed); + UpdateNearbyShareIOFail(IOErrorResult::kFileReaderFailed); OnStreamingFinished(false); return; }
diff --git a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc index 65f07bb..7ea7c35e0 100644 --- a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc +++ b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc
@@ -180,7 +180,7 @@ // print preview will find the embedded plugin element instead of trying to // print the top-level frame. bool IsPdfPluginLoaded(content::WebContents* web_contents) { - if (!web_contents->IsDocumentOnLoadCompletedInMainFrame()) { + if (!web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()) { VLOG(1) << "Top-level WebContents not ready yet."; return false; } @@ -198,7 +198,7 @@ return false; } - if (!contents_to_use->IsDocumentOnLoadCompletedInMainFrame()) { + if (!contents_to_use->IsDocumentOnLoadCompletedInPrimaryMainFrame()) { VLOG(1) << "Plugin frame still loading."; return false; }
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index ad3e041..3eb14f3a 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -87,6 +87,7 @@ #include "chrome/browser/ash/dbus/smb_fs_service_provider.h" #include "chrome/browser/ash/dbus/virtual_file_request_service_provider.h" #include "chrome/browser/ash/dbus/vm/vm_disk_management_service_provider.h" +#include "chrome/browser/ash/dbus/vm/vm_launch_service_provider.h" #include "chrome/browser/ash/dbus/vm/vm_permission_service_provider.h" #include "chrome/browser/ash/dbus/vm/vm_sk_forwarding_service_provider.h" #include "chrome/browser/ash/dbus/vm_applications_service_provider.h" @@ -172,10 +173,11 @@ #include "chrome/browser/task_manager/task_manager_interface.h" #include "chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.h" #include "chrome/browser/ui/ash/assistant/assistant_state_client.h" +#include "chrome/browser/ui/ash/fwupd_download_client_impl.h" #include "chrome/browser/ui/ash/image_downloader_impl.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" #include "chrome/browser/ui/ash/session_controller_client_impl.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" #include "chrome/browser/ui/webui/chromeos/emoji/emoji_ui.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_constants.h" @@ -240,6 +242,7 @@ #include "rlz/buildflags/buildflags.h" #include "services/audio/public/cpp/sounds/sounds_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" +#include "third_party/cros_system_api/dbus/vm_launch/dbus-constants.h" #include "ui/base/emoji/emoji_panel_helper.h" #include "ui/base/ime/ash/ime_keyboard.h" #include "ui/base/ime/ash/input_method_manager.h" @@ -379,6 +382,12 @@ CrosDBusService::CreateServiceProviderList( std::make_unique<VmDiskManagementServiceProvider>())); + vm_launch_service_ = CrosDBusService::Create( + system_bus, vm_tools::launch::kVmLaunchServiceName, + dbus::ObjectPath(vm_tools::launch::kVmLaunchServicePath), + CrosDBusService::CreateServiceProviderList( + std::make_unique<VmLaunchServiceProvider>())); + vm_sk_forwarding_service_ = CrosDBusService::Create( system_bus, vm_tools::sk_forwarding::kVmSKForwardingServiceName, dbus::ObjectPath(vm_tools::sk_forwarding::kVmSKForwardingServicePath), @@ -495,6 +504,7 @@ chrome_features_service_.reset(); vm_applications_service_.reset(); vm_disk_management_service_.reset(); + vm_launch_service_.reset(); vm_sk_forwarding_service_.reset(); vm_permission_service_.reset(); drive_file_stream_service_.reset(); @@ -525,6 +535,7 @@ std::unique_ptr<CrosDBusService> chrome_features_service_; std::unique_ptr<CrosDBusService> vm_applications_service_; std::unique_ptr<CrosDBusService> vm_disk_management_service_; + std::unique_ptr<CrosDBusService> vm_launch_service_; std::unique_ptr<CrosDBusService> vm_sk_forwarding_service_; std::unique_ptr<CrosDBusService> vm_permission_service_; std::unique_ptr<CrosDBusService> drive_file_stream_service_; @@ -1247,6 +1258,7 @@ if (features::IsFirmwareUpdaterAppEnabled()) { firmware_update_manager_ = std::make_unique<FirmwareUpdateManager>(); + fwupd_download_client_ = std::make_unique<FwupdDownloadClientImpl>(); } if (features::IsPciguardUiEnabled()) {
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.h b/chrome/browser/ash/chrome_browser_main_parts_ash.h index 7c0d28f..9b40163 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.h +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.h
@@ -31,6 +31,7 @@ class AssistantStateClient; class ChromeKeyboardControllerClient; class ImageDownloaderImpl; +class QuickAnswersController; namespace arc { namespace data_snapshotd { @@ -73,6 +74,7 @@ class DemoModeResourcesRemover; class EventRewriterDelegateImpl; class FirmwareUpdateManager; +class FwupdDownloadClientImpl; class GnubbyNotification; class IdleActionWarningObserver; class LoginScreenExtensionsLifetimeManager; @@ -80,7 +82,6 @@ class LowDiskNotification; class PowerMetricsReporter; class PSIMemoryMetrics; -class QuickAnswersController; class RendererFreezer; class SessionTerminationManager; class ShortcutMappingPrefService; @@ -163,7 +164,7 @@ std::unique_ptr<NetworkThrottlingObserver> network_throttling_observer_; std::unique_ptr<NetworkChangeManagerClient> network_change_manager_client_; std::unique_ptr<DebugdNotificationHandler> debugd_notification_handler_; - std::unique_ptr<ash::QuickAnswersController> quick_answers_controller_; + std::unique_ptr<QuickAnswersController> quick_answers_controller_; std::unique_ptr<internal::DBusServices> dbus_services_; @@ -229,6 +230,8 @@ std::unique_ptr<BulkPrintersCalculatorFactory> bulk_printers_calculator_factory_; + std::unique_ptr<FwupdDownloadClientImpl> fwupd_download_client_; + std::unique_ptr<SessionTerminationManager> session_termination_manager_; // Set when PreProfileInit() is called. If PreMainMessageLoopRun() exits
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index 555fae2..d38dffd 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -40,6 +40,7 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/threading/thread_restrictions.h" +#include "chrome/browser/ash/app_restore/full_restore_service.h" #include "chrome/browser/ash/crosapi/browser_data_migrator.h" #include "chrome/browser/ash/crosapi/browser_loader.h" #include "chrome/browser/ash/crosapi/browser_service_host_ash.h" @@ -96,6 +97,45 @@ kMaxValue = kLacrosOnly }; +// The actual Lacros launch mode. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class LacrosLaunchModeAndSource { + // Either set by user or system/flags, indicates that Lacros is disabled. + kPossiblySetByUserLacrosDisabled = 0, + // Either set by user or system/flags, indicates that Lacros and Ash are both + // enabled and accessible by the user. + kPossiblySetByUserSideBySide = 1, + // Either set by user or system/flags, indicates that Lacros is the primary + // (but not only) browser. + kPossiblySetByUserLacrosPrimary = 2, + // Either set by user or system/flags, Lacros is the only browser and Ash is + // disabled. + kPossiblySetByUserLacrosOnly = 3, + // Enforced by the user, indicates that Lacros is disabled. + kForcedByUserLacrosDisabled = 4 + kPossiblySetByUserLacrosDisabled, + // Enforced by the user, indicates that Lacros and Ash are both enabled and + // accessible by the user. + kForcedByUserSideBySide = 4 + kPossiblySetByUserSideBySide, + // Enforced by the user, indicates that Lacros is the primary (but not only) + // browser. + kForcedByUserLacrosPrimary = 4 + kPossiblySetByUserLacrosPrimary, + // Enforced by the user, Lacros is the only browser and Ash is disabled. + kForcedByUserLacrosOnly = 4 + kPossiblySetByUserLacrosOnly, + // Enforced by policy, indicates that Lacros is disabled. + kForcedByPolicyLacrosDisabled = 8 + kPossiblySetByUserLacrosDisabled, + // Enforced by policy, indicates that Lacros and Ash are both enabled and + // accessible by the user. + kForcedByPolicySideBySide = 8 + kPossiblySetByUserSideBySide, + // Enforced by policy, indicates that Lacros is the primary (but not only) + // browser. + kForcedByPolicyLacrosPrimary = 8 + kPossiblySetByUserLacrosPrimary, + // Enforced by policy, Lacros is the only browser and Ash is disabled. + kForcedByPolicyLacrosOnly = 8 + kPossiblySetByUserLacrosOnly, + + kMaxValue = kForcedByPolicyLacrosOnly +}; + using LaunchParamsFromBackground = BrowserManager::LaunchParamsFromBackground; // Pointer to the global instance of BrowserManager. @@ -230,11 +270,14 @@ browser_util::kLaunchOnLoginPref); } -// Returns the initial browser action. No browser will be opened when -// lacros-chrome is initialized in the web Kiosk session. +// Returns the initial browser action. No browser will be opened in the +// following circumstances: +// 1. Lacros-chrome is initialized in the web Kiosk session +// 2. Full restore is responsible for restoring/launching Lacros. browser_util::InitialBrowserAction GetInitialBrowserAction() { return browser_util::InitialBrowserAction( - user_manager::UserManager::Get()->IsLoggedInAsWebKioskApp() + user_manager::UserManager::Get()->IsLoggedInAsWebKioskApp() || + ash::full_restore::IsFullRestoreAvailableForLacros() ? mojom::InitialBrowserAction::kDoNotOpenWindow : mojom::InitialBrowserAction::kUseStartupPreference); } @@ -497,14 +540,14 @@ void BrowserManager::InitializeAndStart() { DCHECK_EQ(state_, State::NOT_INITIALIZED); - // Perform the UMA recording for the current Lacros mode of operation. - RecordLacrosLaunchMode(); - // Ensure this isn't run multiple times. session_manager::SessionManager::Get()->RemoveObserver(this); PrepareLacrosPolicies(); + // Perform the UMA recording for the current Lacros mode of operation. + RecordLacrosLaunchMode(); + const bool is_lacros_enabled = browser_util::IsLacrosEnabled(); // As a switch between Ash and Lacros mode requires an Ash restart plus @@ -822,7 +865,6 @@ "--ozone-platform=wayland", "--user-data-dir=" + user_data_dir, "--enable-gpu-rasterization", - "--enable-oop-rasterization", "--lang=" + locale, "--enable-crashpad", "--enable-webgl-image-chromium", @@ -923,6 +965,8 @@ return; } + is_terminated_ = false; + DCHECK(!browser_service_.has_value()); browser_service_ = BrowserServiceInfo{mojo_id, browser_service, browser_service_version}; @@ -985,6 +1029,8 @@ // abnormally (e.g. crashes). For now, assume the user meant to close it. SetLaunchOnLoginPref(false); + is_terminated_ = true; + if (!shutdown_requested_ && relaunch_requested_) { MaybeStart(browser_util::InitialBrowserAction( mojom::InitialBrowserAction::kRestoreLastSession)); @@ -1167,21 +1213,60 @@ void BrowserManager::RecordLacrosLaunchMode() { LacrosLaunchMode lacros_mode; + LacrosLaunchModeAndSource lacros_mode_and_source; + if (!browser_util::IsAshWebBrowserEnabled(chrome::GetChannel())) { // As Ash is disabled, Lacros is the only available browser. lacros_mode = LacrosLaunchMode::kLacrosOnly; + lacros_mode_and_source = + LacrosLaunchModeAndSource::kPossiblySetByUserLacrosOnly; } else if (browser_util::IsLacrosPrimaryBrowser()) { // Lacros is the primary browser - but Ash is still available. lacros_mode = LacrosLaunchMode::kLacrosPrimary; + lacros_mode_and_source = + LacrosLaunchModeAndSource::kPossiblySetByUserLacrosPrimary; } else if (browser_util::IsLacrosEnabled()) { // If Lacros is enabled but not primary or the only browser, the // side by side mode is active. lacros_mode = LacrosLaunchMode::kSideBySide; + lacros_mode_and_source = + LacrosLaunchModeAndSource::kPossiblySetByUserSideBySide; + } else { lacros_mode = LacrosLaunchMode::kLacrosDisabled; + lacros_mode_and_source = + LacrosLaunchModeAndSource::kPossiblySetByUserLacrosDisabled; } UMA_HISTOGRAM_ENUMERATION("Ash.Lacros.Launch.Mode", lacros_mode); + + crosapi::browser_util::LacrosLaunchSwitchSource source = + crosapi::browser_util::GetLacrosLaunchSwitchSource(); + + // Unit tests can come here before the source is known. + if (source == crosapi::browser_util::LacrosLaunchSwitchSource::kUnknown) + return; + + LacrosLaunchModeAndSource source_offset; + if (source == + crosapi::browser_util::LacrosLaunchSwitchSource::kPossiblySetByUser) { + source_offset = LacrosLaunchModeAndSource::kPossiblySetByUserLacrosDisabled; + } else if (source == + crosapi::browser_util::LacrosLaunchSwitchSource::kForcedByUser) { + source_offset = LacrosLaunchModeAndSource::kForcedByUserLacrosDisabled; + } else { + source_offset = LacrosLaunchModeAndSource::kForcedByPolicyLacrosDisabled; + } + + // The states are comprised of the basic four Lacros options and the + // source of the mode selection (By user, by Policy, by System). These + // combinations are "nibbled together" here in one status value. + lacros_mode_and_source = static_cast<LacrosLaunchModeAndSource>( + static_cast<int>(source_offset) + + static_cast<int>(lacros_mode_and_source)); + + UMA_HISTOGRAM_ENUMERATION("Ash.Lacros.Launch.ModeAndSource", + lacros_mode_and_source); } } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h index 3ece2f5..0a138ed 100644 --- a/chrome/browser/ash/crosapi/browser_manager.h +++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -84,6 +84,9 @@ // Virtual for testing. virtual bool IsRunningOrWillRun() const; + // Returns true if Lacros is terminated. + bool IsTerminated() const { return is_terminated_; } + // Opens the browser window in lacros-chrome. // If lacros-chrome is not yet launched, it triggers to launch. If this is // called again during the setup phase of the launch process, it will be @@ -443,6 +446,9 @@ // if an update should be loaded prior to starting the browser. bool update_available_ = false; + // Tracks whether lacros-chrome is terminated. + bool is_terminated_ = false; + // Helps set up and manage the mojo connections between lacros-chrome and // ash-chrome in testing environment. Only applicable when // '--lacros-mojo-socket-for-testing' is present in the command line.
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 4b175d0..375edb8 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -49,6 +49,9 @@ absl::optional<bool> g_lacros_primary_browser_for_test; +LacrosLaunchSwitchSource g_lacros_launch_switch_source = + LacrosLaunchSwitchSource::kUnknown; + // At session start the value for LacrosLaunchSwitch logic is applied and the // result is stored in this value which is used after that as a cache. absl::optional<LacrosLaunchSwitch> g_lacros_launch_switch_cache; @@ -629,10 +632,12 @@ LOG(ERROR) << "Trying to cache LacrosLaunchSwitch and the value was set"; return; } + g_lacros_launch_switch_source = LacrosLaunchSwitchSource::kPossiblySetByUser; // Users can set this switch in chrome://flags to disable the effect of the // lacros-availability policy. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(ash::switches::kLacrosAvailabilityIgnore)) { + g_lacros_launch_switch_source = LacrosLaunchSwitchSource::kForcedByUser; g_lacros_launch_switch_cache = LacrosLaunchSwitch::kUserChoice; return; } @@ -659,6 +664,9 @@ return; } + if (result != LacrosLaunchSwitch::kUserChoice) + g_lacros_launch_switch_source = LacrosLaunchSwitchSource::kForcedByPolicy; + g_lacros_launch_switch_cache = result; } @@ -744,5 +752,9 @@ g_profile_migration_completed_for_test = is_completed; } +LacrosLaunchSwitchSource GetLacrosLaunchSwitchSource() { + return g_lacros_launch_switch_source; +} + } // namespace browser_util } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index 60971ee..fa07ba41 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -40,6 +40,22 @@ namespace crosapi { namespace browser_util { +// Indicates how the decision for the usage of Lacros has been made. +enum class LacrosLaunchSwitchSource { + // It is unknown yet if and how Lacros will be used. + kUnknown = 0, + // Either there were no policies, or the system had a special condition in + // which the policy got ignored and the user could have set the mode. + kPossiblySetByUser = 1, + // The Lacros usage was enforced by the user via #lacros-availability-ignore + // flag override. + kForcedByUser = 2, + // The Lacros usage was enforced using the policy. Note that in this case + // the policy might still not be used, but it is programmatically overridden + // and not by the user (e.g. special Googler user case). + kForcedByPolicy = 3 +}; + // Represents different options for how to launch Lacros browser. The values // shall be consistent with the controlling policy. enum class LacrosLaunchSwitch { @@ -262,6 +278,10 @@ // g_browser_process->local_state() etc. void SetProfileMigrationCompletedForTest(bool is_completed); +// Returns who decided how Lacros should be used - or not: The User, the policy +// or another edge case. +LacrosLaunchSwitchSource GetLacrosLaunchSwitchSource(); + } // namespace browser_util } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/chrome_app_window_tracker_ash.cc b/chrome/browser/ash/crosapi/chrome_app_window_tracker_ash.cc index 2dce58a..69bdc77 100644 --- a/chrome/browser/ash/crosapi/chrome_app_window_tracker_ash.cc +++ b/chrome/browser/ash/crosapi/chrome_app_window_tracker_ash.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/shelf_model.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h" +#include "components/app_restore/full_restore_utils.h" #include "components/exo/shell_surface_util.h" namespace crosapi { @@ -29,12 +30,14 @@ const std::string& window_id) { pending_window_ids_[window_id].app_id = app_id; CheckWindowNoLongerPending(window_id); + full_restore::OnLacrosChromeAppWindowAdded(app_id, window_id); } void ChromeAppWindowTrackerAsh::OnAppWindowRemoved( const std::string& app_id, const std::string& window_id) { pending_window_ids_.erase(window_id); + full_restore::OnLacrosChromeAppWindowRemoved(app_id, window_id); } void ChromeAppWindowTrackerAsh::OnWindowInitialized(aura::Window* window) {
diff --git a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc index bc3c5b6..e98b4b5 100644 --- a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc +++ b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc
@@ -115,8 +115,7 @@ /*id=*/"VKUnsupportedInCrostini", /*text=*/ l10n_util::GetStringUTF16(IDS_CROSTINI_UNSUPPORTED_VIRTUAL_KEYBOARD), - /*timeout_ms=*/delegate_->ToastTimeoutMs(), - /*dismiss_text=*/absl::nullopt}; + /*timeout_ms=*/delegate_->ToastTimeoutMs()}; delegate_->ShowToast(data); virtual_keyboard_unsupported_message_shown_ = true; EmitMetricReasonShown(reason); @@ -138,8 +137,7 @@ /*id=*/"IMEUnsupportedInCrostini", /*text=*/ l10n_util::GetStringFUTF16(IDS_CROSTINI_UNSUPPORTED_IME, ime_name), - /*timeout_ms=*/delegate_->ToastTimeoutMs(), - /*dismiss_text=*/absl::nullopt}; + /*timeout_ms=*/delegate_->ToastTimeoutMs()}; delegate_->ShowToast(data); ime_unsupported_message_shown_ = true; EmitMetricReasonShown(NotificationReason::kUnsupportedIME); @@ -194,7 +192,7 @@ (manager->IsMagnifierEnabled() || manager->IsDockedMagnifierEnabled())) { return 60 * 1000; } else { - return 5 * 1000; + return ash::ToastData::kDefaultToastDurationMs; } }
diff --git a/chrome/browser/ash/dbus/vm/org.chromium.VmLaunchService.conf b/chrome/browser/ash/dbus/vm/org.chromium.VmLaunchService.conf new file mode 100644 index 0000000..65dbaa0 --- /dev/null +++ b/chrome/browser/ash/dbus/vm/org.chromium.VmLaunchService.conf
@@ -0,0 +1,22 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<!-- + 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. +--> + +<busconfig> + <policy user="chronos"> + <allow own="org.chromium.VmLaunchService"/> + </policy> + + <policy user="crosvm"> + <allow send_destination="org.chromium.VmLaunchService" + send_interface="org.chromium.VmLaunchService" + send_member="StartWaylandServer"/> + <allow send_destination="org.chromium.VmLaunchService" + send_interface="org.chromium.VmLaunchService" + send_member="StopWaylandServer"/> + </policy> +</busconfig>
diff --git a/chrome/browser/ash/dbus/vm/vm_launch_service_provider.cc b/chrome/browser/ash/dbus/vm/vm_launch_service_provider.cc new file mode 100644 index 0000000..443d034 --- /dev/null +++ b/chrome/browser/ash/dbus/vm/vm_launch_service_provider.cc
@@ -0,0 +1,133 @@ +// 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/ash/dbus/vm/vm_launch_service_provider.h" + +#include <dbus/dbus-protocol.h> +#include <memory> + +#include "base/bind.h" +#include "base/logging.h" +#include "chrome/browser/ash/borealis/borealis_service.h" +#include "chrome/browser/ash/borealis/borealis_wayland_interface.h" +#include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chromeos/dbus/vm_launch/launch.pb.h" +#include "dbus/message.h" +#include "third_party/cros_system_api/dbus/vm_launch/dbus-constants.h" + +namespace ash { + +namespace { +void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(ERROR, !success) << "Failed to export " << interface_name << "." + << method_name; +} +} // namespace + +VmLaunchServiceProvider::VmLaunchServiceProvider() = default; + +VmLaunchServiceProvider::~VmLaunchServiceProvider() = default; + +void VmLaunchServiceProvider::Start( + scoped_refptr<dbus::ExportedObject> exported_object) { + exported_object->ExportMethod( + vm_tools::launch::kVmLaunchServiceInterface, + vm_tools::launch::kVmLaunchServiceStartWaylandServerMethod, + base::BindRepeating(&VmLaunchServiceProvider::StartWaylandServer, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&OnExported)); + + exported_object->ExportMethod( + vm_tools::launch::kVmLaunchServiceInterface, + vm_tools::launch::kVmLaunchServiceStopWaylandServerMethod, + base::BindRepeating(&VmLaunchServiceProvider::StopWaylandServer, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&OnExported)); +} + +void VmLaunchServiceProvider::StartWaylandServer( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + vm_tools::launch::StartWaylandServerRequest request; + if (!dbus::MessageReader(method_call).PopArrayOfBytesAsProto(&request)) { + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_INVALID_ARGS, + "Unable to parse StartWaylandServerRequest from message")); + return; + } + + Profile* profile = ProfileManager::GetPrimaryUserProfile(); + if (!profile || + ProfileHelper::GetUserIdHashFromProfile(profile) != request.owner_id()) { + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_INVALID_ARGS, "Invalid owner_id")); + return; + } + + switch (request.vm_type()) { + case vm_tools::launch::VmType::BOREALIS: + borealis::BorealisService::GetForProfile(profile) + ->WaylandInterface() + .GetWaylandServer( + base::BindOnce(&VmLaunchServiceProvider::OnWaylandServerStarted, + weak_ptr_factory_.GetWeakPtr(), method_call, + std::move(response_sender))); + break; + default: + LOG(WARNING) << "StartWaylandServer is not implemented for VM type=" + << request.vm_type() << " owner=" << request.owner_id(); + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_NOT_SUPPORTED, "Not implemented")); + break; + } +} + +void VmLaunchServiceProvider::OnWaylandServerStarted( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + borealis::BorealisCapabilities* capabilities, + const base::FilePath& path) { + if (!capabilities || path.empty()) { + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_FAILED, "Wayland server creation failed")); + return; + } + std::unique_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + vm_tools::launch::StartWaylandServerResponse response_pb; + response_pb.mutable_server()->set_path(path.AsUTF8Unsafe()); + dbus::MessageWriter writer(response.get()); + writer.AppendProtoAsArrayOfBytes(response_pb); + std::move(response_sender).Run(std::move(response)); +} + +void VmLaunchServiceProvider::StopWaylandServer( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + vm_tools::launch::StopWaylandServerRequest request; + if (!dbus::MessageReader(method_call).PopArrayOfBytesAsProto(&request)) { + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_INVALID_ARGS, + "Unable to parse StopWaylandServerRequest from message")); + return; + } + // TODO(b/200896773): Stop is not used currently as the current set of wayland + // servers all ignore shutdown requests while their lifetimes are tied to + // chrome itself. Going forward this method will be necessary for servers + // whose lifetime is not bound to chrome's. + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_NOT_SUPPORTED, "Not implemented.")); +} + +} // namespace ash
diff --git a/chrome/browser/ash/dbus/vm/vm_launch_service_provider.h b/chrome/browser/ash/dbus/vm/vm_launch_service_provider.h new file mode 100644 index 0000000..eab18fac --- /dev/null +++ b/chrome/browser/ash/dbus/vm/vm_launch_service_provider.h
@@ -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. + +#ifndef CHROME_BROWSER_ASH_DBUS_VM_VM_LAUNCH_SERVICE_PROVIDER_H_ +#define CHROME_BROWSER_ASH_DBUS_VM_VM_LAUNCH_SERVICE_PROVIDER_H_ + +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/dbus/services/cros_dbus_service.h" +#include "dbus/exported_object.h" + +namespace borealis { +class BorealisCapabilities; +} + +namespace ash { + +class VmLaunchServiceProvider + : public CrosDBusService::ServiceProviderInterface { + public: + VmLaunchServiceProvider(); + ~VmLaunchServiceProvider() override; + + // Delete copy constructor/assign. + VmLaunchServiceProvider(const VmLaunchServiceProvider&) = delete; + VmLaunchServiceProvider& operator=(const VmLaunchServiceProvider&) = delete; + + // CrosDBusService::ServiceProviderInterface overrides: + void Start(scoped_refptr<dbus::ExportedObject> exported_object) override; + + private: + void StartWaylandServer(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender); + + void OnWaylandServerStarted( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + borealis::BorealisCapabilities* capabilities, + const base::FilePath& path); + + void StopWaylandServer(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender); + + base::WeakPtrFactory<VmLaunchServiceProvider> weak_ptr_factory_{this}; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_ASH_DBUS_VM_VM_LAUNCH_SERVICE_PROVIDER_H_
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc index 5259ac4..19bfc08 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -446,7 +446,7 @@ TestCase("renameFileDrive"), TestCase("renameNewFolderDownloads").InGuestMode(), TestCase("renameNewFolderDownloads"), - TestCase("renameNewFolderDrive"))); + TestCase("renameRemovableWithKeyboardOnFileList"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( ContextMenu, /* context_menu.js for file list */
diff --git a/chrome/browser/ash/file_system_provider/registry.cc b/chrome/browser/ash/file_system_provider/registry.cc index 38e5cd9d..d6f8f945 100644 --- a/chrome/browser/ash/file_system_provider/registry.cc +++ b/chrome/browser/ash/file_system_provider/registry.cc
@@ -129,29 +129,24 @@ PrefService* const pref_service = profile_->GetPrefs(); DCHECK(pref_service); - const base::DictionaryValue* const file_systems = - &base::Value::AsDictionaryValue( - *pref_service->GetDictionary(prefs::kFileSystemProviderMounted)); + const base::Value* const file_systems = + pref_service->GetDictionary(prefs::kFileSystemProviderMounted); DCHECK(file_systems); - const base::DictionaryValue* file_systems_per_extension = NULL; - if (!file_systems->GetDictionaryWithoutPathExpansion( - provider_id.ToString(), &file_systems_per_extension)) { + const base::Value* file_systems_per_extension = + file_systems->FindDictKey(provider_id.ToString()); + if (!file_systems_per_extension) { return base::WrapUnique(new RestoredFileSystems); // Nothing to restore. } std::unique_ptr<RestoredFileSystems> restored_file_systems( new RestoredFileSystems); - for (base::DictionaryValue::Iterator it(*file_systems_per_extension); - !it.IsAtEnd(); - it.Advance()) { - const base::DictionaryValue* file_system = NULL; - const base::Value* file_system_value = - file_systems_per_extension->FindKey(it.key()); - DCHECK(file_system_value); + for (const auto it : file_systems_per_extension->DictItems()) { + const base::Value* file_system = + file_systems_per_extension->FindDictKey(it.first); - if (!file_system_value->GetAsDictionary(&file_system)) { + if (!file_system) { LOG(ERROR) << "Malformed provided file system information in preferences."; continue; @@ -191,16 +186,11 @@ restored_file_system.options = options; // Restore watchers. It's optional, since this field is new. - const base::DictionaryValue* watchers = NULL; - if (file_system->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers, - &watchers)) { - for (base::DictionaryValue::Iterator it(*watchers); !it.IsAtEnd(); - it.Advance()) { - const base::DictionaryValue* watcher = NULL; - const base::Value* watcher_value = watchers->FindKey(it.key()); - DCHECK(watcher_value); - - if (!watcher_value->GetAsDictionary(&watcher)) { + const base::Value* watchers = file_system->FindDictKey(kPrefKeyWatchers); + if (watchers) { + for (const auto it : watchers->DictItems()) { + const base::Value* watcher = watchers->FindDictKey(it.first); + if (!watcher) { LOG(ERROR) << "Malformed watcher information in preferences."; continue; } @@ -211,12 +201,11 @@ watcher->FindBoolKey(kPrefKeyWatcherRecursive); const std::string* last_tag = watcher->FindStringKey(kPrefKeyWatcherLastTag); - const base::ListValue* persistent_origins = NULL; + const base::Value* persistent_origins = + watcher->FindListKey(kPrefKeyWatcherPersistentOrigins); - if (!entry_path || !recursive || !last_tag || - !watcher->GetListWithoutPathExpansion( - kPrefKeyWatcherPersistentOrigins, &persistent_origins) || - it.key() != *entry_path || entry_path->empty() || + if (!entry_path || !recursive || !last_tag || !persistent_origins || + it.first != *entry_path || entry_path->empty() || (!options.supports_notify_tag && (!last_tag->empty() || persistent_origins->GetList().size()))) { LOG(ERROR) << "Malformed watcher information in preferences.";
diff --git a/chrome/browser/ash/file_system_provider/registry_unittest.cc b/chrome/browser/ash/file_system_provider/registry_unittest.cc index 0269d1cf..359bf61 100644 --- a/chrome/browser/ash/file_system_provider/registry_unittest.cc +++ b/chrome/browser/ash/file_system_provider/registry_unittest.cc
@@ -37,7 +37,7 @@ // The dot in the file system ID is there in order to check that saving to // preferences works correctly. File System ID is used as a key in -// a base::DictionaryValue, so it has to be stored without path expansion. +// a base::Value, so it has to be stored without path expansion. const char kFileSystemId[] = "camera/pictures/id .!@#$%^&*()_+"; const int kOpenedFilesLimit = 5; @@ -58,43 +58,37 @@ profile->GetTestingPrefService(); ASSERT_TRUE(pref_service); - base::DictionaryValue extensions; - auto file_system = std::make_unique<base::DictionaryValue>(); - file_system->SetKey(kPrefKeyFileSystemId, base::Value(kFileSystemId)); - file_system->SetKey(kPrefKeyDisplayName, base::Value(kDisplayName)); - file_system->SetKey(kPrefKeyWritable, base::Value(writable)); - file_system->SetKey(kPrefKeySupportsNotifyTag, - base::Value(supports_notify_tag)); - file_system->SetKey(kPrefKeyOpenedFilesLimit, - base::Value(opened_files_limit)); + base::Value extensions{base::Value::Type::DICTIONARY}; + base::Value file_system{base::Value::Type::DICTIONARY}; + file_system.SetKey(kPrefKeyFileSystemId, base::Value(kFileSystemId)); + file_system.SetKey(kPrefKeyDisplayName, base::Value(kDisplayName)); + file_system.SetKey(kPrefKeyWritable, base::Value(writable)); + file_system.SetKey(kPrefKeySupportsNotifyTag, + base::Value(supports_notify_tag)); + file_system.SetKey(kPrefKeyOpenedFilesLimit, base::Value(opened_files_limit)); // Remember watchers. - auto watcher_value = std::make_unique<base::DictionaryValue>(); - watcher_value->SetKey(kPrefKeyWatcherEntryPath, - base::Value(watcher.entry_path.value())); - watcher_value->SetKey(kPrefKeyWatcherRecursive, - base::Value(watcher.recursive)); - watcher_value->SetKey(kPrefKeyWatcherLastTag, base::Value(watcher.last_tag)); - auto persistent_origins_value = std::make_unique<base::ListValue>(); + base::Value watcher_value{base::Value::Type::DICTIONARY}; + watcher_value.SetKey(kPrefKeyWatcherEntryPath, + base::Value(watcher.entry_path.value())); + watcher_value.SetKey(kPrefKeyWatcherRecursive, + base::Value(watcher.recursive)); + watcher_value.SetKey(kPrefKeyWatcherLastTag, base::Value(watcher.last_tag)); + base::Value persistent_origins_value{base::Value::Type::LIST}; for (const auto& subscriber_it : watcher.subscribers) { if (subscriber_it.second.persistent) - persistent_origins_value->Append(subscriber_it.first.spec()); + persistent_origins_value.Append(subscriber_it.first.spec()); } - watcher_value->SetKey( - kPrefKeyWatcherPersistentOrigins, - base::Value::FromUniquePtrValue(std::move(persistent_origins_value))); - auto watchers = std::make_unique<base::DictionaryValue>(); - watchers->SetKey(watcher.entry_path.value(), - base::Value::FromUniquePtrValue(std::move(watcher_value))); - file_system->SetKey(kPrefKeyWatchers, - base::Value::FromUniquePtrValue(std::move(watchers))); - auto file_systems = std::make_unique<base::DictionaryValue>(); - file_systems->SetKey(kFileSystemId, - base::Value::FromUniquePtrValue(std::move(file_system))); - extensions.SetKey(kProviderId.ToString(), - base::Value::FromUniquePtrValue(std::move(file_systems))); - pref_service->Set(prefs::kFileSystemProviderMounted, extensions); + watcher_value.SetKey(kPrefKeyWatcherPersistentOrigins, + std::move(persistent_origins_value)); + base::Value watchers{base::Value::Type::DICTIONARY}; + watchers.SetKey(watcher.entry_path.value(), std::move(watcher_value)); + file_system.SetKey(kPrefKeyWatchers, std::move(watchers)); + base::Value file_systems{base::Value::Type::DICTIONARY}; + file_systems.SetKey(kFileSystemId, std::move(file_system)); + extensions.SetKey(kProviderId.ToString(), std::move(file_systems)); + pref_service->Set(prefs::kFileSystemProviderMounted, std::move(extensions)); } } // namespace @@ -179,20 +173,17 @@ profile_->GetTestingPrefService(); ASSERT_TRUE(pref_service); - const base::DictionaryValue* const extensions = - &base::Value::AsDictionaryValue( - *pref_service->GetDictionary(prefs::kFileSystemProviderMounted)); + const base::Value* const extensions = + pref_service->GetDictionary(prefs::kFileSystemProviderMounted); ASSERT_TRUE(extensions); - const base::DictionaryValue* file_systems = NULL; - ASSERT_TRUE(extensions->GetDictionaryWithoutPathExpansion( - kProviderId.ToString(), &file_systems)); + const base::Value* file_systems = + extensions->FindDictKey(kProviderId.ToString()); + ASSERT_TRUE(file_systems); EXPECT_EQ(1u, file_systems->DictSize()); - const base::Value* file_system_value = file_systems->FindKey(kFileSystemId); - ASSERT_TRUE(file_system_value); - const base::DictionaryValue* file_system = NULL; - ASSERT_TRUE(file_system_value->GetAsDictionary(&file_system)); + const base::Value* file_system = file_systems->FindKey(kFileSystemId); + ASSERT_TRUE(file_system); const std::string* file_system_id = file_system->FindStringKey(kPrefKeyFileSystemId); @@ -218,13 +209,13 @@ EXPECT_TRUE(opened_files_limit.has_value()); EXPECT_EQ(kOpenedFilesLimit, opened_files_limit.value()); - const base::DictionaryValue* watchers_value = NULL; - ASSERT_TRUE(file_system->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers, - &watchers_value)); + const base::Value* watchers_value = + file_system->FindDictKey(kPrefKeyWatchers); + ASSERT_TRUE(watchers_value); - const base::DictionaryValue* watcher = NULL; - ASSERT_TRUE(watchers_value->GetDictionaryWithoutPathExpansion( - fake_watcher_.entry_path.value(), &watcher)); + const base::Value* watcher = + watchers_value->FindDictKey(fake_watcher_.entry_path.value()); + ASSERT_TRUE(watcher); const std::string* entry_path = watcher->FindStringKey(kPrefKeyWatcherEntryPath); @@ -240,9 +231,9 @@ EXPECT_TRUE(last_tag); EXPECT_EQ(fake_watcher_.last_tag, *last_tag); - const base::ListValue* persistent_origins = NULL; - ASSERT_TRUE(watcher->GetListWithoutPathExpansion( - kPrefKeyWatcherPersistentOrigins, &persistent_origins)); + const base::Value* persistent_origins = + watcher->FindListKey(kPrefKeyWatcherPersistentOrigins); + ASSERT_TRUE(persistent_origins); ASSERT_GT(fake_watcher_.subscribers.size(), persistent_origins->GetList().size()); ASSERT_EQ(1u, persistent_origins->GetList().size()); @@ -267,14 +258,13 @@ profile_->GetTestingPrefService(); ASSERT_TRUE(pref_service); - const base::DictionaryValue* const extensions = - &base::Value::AsDictionaryValue( - *pref_service->GetDictionary(prefs::kFileSystemProviderMounted)); + const base::Value* const extensions = + pref_service->GetDictionary(prefs::kFileSystemProviderMounted); ASSERT_TRUE(extensions); - const base::DictionaryValue* file_systems = NULL; - EXPECT_FALSE(extensions->GetDictionaryWithoutPathExpansion( - kProviderId.GetExtensionId(), &file_systems)); + const base::Value* file_systems = + extensions->FindDictKey(kProviderId.GetExtensionId()); + EXPECT_FALSE(file_systems); } TEST_F(FileSystemProviderRegistryTest, UpdateWatcherTag) { @@ -300,28 +290,25 @@ profile_->GetTestingPrefService(); ASSERT_TRUE(pref_service); - const base::DictionaryValue* const extensions = - &base::Value::AsDictionaryValue( - *pref_service->GetDictionary(prefs::kFileSystemProviderMounted)); + const base::Value* const extensions = + pref_service->GetDictionary(prefs::kFileSystemProviderMounted); ASSERT_TRUE(extensions); - const base::DictionaryValue* file_systems = NULL; - ASSERT_TRUE(extensions->GetDictionaryWithoutPathExpansion( - kProviderId.ToString(), &file_systems)); + const base::Value* file_systems = + extensions->FindDictKey(kProviderId.ToString()); + ASSERT_TRUE(file_systems); EXPECT_EQ(1u, file_systems->DictSize()); - const base::Value* file_system_value = file_systems->FindKey(kFileSystemId); - ASSERT_TRUE(file_system_value); - const base::DictionaryValue* file_system = NULL; - ASSERT_TRUE(file_system_value->GetAsDictionary(&file_system)); + const base::Value* file_system = file_systems->FindKey(kFileSystemId); + ASSERT_TRUE(file_system); - const base::DictionaryValue* watchers_value = NULL; - ASSERT_TRUE(file_system->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers, - &watchers_value)); + const base::Value* watchers_value = + file_system->FindDictKey(kPrefKeyWatchers); + ASSERT_TRUE(watchers_value); - const base::DictionaryValue* watcher = NULL; - ASSERT_TRUE(watchers_value->GetDictionaryWithoutPathExpansion( - fake_watcher_.entry_path.value(), &watcher)); + const base::Value* watcher = + watchers_value->FindDictKey(fake_watcher_.entry_path.value()); + ASSERT_TRUE(watcher); const std::string* last_tag = watcher->FindStringKey(kPrefKeyWatcherLastTag); EXPECT_TRUE(last_tag);
diff --git a/chrome/browser/ash/input_method/ui/grammar_suggestion_window.cc b/chrome/browser/ash/input_method/ui/grammar_suggestion_window.cc index aecb0e1..07fcac0 100644 --- a/chrome/browser/ash/input_method/ui/grammar_suggestion_window.cc +++ b/chrome/browser/ash/input_method/ui/grammar_suggestion_window.cc
@@ -28,8 +28,6 @@ // Large enough to make the background a circle. constexpr float kIconBorderRadius = 100; constexpr int kWindowOffsetY = -4; -const char16_t kSuggestionButtonAccessibleName[] = u"grammar suggestion button"; -const char16_t kIgnoreButtonAccessibleName[] = u"ignore button"; bool ShouldHighlight(const views::Button& button) { return button.GetState() == views::Button::STATE_HOVERED || @@ -61,9 +59,7 @@ .window_type = ui::ime::AssistiveWindowType::kGrammarSuggestion}))); suggestion_button_->SetBackground(nullptr); - suggestion_button_->SetAccessibleName(kSuggestionButtonAccessibleName); - suggestion_button_->SetFocusBehavior( - views::View::FocusBehavior::ACCESSIBLE_ONLY); + suggestion_button_->SetFocusBehavior(views::View::FocusBehavior::NEVER); suggestion_button_->SetVisible(true); ignore_button_ = @@ -76,8 +72,7 @@ }))); ignore_button_->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); ignore_button_->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE); - ignore_button_->SetAccessibleName(kIgnoreButtonAccessibleName); - ignore_button_->SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY); + ignore_button_->SetFocusBehavior(views::View::FocusBehavior::NEVER); ignore_button_->SetVisible(true); // Highlights buttons when they are hovered or pressed.
diff --git a/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.cc b/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.cc index 3d89966..41049a5 100644 --- a/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.cc +++ b/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.cc
@@ -146,8 +146,7 @@ clock_->NowTicks() - time_stamps_[State::kLaunchRequested]); } -void AppWindowMetricsTracker::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void AppWindowMetricsTracker::DocumentOnLoadCompletedInPrimaryMainFrame() { State next_state = state_after_window_contents_load_.value(); state_after_window_contents_load_.reset(); SetState(next_state);
diff --git a/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.h b/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.h index ba6ad76e..bc32a92 100644 --- a/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.h +++ b/chrome/browser/ash/lock_screen_apps/app_window_metrics_tracker.h
@@ -49,8 +49,7 @@ // content::WebContentsObserver: void RenderFrameCreated(content::RenderFrameHost* frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; private: // NOTE: Used in histograms - do not change order, or remove entries.
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc index 24873a0..9ac2114 100644 --- a/chrome/browser/ash/login/chrome_restart_request.cc +++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -119,7 +119,6 @@ ::switches::kEnableGpuRasterization, ::switches::kEnableLogging, ::switches::kEnableNativeGpuMemoryBuffers, - ::switches::kEnableOopRasterization, ::switches::kEnableTouchDragDrop, ::switches::kEnableUnifiedDesktop, ::switches::kEnableUseZoomForDSF,
diff --git a/chrome/browser/ash/login/demo_mode/OWNERS b/chrome/browser/ash/login/demo_mode/OWNERS index bc6d532f..f8073eb 100644 --- a/chrome/browser/ash/login/demo_mode/OWNERS +++ b/chrome/browser/ash/login/demo_mode/OWNERS
@@ -1,3 +1,4 @@ drcrash@chromium.org agawronska@chromium.org tbarzic@chromium.org +jacksontadie@google.com
diff --git a/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc index 5534073..7dfb804 100644 --- a/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc +++ b/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc
@@ -274,6 +274,10 @@ // consumer-owned) so doing a FRE check is not necessary. return FRERequirement::kNotRequired; } + if (!vpd_read_successfully) { + LOG(ERROR) << "VPD could not be read, skipping explicitly required auto " + "enrollment check."; + } return FRERequirement::kRequired; }
diff --git a/chrome/browser/ash/ownership/owner_settings_service_ash.cc b/chrome/browser/ash/ownership/owner_settings_service_ash.cc index e753b8f4..b69b32b 100644 --- a/chrome/browser/ash/ownership/owner_settings_service_ash.cc +++ b/chrome/browser/ash/ownership/owner_settings_service_ash.cc
@@ -690,6 +690,7 @@ // kReportDeviceSystemInfo // kReportDevicePrintJobs // kReportDeviceLoginLogout + // kReportCRDSessions // kServiceAccountIdentity // kSystemTimezonePolicy // kVariationsRestrictParameter
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc index f16b1c2..bcf5f6e 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -877,6 +877,11 @@ POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, base::Value(container.report_login_logout()), nullptr); } + if (container.has_report_crd_sessions()) { + policies->Set(key::kReportCRDSessions, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, + base::Value(container.report_crd_sessions()), nullptr); + } if (container.has_report_network_telemetry_collection_rate_ms()) { DecodeIntegerReportingPolicy( policies, key::kReportDeviceNetworkTelemetryCollectionRateMs,
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc index 9013d43..7aa7eda 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
@@ -223,6 +223,19 @@ std::move(report_login_logout_value)); } +TEST_F(DevicePolicyDecoderTest, ReportDeviceCRDSessions) { + em::ChromeDeviceSettingsProto device_policy; + + DecodeUnsetDevicePolicyTestHelper(device_policy, key::kReportCRDSessions); + + base::Value report_crd_sessions_value(true); + device_policy.mutable_device_reporting()->set_report_crd_sessions( + report_crd_sessions_value.GetBool()); + + DecodeDevicePolicyTestHelper(device_policy, key::kReportCRDSessions, + std::move(report_crd_sessions_value)); +} + TEST_F(DevicePolicyDecoderTest, ReportDeviceNetworkTelemetryCollectionRateMs) { em::ChromeDeviceSettingsProto device_policy;
diff --git a/chrome/browser/ash/policy/login/blocking_login_browsertest.cc b/chrome/browser/ash/policy/login/blocking_login_browsertest.cc index 8a2cd55..26ab1bd6 100644 --- a/chrome/browser/ash/policy/login/blocking_login_browsertest.cc +++ b/chrome/browser/ash/policy/login/blocking_login_browsertest.cc
@@ -265,19 +265,19 @@ case 5: PushResponse(net::HTTP_OK).set_content(GetPolicyResponse()); - FALLTHROUGH; + [[fallthrough]]; case 4: PushResponse(net::HTTP_OK).set_content(GetRegisterResponse()); - FALLTHROUGH; + [[fallthrough]]; case 3: PushResponse(net::HTTP_OK).set_content(kOAuth2AccessTokenData); - FALLTHROUGH; + [[fallthrough]]; case 2: PushResponse(net::HTTP_OK).set_content(kOAuth2TokenPairData); - FALLTHROUGH; + [[fallthrough]]; case 1: PushResponse(net::HTTP_OK)
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.cc index e4035d9..aebf320 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.cc
@@ -18,16 +18,18 @@ void UsbEventsObserver::OnAdd(UsbEventInfoPtr info) { MetricData metric_data; metric_data.mutable_event_data()->set_type(MetricEventType::USB_ADDED); - FillUsbEventData(metric_data.mutable_event_data()->mutable_usb_event_data(), - std::move(info)); + FillUsbTelemetry( + metric_data.mutable_telemetry_data()->mutable_usb_telemetry(), + std::move(info)); OnEventObserved(std::move(metric_data)); } void UsbEventsObserver::OnRemove(UsbEventInfoPtr info) { MetricData metric_data; metric_data.mutable_event_data()->set_type(MetricEventType::USB_REMOVED); - FillUsbEventData(metric_data.mutable_event_data()->mutable_usb_event_data(), - std::move(info)); + FillUsbTelemetry( + metric_data.mutable_telemetry_data()->mutable_usb_telemetry(), + std::move(info)); OnEventObserved(std::move(metric_data)); } @@ -36,7 +38,7 @@ BindNewPipeAndPassRemote()); } -void UsbEventsObserver::FillUsbEventData(UsbEventData* data, +void UsbEventsObserver::FillUsbTelemetry(UsbTelemetry* data, UsbEventInfoPtr info) { data->set_vendor(info->vendor); data->set_name(info->name);
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.h b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.h index 02a5667..8863c6b 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.h +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer.h
@@ -34,7 +34,7 @@ void AddObserver() override; private: - void FillUsbEventData(UsbEventData* data, UsbEventInfoPtr info); + void FillUsbTelemetry(UsbTelemetry* data, UsbEventInfoPtr info); }; } // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer_unittest.cc index 84c8519..ed02eb6 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer_unittest.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/usb/usb_events_observer_unittest.cc
@@ -74,28 +74,25 @@ usb_observer.OnRemove(std::move(test_usb_event_info)); ASSERT_TRUE(metric_data.has_event_data()); - ASSERT_TRUE(metric_data.event_data().has_usb_event_data()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_name()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_pid()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vendor()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vid()); - EXPECT_THAT(metric_data.event_data().usb_event_data().categories(), - Not(IsEmpty())); - EXPECT_THAT(metric_data.event_data().usb_event_data().name(), + ASSERT_TRUE(metric_data.telemetry_data().has_usb_telemetry()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_name()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_pid()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vendor()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vid()); + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().name(), StrEq(kTestName)); - EXPECT_THAT(metric_data.event_data().usb_event_data().pid(), Eq(kTestPid)); - EXPECT_THAT(metric_data.event_data().usb_event_data().vendor(), + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().pid(), Eq(kTestPid)); + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().vendor(), StrEq(kTestVendor)); - EXPECT_THAT(metric_data.event_data().usb_event_data().vid(), Eq(kTestVid)); - EXPECT_THAT(metric_data.event_data().usb_event_data().categories().size(), + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().vid(), Eq(kTestVid)); + EXPECT_EQ(metric_data.event_data().type(), MetricEventType::USB_REMOVED); + ASSERT_THAT(metric_data.telemetry_data().usb_telemetry().categories().size(), Eq(kTestCategories.size())); - for (int i = 0; i < kTestCategories.size(); i++) { - EXPECT_THAT(metric_data.event_data().usb_event_data().categories()[i], + for (int i = 0; i < kTestCategories.size(); ++i) { + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().categories()[i], StrEq(kTestCategories[i])); } - - EXPECT_EQ(metric_data.event_data().type(), MetricEventType::USB_REMOVED); } TEST_F(UsbEventsObserverTest, UsbOnRemoved) { @@ -109,28 +106,25 @@ usb_observer.OnAdd(std::move(test_usb_event_info)); ASSERT_TRUE(metric_data.has_event_data()); - ASSERT_TRUE(metric_data.event_data().has_usb_event_data()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_name()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_pid()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vendor()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vid()); - EXPECT_THAT(metric_data.event_data().usb_event_data().categories(), - Not(IsEmpty())); - EXPECT_THAT(metric_data.event_data().usb_event_data().name(), + ASSERT_TRUE(metric_data.telemetry_data().has_usb_telemetry()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_name()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_pid()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vendor()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vid()); + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().name(), StrEq(kTestName)); - EXPECT_THAT(metric_data.event_data().usb_event_data().pid(), Eq(kTestPid)); - EXPECT_THAT(metric_data.event_data().usb_event_data().vendor(), + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().pid(), Eq(kTestPid)); + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().vendor(), StrEq(kTestVendor)); - EXPECT_THAT(metric_data.event_data().usb_event_data().vid(), Eq(kTestVid)); - EXPECT_THAT(metric_data.event_data().usb_event_data().categories().size(), + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().vid(), Eq(kTestVid)); + EXPECT_EQ(metric_data.event_data().type(), MetricEventType::USB_ADDED); + ASSERT_THAT(metric_data.telemetry_data().usb_telemetry().categories().size(), Eq(kTestCategories.size())); - for (int i = 0; i < kTestCategories.size(); i++) { - EXPECT_THAT(metric_data.event_data().usb_event_data().categories()[i], + for (int i = 0; i < kTestCategories.size(); ++i) { + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().categories()[i], StrEq(kTestCategories[i])); } - - EXPECT_EQ(metric_data.event_data().type(), MetricEventType::USB_ADDED); } TEST_F(UsbEventsObserverTest, UsbOnAddUsingFakeCrosHealthdClient) { @@ -145,12 +139,12 @@ const auto metric_data = result_metric_data.result(); ASSERT_TRUE(metric_data.has_event_data()); - ASSERT_TRUE(metric_data.event_data().has_usb_event_data()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_name()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_pid()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vendor()); - EXPECT_TRUE(metric_data.event_data().usb_event_data().has_vid()); - EXPECT_THAT(metric_data.event_data().usb_event_data().categories(), + ASSERT_TRUE(metric_data.telemetry_data().has_usb_telemetry()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_name()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_pid()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vendor()); + EXPECT_TRUE(metric_data.telemetry_data().usb_telemetry().has_vid()); + EXPECT_THAT(metric_data.telemetry_data().usb_telemetry().categories(), IsEmpty()); EXPECT_EQ(metric_data.event_data().type(), MetricEventType::USB_ADDED); }
diff --git a/chrome/browser/ash/power/ml/smart_dim/builtin_worker.cc b/chrome/browser/ash/power/ml/smart_dim/builtin_worker.cc index 71d40ba..822a167 100644 --- a/chrome/browser/ash/power/ml/smart_dim/builtin_worker.cc +++ b/chrome/browser/ash/power/ml/smart_dim/builtin_worker.cc
@@ -91,7 +91,7 @@ if (!executor_) { // Get the graph executor. - model_->CreateGraphExecutorWithOptions( + model_->CreateGraphExecutor( chromeos::machine_learning::mojom::GraphExecutorOptions::New(), executor_.BindNewPipeAndPassReceiver(), base::DoNothing()); executor_.set_disconnect_handler(base::BindOnce(
diff --git a/chrome/browser/ash/power/ml/smart_dim/download_worker.cc b/chrome/browser/ash/power/ml/smart_dim/download_worker.cc index b27f6fd..a2685ed 100644 --- a/chrome/browser/ash/power/ml/smart_dim/download_worker.cc +++ b/chrome/browser/ash/power/ml/smart_dim/download_worker.cc
@@ -117,7 +117,7 @@ model_.BindNewPipeAndPassReceiver(), base::BindOnce(&DownloadWorker::LoadModelCallback, base::Unretained(this))); - model_->CreateGraphExecutorWithOptions( + model_->CreateGraphExecutor( chromeos::machine_learning::mojom::GraphExecutorOptions::New(), executor_.BindNewPipeAndPassReceiver(), base::BindOnce(&DownloadWorker::CreateGraphExecutorCallback,
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc index d17694e5..a613af3f 100644 --- a/chrome/browser/ash/settings/device_settings_provider.cc +++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -687,9 +687,8 @@ reporting_policy.report_network_interfaces()); } if (reporting_policy.has_report_network_status()) { - new_values_cache->SetBoolean( - kReportDeviceNetworkStatus, - reporting_policy.report_network_status()); + new_values_cache->SetBoolean(kReportDeviceNetworkStatus, + reporting_policy.report_network_status()); } if (reporting_policy.has_report_users()) { new_values_cache->SetBoolean(kReportDeviceUsers, @@ -779,6 +778,10 @@ new_values_cache->SetBoolean(kReportDeviceLoginLogout, reporting_policy.report_login_logout()); } + if (reporting_policy.has_report_crd_sessions()) { + new_values_cache->SetBoolean(kReportCRDSessions, + reporting_policy.report_crd_sessions()); + } if (reporting_policy.has_report_network_telemetry_collection_rate_ms()) { new_values_cache->SetInteger( kReportDeviceNetworkTelemetryCollectionRateMs, @@ -1603,7 +1606,7 @@ case DeviceSettingsService::STORE_NO_POLICY: if (MitigateMissingPolicy()) break; - FALLTHROUGH; + [[fallthrough]]; case DeviceSettingsService::STORE_KEY_UNAVAILABLE: VLOG(1) << "No policies present yet, will use the temp storage."; trusted_status_ = PERMANENTLY_UNTRUSTED;
diff --git a/chrome/browser/ash/settings/device_settings_provider_unittest.cc b/chrome/browser/ash/settings/device_settings_provider_unittest.cc index e80e3a6a0..9d99304c 100644 --- a/chrome/browser/ash/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
@@ -115,6 +115,7 @@ proto->set_report_app_info(enable_reporting); proto->set_report_print_jobs(enable_reporting); proto->set_report_login_logout(enable_reporting); + proto->set_report_crd_sessions(enable_reporting); proto->set_report_network_telemetry_collection_rate_ms(frequency); proto->set_report_network_telemetry_event_checking_rate_ms(frequency); proto->set_device_status_frequency(frequency);
diff --git a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc index 5662e761..0453f34 100644 --- a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc +++ b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
@@ -27,7 +27,6 @@ namespace { const char kToastId[] = "copy_to_clipboard_share_action"; -const int kToastDurationMs = 2500; void RecordMimeTypes( const base::flat_set<::sharesheet::SharesheetMetrics::MimeType>& @@ -109,10 +108,7 @@ ToastData toast(kToastId, l10n_util::GetStringUTF16( - IDS_SHARESHEET_COPY_TO_CLIPBOARD_SUCCESS_TOAST_LABEL), - kToastDurationMs, - /*dismiss_text=*/absl::nullopt, - /*visible_on_lock_screen=*/false); + IDS_SHARESHEET_COPY_TO_CLIPBOARD_SUCCESS_TOAST_LABEL)); ShowToast(toast); }
diff --git a/chrome/browser/ash/web_applications/personalization_app/DEPS b/chrome/browser/ash/web_applications/personalization_app/DEPS index f489ceaa..3a948b0d 100644 --- a/chrome/browser/ash/web_applications/personalization_app/DEPS +++ b/chrome/browser/ash/web_applications/personalization_app/DEPS
@@ -1,5 +1,5 @@ specific_include_rules = { - "chrome_personalization_app_ui_delegate.cc" : [ + "chrome_personalization_app_wallpaper_provider.cc" : [ "+chrome/browser/ui/views/frame/browser_view.h", "+chrome/browser/ui/views/frame/contents_web_view.h", ]
diff --git a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.cc similarity index 83% rename from chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc rename to chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.cc index e3a3f0fa..da667009 100644 --- a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc +++ b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h" +#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h" #include <stdint.h> #include <algorithm> @@ -99,24 +99,24 @@ } // namespace -ChromePersonalizationAppUiDelegate::ChromePersonalizationAppUiDelegate( - content::WebUI* web_ui) +ChromePersonalizationAppWallpaperProvider:: + ChromePersonalizationAppWallpaperProvider(content::WebUI* web_ui) : web_ui_(web_ui), profile_(Profile::FromWebUI(web_ui)) { content::URLDataSource::Add(profile_, std::make_unique<SanitizedImageSource>(profile_)); } -ChromePersonalizationAppUiDelegate::~ChromePersonalizationAppUiDelegate() = - default; +ChromePersonalizationAppWallpaperProvider:: + ~ChromePersonalizationAppWallpaperProvider() = default; -void ChromePersonalizationAppUiDelegate::BindInterface( +void ChromePersonalizationAppWallpaperProvider::BindInterface( mojo::PendingReceiver<ash::personalization_app::mojom::WallpaperProvider> receiver) { wallpaper_receiver_.reset(); wallpaper_receiver_.Bind(std::move(receiver)); } -void ChromePersonalizationAppUiDelegate::MakeTransparent() { +void ChromePersonalizationAppWallpaperProvider::MakeTransparent() { auto* web_contents = web_ui_->GetWebContents(); // Disable the window backdrop that creates an opaque layer in tablet mode. @@ -143,7 +143,7 @@ ->SetBackgroundColorOverride(SK_ColorTRANSPARENT); } -void ChromePersonalizationAppUiDelegate::FetchCollections( +void ChromePersonalizationAppWallpaperProvider::FetchCollections( FetchCollectionsCallback callback) { pending_collections_callbacks_.push_back(std::move(callback)); if (wallpaper_collection_info_fetcher_) { @@ -156,12 +156,12 @@ // base::Unretained is safe to use because |this| outlives // |wallpaper_collection_info_fetcher_|. - wallpaper_collection_info_fetcher_->Start( - base::BindOnce(&ChromePersonalizationAppUiDelegate::OnFetchCollections, - base::Unretained(this))); + wallpaper_collection_info_fetcher_->Start(base::BindOnce( + &ChromePersonalizationAppWallpaperProvider::OnFetchCollections, + base::Unretained(this))); } -void ChromePersonalizationAppUiDelegate::FetchImagesForCollection( +void ChromePersonalizationAppWallpaperProvider::FetchImagesForCollection( const std::string& collection_id, FetchImagesForCollectionCallback callback) { auto wallpaper_images_info_fetcher = @@ -170,12 +170,12 @@ auto* wallpaper_images_info_fetcher_ptr = wallpaper_images_info_fetcher.get(); wallpaper_images_info_fetcher_ptr->Start(base::BindOnce( - &ChromePersonalizationAppUiDelegate::OnFetchCollectionImages, + &ChromePersonalizationAppWallpaperProvider::OnFetchCollectionImages, weak_ptr_factory_.GetWeakPtr(), std::move(callback), std::move(wallpaper_images_info_fetcher))); } -void ChromePersonalizationAppUiDelegate::FetchGooglePhotosCount( +void ChromePersonalizationAppWallpaperProvider::FetchGooglePhotosCount( FetchGooglePhotosCountCallback callback) { if (!ash::features::IsWallpaperGooglePhotosIntegrationEnabled()) { mojo::ReportBadMessage( @@ -194,17 +194,17 @@ std::move(callback)); } -void ChromePersonalizationAppUiDelegate::GetLocalImages( +void ChromePersonalizationAppWallpaperProvider::GetLocalImages( GetLocalImagesCallback callback) { // TODO(b/190062481) also load images from android files. ash::EnumerateLocalWallpaperFiles( profile_, - base::BindOnce(&ChromePersonalizationAppUiDelegate::OnGetLocalImages, - backend_weak_ptr_factory_.GetWeakPtr(), - std::move(callback))); + base::BindOnce( + &ChromePersonalizationAppWallpaperProvider::OnGetLocalImages, + backend_weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } -void ChromePersonalizationAppUiDelegate::GetLocalImageThumbnail( +void ChromePersonalizationAppWallpaperProvider::GetLocalImageThumbnail( const base::FilePath& path, GetLocalImageThumbnailCallback callback) { if (local_images_.count(path) == 0) { @@ -221,11 +221,11 @@ thumbnail_loader_->Load( request, base::BindOnce( - &ChromePersonalizationAppUiDelegate::OnGetLocalImageThumbnail, + &ChromePersonalizationAppWallpaperProvider::OnGetLocalImageThumbnail, base::Unretained(this), std::move(callback))); } -void ChromePersonalizationAppUiDelegate::SetWallpaperObserver( +void ChromePersonalizationAppWallpaperProvider::SetWallpaperObserver( mojo::PendingRemote<ash::personalization_app::mojom::WallpaperObserver> observer) { // May already be bound if user refreshes page. @@ -237,7 +237,7 @@ OnWallpaperChanged(); } -void ChromePersonalizationAppUiDelegate::OnWallpaperChanged() { +void ChromePersonalizationAppWallpaperProvider::OnWallpaperChanged() { wallpaper_attribution_info_fetcher_.reset(); attribution_weak_ptr_factory_.InvalidateWeakPtrs(); @@ -258,10 +258,10 @@ DVLOG(2) << "no collection_id or asset_id found"; // Older versions of ChromeOS do not store these information, need to // look up all collections and match URL. - FetchCollections( - base::BindOnce(&ChromePersonalizationAppUiDelegate::FindAttribution, - attribution_weak_ptr_factory_.GetWeakPtr(), info, - wallpaper_data_url)); + FetchCollections(base::BindOnce( + &ChromePersonalizationAppWallpaperProvider::FindAttribution, + attribution_weak_ptr_factory_.GetWeakPtr(), info, + wallpaper_data_url)); return; } @@ -304,11 +304,11 @@ } } -void ChromePersonalizationAppUiDelegate::OnWallpaperPreviewEnded() { - ChromePersonalizationAppUiDelegate::OnWallpaperChanged(); +void ChromePersonalizationAppWallpaperProvider::OnWallpaperPreviewEnded() { + ChromePersonalizationAppWallpaperProvider::OnWallpaperChanged(); } -void ChromePersonalizationAppUiDelegate::SelectWallpaper( +void ChromePersonalizationAppWallpaperProvider::SelectWallpaper( uint64_t image_asset_id, bool preview_mode, SelectWallpaperCallback callback) { @@ -348,11 +348,11 @@ /*from_user=*/true, /*daily_refresh_enabled=*/false, it->second.unit_id, variants), base::BindOnce( - &ChromePersonalizationAppUiDelegate::OnOnlineWallpaperSelected, + &ChromePersonalizationAppWallpaperProvider::OnOnlineWallpaperSelected, backend_weak_ptr_factory_.GetWeakPtr())); } -void ChromePersonalizationAppUiDelegate::SelectLocalImage( +void ChromePersonalizationAppWallpaperProvider::SelectLocalImage( const base::FilePath& path, ash::WallpaperLayout layout, bool preview_mode, @@ -372,30 +372,31 @@ WallpaperController::Get()->SetCustomWallpaper( GetAccountId(profile_), path, layout, preview_mode, - base::BindOnce(&ChromePersonalizationAppUiDelegate::OnLocalImageSelected, - backend_weak_ptr_factory_.GetWeakPtr())); + base::BindOnce( + &ChromePersonalizationAppWallpaperProvider::OnLocalImageSelected, + backend_weak_ptr_factory_.GetWeakPtr())); } -void ChromePersonalizationAppUiDelegate::SetCustomWallpaperLayout( +void ChromePersonalizationAppWallpaperProvider::SetCustomWallpaperLayout( ash::WallpaperLayout layout) { WallpaperController::Get()->UpdateCustomWallpaperLayout( GetAccountId(profile_), layout); } -void ChromePersonalizationAppUiDelegate::SetDailyRefreshCollectionId( +void ChromePersonalizationAppWallpaperProvider::SetDailyRefreshCollectionId( const std::string& collection_id) { WallpaperController::Get()->SetDailyRefreshCollectionId( GetAccountId(profile_), collection_id); } -void ChromePersonalizationAppUiDelegate::GetDailyRefreshCollectionId( +void ChromePersonalizationAppWallpaperProvider::GetDailyRefreshCollectionId( GetDailyRefreshCollectionIdCallback callback) { auto* controller = WallpaperController::Get(); std::move(callback).Run( controller->GetDailyRefreshCollectionId(GetAccountId(profile_))); } -void ChromePersonalizationAppUiDelegate::UpdateDailyRefreshWallpaper( +void ChromePersonalizationAppWallpaperProvider::UpdateDailyRefreshWallpaper( UpdateDailyRefreshWallpaperCallback callback) { if (pending_update_daily_refresh_wallpaper_callback_) std::move(pending_update_daily_refresh_wallpaper_callback_) @@ -405,34 +406,35 @@ WallpaperControllerClientImpl::Get()->RecordWallpaperSourceUMA( ash::WallpaperType::kDaily); - WallpaperController::Get()->UpdateDailyRefreshWallpaper(base::BindOnce( - &ChromePersonalizationAppUiDelegate::OnDailyRefreshWallpaperUpdated, - backend_weak_ptr_factory_.GetWeakPtr())); + WallpaperController::Get()->UpdateDailyRefreshWallpaper( + base::BindOnce(&ChromePersonalizationAppWallpaperProvider:: + OnDailyRefreshWallpaperUpdated, + backend_weak_ptr_factory_.GetWeakPtr())); } -void ChromePersonalizationAppUiDelegate::IsInTabletMode( +void ChromePersonalizationAppWallpaperProvider::IsInTabletMode( IsInTabletModeCallback callback) { std::move(callback).Run(ash::TabletMode::IsInTabletMode()); } -void ChromePersonalizationAppUiDelegate::ConfirmPreviewWallpaper() { +void ChromePersonalizationAppWallpaperProvider::ConfirmPreviewWallpaper() { SetMinimizedWindowStateForPreview(/*preview_mode=*/false); WallpaperController::Get()->ConfirmPreviewWallpaper(); } -void ChromePersonalizationAppUiDelegate::CancelPreviewWallpaper() { +void ChromePersonalizationAppWallpaperProvider::CancelPreviewWallpaper() { SetMinimizedWindowStateForPreview(/*preview_mode=*/false); WallpaperController::Get()->CancelPreviewWallpaper(); } wallpaper_handlers::GooglePhotosCountFetcher* -ChromePersonalizationAppUiDelegate::SetGooglePhotosCountFetcherForTest( +ChromePersonalizationAppWallpaperProvider::SetGooglePhotosCountFetcherForTest( std::unique_ptr<wallpaper_handlers::GooglePhotosCountFetcher> fetcher) { google_photos_count_fetcher_ = std::move(fetcher); return google_photos_count_fetcher_.get(); } -void ChromePersonalizationAppUiDelegate::OnFetchCollections( +void ChromePersonalizationAppWallpaperProvider::OnFetchCollections( bool success, const std::vector<backdrop::Collection>& collections) { DCHECK(wallpaper_collection_info_fetcher_); @@ -450,7 +452,7 @@ wallpaper_collection_info_fetcher_.reset(); } -void ChromePersonalizationAppUiDelegate::OnFetchCollectionImages( +void ChromePersonalizationAppWallpaperProvider::OnFetchCollectionImages( FetchImagesForCollectionCallback callback, std::unique_ptr<wallpaper_handlers::BackdropImageInfoFetcher> fetcher, bool success, @@ -476,14 +478,14 @@ std::move(callback).Run(std::move(result)); } -void ChromePersonalizationAppUiDelegate::OnGetLocalImages( +void ChromePersonalizationAppWallpaperProvider::OnGetLocalImages( GetLocalImagesCallback callback, const std::vector<base::FilePath>& images) { local_images_ = std::set<base::FilePath>(images.begin(), images.end()); std::move(callback).Run(images); } -void ChromePersonalizationAppUiDelegate::OnGetLocalImageThumbnail( +void ChromePersonalizationAppWallpaperProvider::OnGetLocalImageThumbnail( GetLocalImageThumbnailCallback callback, const SkBitmap* bitmap, base::File::Error error) { @@ -496,24 +498,25 @@ std::move(callback).Run(webui::GetBitmapDataUrl(*bitmap)); } -void ChromePersonalizationAppUiDelegate::OnOnlineWallpaperSelected( +void ChromePersonalizationAppWallpaperProvider::OnOnlineWallpaperSelected( bool success) { DCHECK(pending_select_wallpaper_callback_); std::move(pending_select_wallpaper_callback_).Run(success); } -void ChromePersonalizationAppUiDelegate::OnLocalImageSelected(bool success) { +void ChromePersonalizationAppWallpaperProvider::OnLocalImageSelected( + bool success) { DCHECK(pending_select_local_image_callback_); std::move(pending_select_local_image_callback_).Run(success); } -void ChromePersonalizationAppUiDelegate::OnDailyRefreshWallpaperUpdated( +void ChromePersonalizationAppWallpaperProvider::OnDailyRefreshWallpaperUpdated( bool success) { DCHECK(pending_update_daily_refresh_wallpaper_callback_); std::move(pending_update_daily_refresh_wallpaper_callback_).Run(success); } -void ChromePersonalizationAppUiDelegate::FindAttribution( +void ChromePersonalizationAppWallpaperProvider::FindAttribution( const ash::WallpaperInfo& info, const GURL& wallpaper_data_url, const absl::optional<std::vector<backdrop::Collection>>& collections) { @@ -533,12 +536,12 @@ collections->at(current_index).collection_id()); wallpaper_attribution_info_fetcher_->Start(base::BindOnce( - &ChromePersonalizationAppUiDelegate::FindAttributionInCollection, + &ChromePersonalizationAppWallpaperProvider::FindAttributionInCollection, attribution_weak_ptr_factory_.GetWeakPtr(), info, wallpaper_data_url, current_index, collections)); } -void ChromePersonalizationAppUiDelegate::FindAttributionInCollection( +void ChromePersonalizationAppWallpaperProvider::FindAttributionInCollection( const ash::WallpaperInfo& info, const GURL& wallpaper_data_url, std::size_t current_index, @@ -589,7 +592,7 @@ auto fetcher = std::make_unique<wallpaper_handlers::BackdropImageInfoFetcher>( collections->at(current_index).collection_id()); fetcher->Start(base::BindOnce( - &ChromePersonalizationAppUiDelegate::FindAttributionInCollection, + &ChromePersonalizationAppWallpaperProvider::FindAttributionInCollection, attribution_weak_ptr_factory_.GetWeakPtr(), info, wallpaper_data_url, current_index, collections)); // resetting the previous fetcher last because the current method is bound @@ -597,8 +600,8 @@ wallpaper_attribution_info_fetcher_ = std::move(fetcher); } -void ChromePersonalizationAppUiDelegate::SetMinimizedWindowStateForPreview( - bool preview_mode) { +void ChromePersonalizationAppWallpaperProvider:: + SetMinimizedWindowStateForPreview(bool preview_mode) { auto* wallpaper_controller = WallpaperController::Get(); const std::string& user_id_hash = GetUser(profile_)->username_hash(); if (preview_mode) @@ -607,7 +610,7 @@ wallpaper_controller->RestoreMinimizedWindows(user_id_hash); } -void ChromePersonalizationAppUiDelegate::NotifyWallpaperChanged( +void ChromePersonalizationAppWallpaperProvider::NotifyWallpaperChanged( ash::personalization_app::mojom::CurrentWallpaperPtr current_wallpaper) { DCHECK(wallpaper_observer_remote_.is_bound()); wallpaper_observer_remote_->OnWallpaperChanged(std::move(current_wallpaper));
diff --git a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h similarity index 88% rename from chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h rename to chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h index 862a3023e..8249cff7 100644 --- a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h +++ b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h
@@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_UI_DELEGATE_H_ -#define CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_UI_DELEGATE_H_ +#ifndef CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ +#define CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_ -#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h" -#include "ash/webui/personalization_app/personalization_app_ui_delegate.h" +#include "ash/webui/personalization_app/personalization_app_wallpaper_provider.h" #include <stdint.h> @@ -52,23 +51,22 @@ class Profile; -// Implemented in //chrome because this will rely on chrome -// |wallpaper_handlers| code when fully implemented. -// TODO(b/182012641) add wallpaper API code here. -class ChromePersonalizationAppUiDelegate - : public ash::PersonalizationAppUiDelegate, +// Implemented in //chrome because this relies on chrome |wallpaper_handlers| +// code. +class ChromePersonalizationAppWallpaperProvider + : public ash::PersonalizationAppWallpaperProvider, ash::WallpaperControllerObserver { public: - explicit ChromePersonalizationAppUiDelegate(content::WebUI* web_ui); + explicit ChromePersonalizationAppWallpaperProvider(content::WebUI* web_ui); - ChromePersonalizationAppUiDelegate( - const ChromePersonalizationAppUiDelegate&) = delete; - ChromePersonalizationAppUiDelegate& operator=( - const ChromePersonalizationAppUiDelegate&) = delete; + ChromePersonalizationAppWallpaperProvider( + const ChromePersonalizationAppWallpaperProvider&) = delete; + ChromePersonalizationAppWallpaperProvider& operator=( + const ChromePersonalizationAppWallpaperProvider&) = delete; - ~ChromePersonalizationAppUiDelegate() override; + ~ChromePersonalizationAppWallpaperProvider() override; - // PersonalizationAppUIDelegate: + // PersonalizationAppWallpaperProvider: // |BindInterface| may be called multiple times, for example if the user // presses Ctrl+Shift+R while on the personalization app. void BindInterface( @@ -136,7 +134,7 @@ std::unique_ptr<wallpaper_handlers::GooglePhotosCountFetcher> fetcher); private: - friend class ChromePersonalizationAppUiDelegateTest; + friend class ChromePersonalizationAppWallpaperProviderTest; void OnFetchCollections(bool success, const std::vector<backdrop::Collection>& collections); @@ -259,16 +257,16 @@ wallpaper_observer_remote_; // Used for interacting with local filesystem. - base::WeakPtrFactory<ChromePersonalizationAppUiDelegate> + base::WeakPtrFactory<ChromePersonalizationAppWallpaperProvider> backend_weak_ptr_factory_{this}; // Used for fetching online image attribution. - base::WeakPtrFactory<ChromePersonalizationAppUiDelegate> + base::WeakPtrFactory<ChromePersonalizationAppWallpaperProvider> attribution_weak_ptr_factory_{this}; // General use other than the specific cases above. - base::WeakPtrFactory<ChromePersonalizationAppUiDelegate> weak_ptr_factory_{ - this}; + base::WeakPtrFactory<ChromePersonalizationAppWallpaperProvider> + weak_ptr_factory_{this}; }; -#endif // CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_UI_DELEGATE_H_ +#endif // CHROME_BROWSER_ASH_WEB_APPLICATIONS_PERSONALIZATION_APP_CHROME_PERSONALIZATION_APP_WALLPAPER_PROVIDER_H_
diff --git a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider_unittest.cc similarity index 88% rename from chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate_unittest.cc rename to chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider_unittest.cc index 6e723e6..e8a7255 100644 --- a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h" +#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h" #include <memory> @@ -112,16 +112,16 @@ } // namespace -class ChromePersonalizationAppUiDelegateTest : public testing::Test { +class ChromePersonalizationAppWallpaperProviderTest : public testing::Test { public: - ChromePersonalizationAppUiDelegateTest() + ChromePersonalizationAppWallpaperProviderTest() : scoped_user_manager_(std::make_unique<ash::FakeChromeUserManager>()), profile_manager_(TestingBrowserProcess::GetGlobal()) {} - ChromePersonalizationAppUiDelegateTest( - const ChromePersonalizationAppUiDelegateTest&) = delete; - ChromePersonalizationAppUiDelegateTest& operator=( - const ChromePersonalizationAppUiDelegateTest&) = delete; - ~ChromePersonalizationAppUiDelegateTest() override = default; + ChromePersonalizationAppWallpaperProviderTest( + const ChromePersonalizationAppWallpaperProviderTest&) = delete; + ChromePersonalizationAppWallpaperProviderTest& operator=( + const ChromePersonalizationAppWallpaperProviderTest&) = delete; + ~ChromePersonalizationAppWallpaperProviderTest() override = default; protected: // testing::Test: @@ -141,16 +141,17 @@ content::WebContents::CreateParams(profile_)); web_ui_.set_web_contents(web_contents_.get()); - delegate_ = std::make_unique<ChromePersonalizationAppUiDelegate>(&web_ui_); + wallpaper_provider_ = + std::make_unique<ChromePersonalizationAppWallpaperProvider>(&web_ui_); - delegate_->BindInterface( + wallpaper_provider_->BindInterface( wallpaper_provider_remote_.BindNewPipeAndPassReceiver()); } void AddWallpaperImage( uint64_t asset_id, - const ChromePersonalizationAppUiDelegate::ImageInfo& image_info) { - delegate_->image_asset_id_map_.insert({asset_id, image_info}); + const ChromePersonalizationAppWallpaperProvider::ImageInfo& image_info) { + wallpaper_provider_->image_asset_id_map_.insert({asset_id, image_info}); } TestWallpaperController* test_wallpaper_controller() { @@ -164,7 +165,9 @@ return &wallpaper_provider_remote_; } - ChromePersonalizationAppUiDelegate* delegate() { return delegate_.get(); } + ChromePersonalizationAppWallpaperProvider* delegate() { + return wallpaper_provider_.get(); + } void SetWallpaperObserver() { wallpaper_provider_remote_->SetWallpaperObserver( @@ -198,11 +201,12 @@ mojo::Remote<ash::personalization_app::mojom::WallpaperProvider> wallpaper_provider_remote_; TestWallpaperObserver test_wallpaper_observer_; - std::unique_ptr<ChromePersonalizationAppUiDelegate> delegate_; + std::unique_ptr<ChromePersonalizationAppWallpaperProvider> + wallpaper_provider_; base::test::ScopedFeatureList scoped_feature_list_; }; -TEST_F(ChromePersonalizationAppUiDelegateTest, SelectWallpaper) { +TEST_F(ChromePersonalizationAppWallpaperProviderTest, SelectWallpaper) { test_wallpaper_controller()->ClearCounts(); const uint64_t asset_id = 1; @@ -240,7 +244,7 @@ test_wallpaper_controller()->wallpaper_info().value()); } -TEST_F(ChromePersonalizationAppUiDelegateTest, PreviewWallpaper) { +TEST_F(ChromePersonalizationAppWallpaperProviderTest, PreviewWallpaper) { test_wallpaper_controller()->ClearCounts(); const uint64_t asset_id = 1; @@ -278,7 +282,8 @@ test_wallpaper_controller()->wallpaper_info().value()); } -TEST_F(ChromePersonalizationAppUiDelegateTest, ObserveWallpaperFiresWhenBound) { +TEST_F(ChromePersonalizationAppWallpaperProviderTest, + ObserveWallpaperFiresWhenBound) { // This will create the data url referenced below in expectation. test_wallpaper_controller()->ShowWallpaperImage( CreateSolidImageSkia(/*width=*/1, /*height=*/1, SK_ColorBLACK)); @@ -323,8 +328,8 @@ current->url); } -class ChromePersonalizationAppUiDelegateGooglePhotosTest - : public ChromePersonalizationAppUiDelegateTest, +class ChromePersonalizationAppWallpaperProviderGooglePhotosTest + : public ChromePersonalizationAppWallpaperProviderTest, public testing::WithParamInterface<bool /* google_photos_enabled */> { public: // Returns true if the test should run with the Google Photos Wallpaper @@ -332,9 +337,9 @@ bool GooglePhotosEnabled() const { return GetParam(); } protected: - // ChromePersonalizationAppUiDelegateTest: + // ChromePersonalizationAppWallpaperProviderTest: void SetUp() override { - ChromePersonalizationAppUiDelegateTest::SetUp(); + ChromePersonalizationAppWallpaperProviderTest::SetUp(); scoped_feature_list_.InitWithFeatureState( ash::features::kWallpaperGooglePhotosIntegration, GooglePhotosEnabled()); @@ -344,11 +349,12 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -INSTANTIATE_TEST_SUITE_P(All, - ChromePersonalizationAppUiDelegateGooglePhotosTest, - /*google_photos_enabled=*/::testing::Bool()); +INSTANTIATE_TEST_SUITE_P( + All, + ChromePersonalizationAppWallpaperProviderGooglePhotosTest, + /*google_photos_enabled=*/::testing::Bool()); -TEST_P(ChromePersonalizationAppUiDelegateGooglePhotosTest, FetchCount) { +TEST_P(ChromePersonalizationAppWallpaperProviderGooglePhotosTest, FetchCount) { // Mock a fetcher for the photos count query. auto* const google_photos_count_fetcher = static_cast< wallpaper_handlers::MockGooglePhotosCountFetcher*>(
diff --git a/chrome/browser/ash/web_applications/terminal_source.cc b/chrome/browser/ash/web_applications/terminal_source.cc index 7754c73..2e36388 100644 --- a/chrome/browser/ash/web_applications/terminal_source.cc +++ b/chrome/browser/ash/web_applications/terminal_source.cc
@@ -123,8 +123,17 @@ if (path.empty()) path = default_file_; - // Replace $i8n{themeColor} in *.html. - if (base::EndsWith(path, ".html", base::CompareCase::INSENSITIVE_ASCII)) { + // TODO(crbug.com/1283153): Remove this redirect when the migration is + // complete. + if (path == "html/nassh.html") { + path = "html/terminal_ssh.html"; + } + + // Refresh the $i8n{themeColor} replacement for css and html files. + if (base::EndsWith(path, ".css", base::CompareCase::INSENSITIVE_ASCII) + // TODO(crbug.com/1283153): We don't need to do it for html files when the + // migration is complete and we don't use nassh.html any more. + || base::EndsWith(path, ".html", base::CompareCase::INSENSITIVE_ASCII)) { replacements_["themeColor"] = net::EscapeForHTML( crostini::GetTerminalSettingBackgroundColor(profile_)); } @@ -171,7 +180,7 @@ case network::mojom::CSPDirectiveName::StyleSrc: return "style-src * 'unsafe-inline'; font-src *;"; case network::mojom::CSPDirectiveName::RequireTrustedTypesFor: - FALLTHROUGH; + [[fallthrough]]; case network::mojom::CSPDirectiveName::TrustedTypes: // TODO(crbug.com/1098685): Trusted Type remaining WebUI // This removes require-trusted-types-for and trusted-types directives
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc index dd81541..8423bf9 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc
@@ -114,6 +114,7 @@ const GURL& url, const std::string& header_value, int32_t load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, OnClearSiteDataCallback callback) { std::move(callback).Run(); }
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h index 6badf39..df296860 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h
@@ -75,10 +75,12 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnClearSiteData(const GURL& url, - const std::string& header_value, - int32_t load_flags, - OnClearSiteDataCallback callback) override; + void OnClearSiteData( + const GURL& url, + const std::string& header_value, + int32_t load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) override; void OnLoadingStateUpdate(network::mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) override; void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash,
diff --git a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.cc b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.cc index fc6995f..d21b8e64 100644 --- a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.cc +++ b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.cc
@@ -29,18 +29,25 @@ DCHECK(provider_); current_input_id_ = 0; - // Extension suggestions always come from the original profile, since that's - // where extensions run. We use the input ID to distinguish whether the - // suggestions are meant for us. - registrar_.Add(this, - extensions::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, - content::Source<Profile>(profile_->GetOriginalProfile())); + registrar_.Add( this, extensions::NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, content::Source<Profile>(profile_->GetOriginalProfile())); - omnibox_observation_.Observe(OmniboxWatcher::GetForBrowserContext(profile_)); + omnibox_input_observation_.Observe( + OmniboxInputWatcher::GetForBrowserContext(profile_)); + + // TODO(crbug.com/1278436): The comment below is historic and maybe misleading + // because extensions don't always "run" in the original profile. Review and + // update as needed. + // + // Extension suggestions always come from the original profile, since that's + // where extensions run. We use the input ID to distinguish whether the + // suggestions are meant for us. + omnibox_suggestions_observation_.Observe( + OmniboxSuggestionsWatcher::GetForBrowserContext( + profile_->GetOriginalProfile())); } KeywordExtensionsDelegateImpl::~KeywordExtensionsDelegateImpl() = default; @@ -135,6 +142,60 @@ IncrementInputId(); } +void KeywordExtensionsDelegateImpl::OnOmniboxSuggestionsReady( + omnibox_api::SendSuggestions::Params* suggestions) { + DCHECK(suggestions); + + if (suggestions->request_id != current_input_id_) + return; // This is an old result. Just ignore. + + TemplateURLService* model = provider_->GetTemplateURLService(); + DCHECK(model); + + const AutocompleteInput& input = extension_suggest_last_input_; + + // ExtractKeywordFromInput() can fail if e.g. this code is triggered by + // direct calls from the development console, outside the normal flow of + // user input. + std::u16string keyword, remaining_input; + if (!KeywordProvider::ExtractKeywordFromInput(input, model, &keyword, + &remaining_input)) + return; + + const TemplateURL* template_url = model->GetTemplateURLForKeyword(keyword); + + for (size_t i = 0; i < suggestions->suggest_results.size(); ++i) { + const omnibox_api::SuggestResult& suggestion = + suggestions->suggest_results[i]; + // We want to order these suggestions in descending order, so start with + // the relevance of the first result (added synchronously in Start()), + // and subtract 1 for each subsequent suggestion from the extension. + // We recompute the first match's relevance; we know that |complete| + // is true, because we wouldn't get results from the extension unless + // the full keyword had been typed. + int first_relevance = KeywordProvider::CalculateRelevance( + input.type(), true, true, true, input.prefer_keyword(), + input.allow_exact_keyword_match()); + // Because these matches are async, we should never let them become the + // default match, lest we introduce race conditions in the omnibox user + // interaction. + extension_suggest_matches_.push_back(provider_->CreateAutocompleteMatch( + template_url, keyword.length(), input, keyword.length(), + base::UTF8ToUTF16(suggestion.content), false, first_relevance - (i + 1), + suggestion.deletable && *suggestion.deletable)); + + AutocompleteMatch* match = &extension_suggest_matches_.back(); + match->contents.assign(base::UTF8ToUTF16(suggestion.description)); + match->contents_class = + extensions::StyleTypesToACMatchClassifications(suggestion); + } + + set_done(true); + matches()->insert(matches()->end(), extension_suggest_matches_.begin(), + extension_suggest_matches_.end()); + OnProviderUpdate(!extension_suggest_matches_.empty()); +} + void KeywordExtensionsDelegateImpl::Observe( int type, const content::NotificationSource& source, @@ -162,60 +223,6 @@ return; } - case extensions::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY: { - const omnibox_api::SendSuggestions::Params& suggestions = - *content::Details< - omnibox_api::SendSuggestions::Params>(details).ptr(); - if (suggestions.request_id != current_input_id_) - return; // This is an old result. Just ignore. - - DCHECK(model); - // ExtractKeywordFromInput() can fail if e.g. this code is triggered by - // direct calls from the development console, outside the normal flow of - // user input. - std::u16string keyword, remaining_input; - if (!KeywordProvider::ExtractKeywordFromInput(input, model, &keyword, - &remaining_input)) - return; - - const TemplateURL* template_url = - model->GetTemplateURLForKeyword(keyword); - - for (size_t i = 0; i < suggestions.suggest_results.size(); ++i) { - const omnibox_api::SuggestResult& suggestion = - suggestions.suggest_results[i]; - // We want to order these suggestions in descending order, so start with - // the relevance of the first result (added synchronously in Start()), - // and subtract 1 for each subsequent suggestion from the extension. - // We recompute the first match's relevance; we know that |complete| - // is true, because we wouldn't get results from the extension unless - // the full keyword had been typed. - int first_relevance = KeywordProvider::CalculateRelevance( - input.type(), true, true, true, input.prefer_keyword(), - input.allow_exact_keyword_match()); - // Because these matches are async, we should never let them become the - // default match, lest we introduce race conditions in the omnibox user - // interaction. - extension_suggest_matches_.push_back(provider_->CreateAutocompleteMatch( - template_url, keyword.length(), input, keyword.length(), - base::UTF8ToUTF16(suggestion.content), false, - first_relevance - (i + 1), - suggestion.deletable && *suggestion.deletable)); - - AutocompleteMatch* match = &extension_suggest_matches_.back(); - match->contents.assign(base::UTF8ToUTF16(suggestion.description)); - match->contents_class = - extensions::StyleTypesToACMatchClassifications(suggestion); - } - - set_done(true); - matches()->insert(matches()->end(), - extension_suggest_matches_.begin(), - extension_suggest_matches_.end()); - OnProviderUpdate(!extension_suggest_matches_.empty()); - return; - } - default: NOTREACHED(); return;
diff --git a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h index 84c89f8..45a79c21 100644 --- a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h +++ b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h
@@ -17,7 +17,8 @@ #include "components/omnibox/browser/autocomplete_provider_listener.h" #include "components/omnibox/browser/keyword_extensions_delegate.h" #include "components/omnibox/browser/keyword_provider.h" -#include "components/omnibox/browser/omnibox_watcher.h" +#include "components/omnibox/browser/omnibox_input_watcher.h" +#include "components/omnibox/browser/omnibox_suggestions_watcher.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "extensions/buildflags/buildflags.h" @@ -28,9 +29,11 @@ class Profile; -class KeywordExtensionsDelegateImpl : public KeywordExtensionsDelegate, - public content::NotificationObserver, - public OmniboxWatcher::Observer { +class KeywordExtensionsDelegateImpl + : public KeywordExtensionsDelegate, + public content::NotificationObserver, + public OmniboxInputWatcher::Observer, + public OmniboxSuggestionsWatcher::Observer { public: KeywordExtensionsDelegateImpl(Profile* profile, KeywordProvider* provider); @@ -55,8 +58,11 @@ void EnterExtensionKeywordMode(const std::string& extension_id) override; void MaybeEndExtensionKeywordMode() override; - // OmniboxWatcher::Observer: + // OmniboxInputWatcher::Observer: void OnOmniboxInputEntered() override; + // OmniboxSuggestionsWatcher::Observer: + void OnOmniboxSuggestionsReady( + extensions::api::omnibox::SendSuggestions::Params* suggestions) override; // content::NotificationObserver: void Observe(int type, @@ -99,8 +105,11 @@ // UID that each provider uses. static int global_input_uid_; - base::ScopedObservation<OmniboxWatcher, OmniboxWatcher::Observer> - omnibox_observation_{this}; + base::ScopedObservation<OmniboxInputWatcher, OmniboxInputWatcher::Observer> + omnibox_input_observation_{this}; + base::ScopedObservation<OmniboxSuggestionsWatcher, + OmniboxSuggestionsWatcher::Observer> + omnibox_suggestions_observation_{this}; }; #endif // CHROME_BROWSER_AUTOCOMPLETE_KEYWORD_EXTENSIONS_DELEGATE_IMPL_H_
diff --git a/chrome/browser/background_fetch/background_fetch_permission_context.cc b/chrome/browser/background_fetch/background_fetch_permission_context.cc index 63c9427..7f7a134 100644 --- a/chrome/browser/background_fetch/background_fetch_permission_context.cc +++ b/chrome/browser/background_fetch/background_fetch_permission_context.cc
@@ -29,18 +29,6 @@ const GURL& embedding_origin) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - auto* host_content_settings_map = - HostContentSettingsMapFactory::GetForProfile(browser_context()); - DCHECK(host_content_settings_map); - - // The set of valid settings for automatic downloads is defined as - // {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK}. - const ContentSetting setting = host_content_settings_map->GetContentSetting( - requesting_origin, requesting_origin, - ContentSettingsType::AUTOMATIC_DOWNLOADS); - if (setting == CONTENT_SETTING_BLOCK) - return setting; - if (render_frame_host && !render_frame_host->GetParent()) { DownloadRequestLimiter* limiter = g_browser_process->download_request_limiter(); @@ -62,13 +50,26 @@ } // |render_frame_host| is either a nullptr, which means we're being called - // from a worker context, or it's not a top level frame. Due to privacy - // concerns as outlined in https://crbug.com/896311 the most permissive state - // BGF can be in for non top level frames or service workers is ASK. This - // causes background fetches that do not originate in a main frame to start - // paused. - DCHECK(setting == CONTENT_SETTING_ASK || setting == CONTENT_SETTING_ALLOW); - return CONTENT_SETTING_ASK; + // from a worker context, or it's not a top level frame. In either case, use + // content settings. + auto* host_content_settings_map = + HostContentSettingsMapFactory::GetForProfile(browser_context()); + DCHECK(host_content_settings_map); + + // The set of valid settings for automatic downloads is defined as + // {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK}. + ContentSetting setting = host_content_settings_map->GetContentSetting( + requesting_origin, requesting_origin, + ContentSettingsType::AUTOMATIC_DOWNLOADS); + + // Due to privacy concerns as outlined in https://crbug.com/896311 the most + // permissive state BGF can be in for non top level frames or service workers + // is ASK. This causes background fetches that do not originate in a main + // frame to start paused. + if (setting == CONTENT_SETTING_ALLOW) + setting = CONTENT_SETTING_ASK; + + return setting; } void BackgroundFetchPermissionContext::DecidePermission(
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 9240870..214eea4 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -637,12 +637,14 @@ if (sb_service) safe_browsing_context = sb_service->GetNetworkContext(profile_); - browsing_data::RemoveEmbedderCookieData( - delete_begin, delete_end, filter_builder, host_content_settings_map_, - safe_browsing_context, - base::BindOnce( - &ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosure, - base::Unretained(this), TracingDataType::kCookies)); + if (!filter_builder->IsCrossSiteClearSiteData()) { + browsing_data::RemoveEmbedderCookieData( + delete_begin, delete_end, filter_builder, host_content_settings_map_, + safe_browsing_context, + base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosure, + base::Unretained(this), TracingDataType::kCookies)); + } if (filter_builder->GetMode() == BrowsingDataFilterBuilder::Mode::kPreserve) { @@ -661,7 +663,8 @@ } if (nullable_filter.is_null() || - nullable_filter.Run(GaiaUrls::GetInstance()->google_url())) { + (!filter_builder->IsCrossSiteClearSiteData() && + nullable_filter.Run(GaiaUrls::GetInstance()->google_url()))) { // Set a flag to clear account storage settings later instead of clearing // it now as we can not reset this setting before passwords are deleted. should_clear_password_account_storage_settings_ = true; @@ -853,7 +856,7 @@ ServiceAccessType::EXPLICIT_ACCESS) .get(); - if (password_store) { + if (password_store && !filter_builder->IsCrossSiteClearSiteData()) { password_store->DisableAutoSignInForOrigins( filter, CreateTaskCompletionClosure(TracingDataType::kDisableAutoSignin));
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 7c5340e..12986539 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -2148,6 +2148,22 @@ } TEST_F(ChromeBrowsingDataRemoverDelegateTest, + DisableAutoSignInCrossSiteClearSiteData) { + RemovePasswordsTester tester(GetProfile()); + std::unique_ptr<BrowsingDataFilterBuilder> filter( + BrowsingDataFilterBuilder::Create( + BrowsingDataFilterBuilder::Mode::kDelete)); + filter->AddRegisterableDomain("cookie.com"); + filter->SetCookiePartitionKeyCollection(net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://notcookie.com")))); + EXPECT_CALL(*tester.profile_store(), DisableAutoSignInForOrigins).Times(0); + BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), + content::BrowsingDataRemover::DATA_TYPE_COOKIES, + std::move(filter)); +} + +TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveContentSettingsWithPreserveFilter) { // This test relies on async loading to complete. RunUntilIdle() should be // removed and an explicit wait should be added.
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index e66c9cf..93a5245 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -663,6 +663,16 @@ // needs to be done before any child processes are initialized as the // ModuleDatabase is an endpoint for IPC from child processes. SetupModuleDatabase(&module_watcher_); + + // If Chrome was launched by a Progressive Web App launcher that needs to be + // updated, update all launchers for this profile. + if (parsed_command_line().HasSwitch(switches::kAppId) && + parsed_command_line().GetSwitchValueASCII( + switches::kPwaLauncherVersion) != chrome::kChromeVersion) { + content::BrowserThread::PostBestEffortTask( + FROM_HERE, base::SequencedTaskRunnerHandle::Get(), + base::BindOnce(&UpdatePwaLaunchersForProfile, profile()->GetPath())); + } } void ChromeBrowserMainPartsWin::PostBrowserStart() { @@ -715,16 +725,6 @@ base::BindOnce(&web_app::WriteChromePathToLastBrowserFile, user_data_dir())); - // If Chrome was launched by a Progressive Web App launcher that needs to be - // updated, update all launchers for this profile. - if (parsed_command_line().HasSwitch(switches::kAppId) && - parsed_command_line().GetSwitchValueASCII( - switches::kPwaLauncherVersion) != chrome::kChromeVersion) { - content::BrowserThread::PostBestEffortTask( - FROM_HERE, base::SequencedTaskRunnerHandle::Get(), - base::BindOnce(&UpdatePwaLaunchersForProfile, profile()->GetPath())); - } - // Record the result of the latest Progressive Web App launcher launch. base::ThreadPool::PostTask( FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 831fef51..89b6e02 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -376,6 +376,7 @@ #include "components/user_manager/user_manager.h" #include "services/service_manager/public/mojom/interface_provider_spec.mojom.h" #include "storage/browser/file_system/external_mount_points.h" +#include "third_party/cros_system_api/switches/chrome_switches.h" #elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/browser/chrome_browser_main_linux.h" #elif defined(OS_ANDROID) @@ -2446,6 +2447,7 @@ static const char* const kSwitchNames[] = { switches::kEnableNaClDebug, switches::kForcePNaClSubzero, + switches::kVerboseLoggingInNacl, }; command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, @@ -2457,6 +2459,14 @@ command_line->CopySwitchesFrom(browser_command_line, kMoreSwitchNames, base::size(kMoreSwitchNames)); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + // This is called before feature flags are parsed, so pass them in their raw + // form. + static const char* const kMoreCrOSSwitchNames[] = { + chromeos::switches::kFeatureFlags}; + command_line->CopySwitchesFrom(browser_command_line, kMoreCrOSSwitchNames, + base::size(kMoreCrOSSwitchNames)); +#endif } else if (process_type == switches::kGpuProcess) { // If --ignore-gpu-blocklist is passed in, don't send in crash reports // because GPU is expected to be unreliable. @@ -4893,6 +4903,7 @@ RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) content::RenderFrameHost* frame_host =
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 5ac9a68..fd28446 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -494,6 +494,7 @@ void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) override; bool WillCreateURLLoaderFactory( content::BrowserContext* browser_context,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index d65f3975..d4e3b674 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -40,6 +40,7 @@ "//chromeos/dbus:seneschal_proto", "//chromeos/dbus:vm_applications_apps_proto", "//chromeos/dbus:vm_disk_management_proto", + "//chromeos/dbus:vm_launch_proto", "//chromeos/dbus:vm_permission_service_proto", "//chromeos/dbus:vm_sk_forwarding_proto", "//chromeos/dbus/anomaly_detector:proto", @@ -1385,6 +1386,8 @@ "../ash/dbus/virtual_file_request_service_provider.h", "../ash/dbus/vm/vm_disk_management_service_provider.cc", "../ash/dbus/vm/vm_disk_management_service_provider.h", + "../ash/dbus/vm/vm_launch_service_provider.cc", + "../ash/dbus/vm/vm_launch_service_provider.h", "../ash/dbus/vm/vm_permission_service_provider.cc", "../ash/dbus/vm/vm_permission_service_provider.h", "../ash/dbus/vm/vm_sk_forwarding_service_provider.cc", @@ -3192,8 +3195,8 @@ "../ash/web_applications/os_settings_web_app_info.h", "../ash/web_applications/os_url_handler_system_web_app_info.cc", "../ash/web_applications/os_url_handler_system_web_app_info.h", - "../ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc", - "../ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h", + "../ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.cc", + "../ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h", "../ash/web_applications/personalization_app/personalization_app_info.cc", "../ash/web_applications/personalization_app/personalization_app_info.h", "../ash/web_applications/print_management_web_app_info.cc", @@ -3618,6 +3621,7 @@ "../ash/dbus/org.chromium.VirtualFileRequestService.conf", "../ash/dbus/org.chromium.VmApplicationsService.conf", "../ash/dbus/vm/org.chromium.VmDiskManagementService.conf", + "../ash/dbus/vm/org.chromium.VmLaunchService.conf", "../ash/dbus/vm/org.chromium.VmPermissionService.conf", "../ash/dbus/vm/org.chromium.VmSKForwardingService.conf", ] @@ -4584,7 +4588,7 @@ "../ash/usb/cros_usb_detector_unittest.cc", "../ash/web_applications/help_app/help_app_discover_tab_notification_unittest.cc", "../ash/web_applications/help_app/help_app_notification_controller_unittest.cc", - "../ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate_unittest.cc", + "../ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider_unittest.cc", "../ash/wilco_dtc_supportd/testing_wilco_dtc_supportd_bridge_wrapper.cc", "../ash/wilco_dtc_supportd/testing_wilco_dtc_supportd_bridge_wrapper.h", "../ash/wilco_dtc_supportd/testing_wilco_dtc_supportd_network_context.cc",
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 7bd4fe7b..bf9f80e0 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -541,19 +541,18 @@ DCHECK(value.is_bool()); } else if (pref_name == prefs::kPrintingAPIExtensionsAllowlist) { DCHECK(value.is_list()); - } else if (pref_name == ash::quick_answers::prefs::kQuickAnswersEnabled) { + } else if (pref_name == quick_answers::prefs::kQuickAnswersEnabled) { DCHECK(value.is_bool()); } else if (pref_name == - ash::quick_answers::prefs::kQuickAnswersDefinitionEnabled) { + quick_answers::prefs::kQuickAnswersDefinitionEnabled) { DCHECK(value.is_bool()); } else if (pref_name == - ash::quick_answers::prefs::kQuickAnswersTranslationEnabled) { + quick_answers::prefs::kQuickAnswersTranslationEnabled) { DCHECK(value.is_bool()); } else if (pref_name == - ash::quick_answers::prefs::kQuickAnswersUnitConverstionEnabled) { + quick_answers::prefs::kQuickAnswersUnitConverstionEnabled) { DCHECK(value.is_bool()); - } else if (pref_name == - ash::quick_answers::prefs::kQuickAnswersConsentStatus) { + } else if (pref_name == quick_answers::prefs::kQuickAnswersConsentStatus) { DCHECK(value.is_int()); } else { return "The pref " + pref_name + " is not whitelisted."; @@ -2292,6 +2291,22 @@ return RespondLater(); } +/////////////////////////////////////////////////////////////////////////////// +// AutotestPrivateCouldAllowCrostiniFunction +/////////////////////////////////////////////////////////////////////////////// + +AutotestPrivateCouldAllowCrostiniFunction:: + ~AutotestPrivateCouldAllowCrostiniFunction() = default; + +ExtensionFunction::ResponseAction +AutotestPrivateCouldAllowCrostiniFunction::Run() { + DVLOG(1) << "AutotestPrivateCouldAllowCrostiniFunction"; + + Profile* profile = Profile::FromBrowserContext(browser_context()); + return RespondNow(OneArgument( + base::Value(crostini::CrostiniFeatures::Get()->CouldBeAllowed(profile)))); +} + void AutotestPrivateImportCrostiniFunction::CrostiniImported( crostini::CrostiniResult result) { if (result == crostini::CrostiniResult::SUCCESS) {
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h index c795205..e750ffa0 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
@@ -466,6 +466,16 @@ void CrostiniImported(crostini::CrostiniResult); }; +class AutotestPrivateCouldAllowCrostiniFunction : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("autotestPrivate.couldAllowCrostini", + AUTOTESTPRIVATE_COULDALLOWCROSTINI) + + private: + ~AutotestPrivateCouldAllowCrostiniFunction() override; + ResponseAction Run() override; +}; + class AutotestPrivateSetPluginVMPolicyFunction : public ExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("autotestPrivate.setPluginVMPolicy",
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc index 18e24b6..d42d8b31 100644 --- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc +++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
@@ -822,7 +822,7 @@ GetNotificationDisplayService()->Close( NotificationHandler::Type::TRANSIENT, kDeviceFailNotificationId); } - FALLTHROUGH; + [[fallthrough]]; case MOUNT_STATUS_NO_RESULT: if (event.status == file_manager_private::MOUNT_COMPLETED_STATUS_SUCCESS) {
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h index bf09e66d..5054800 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h +++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h
@@ -27,9 +27,6 @@ // Clipboard Plugin VM toast ID in warning mode. constexpr char kClipboardWarnPluginVmToastId[] = "clipboard_dlp_warn_plugin_vm"; -// The duration of the clipboard toast/bubble shown on blocked paste. -constexpr int kClipboardDlpToastDurationMs = 2500; - // The duration of the clipboard bubble shown on blocked paste. constexpr int kClipboardDlpBlockDurationMs = 6000;
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc index bac55df15..636ce14 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -270,7 +270,8 @@ void DlpClipboardNotifier::ShowToast(const std::string& id, const std::u16string& text) const { ash::ToastData toast( - id, text, kClipboardDlpToastDurationMs, + id, text, ash::ToastData::kDefaultToastDurationMs, + /*visible_on_lock_screen=*/false, l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_BLOCK_TOAST_BUTTON)); toast.is_managed = true; toast.dismiss_callback = base::BindRepeating(&OnToastClicked);
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_utils.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_utils.cc index 3554a28f1..aa56de63 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_utils.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_utils.cc
@@ -148,7 +148,7 @@ case ::printing::CupsJob::CANCELED: print_job->set_error_code( PrinterErrorCodeFromPrinterStatusReasons(printer_status)); - FALLTHROUGH; + [[fallthrough]]; default: print_job->set_state(ConvertState(job.state)); break;
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java index abab6ea..eed2a085 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java
@@ -21,6 +21,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.IntentUtils; import org.chromium.base.Log; @@ -62,6 +63,8 @@ "org.chromium.chrome.browser.price_tracking.DESTINATION_URL"; static final String EXTRA_ACTION_ID = "org.chromium.chrome.browser.price_tracking.ACTION_ID"; static final String EXTRA_OFFER_ID = "org.chromium.chrome.browser.price_tracking.OFFER_ID"; + static final String EXTRA_PRODUCT_CLUSTER_ID = + "org.chromium.chrome.browser.price_tracking.PRODUCT_CLUSTER_ID"; private static NotificationManagerProxy sNotificationManagerForTesting; @@ -76,6 +79,7 @@ String destinationUrl = IntentUtils.safeGetStringExtra(intent, EXTRA_DESTINATION_URL); String actionId = IntentUtils.safeGetStringExtra(intent, EXTRA_ACTION_ID); String offerId = IntentUtils.safeGetStringExtra(intent, EXTRA_OFFER_ID); + String clusterId = IntentUtils.safeGetStringExtra(intent, EXTRA_PRODUCT_CLUSTER_ID); if (TextUtils.isEmpty(offerId)) { Log.e(TAG, "No offer id is provided when handling turn off alert action."); @@ -90,7 +94,7 @@ assert ACTION_ID_TURN_OFF_ALERT.equals(actionId) : "Currently only turn off alert action uses this activity."; priceDropNotificationManager.onNotificationActionClicked( - actionId, destinationUrl, offerId, /*recordMetrics=*/false); + actionId, destinationUrl, offerId, clusterId, /*recordMetrics=*/false); // Finish immediately. Could be better to have a callback from shopping backend. finish(); }); @@ -189,33 +193,43 @@ * @param actionId the id used to identify certain action. * @param url of the tab which triggered the notification. * @param offerId the id of the offer associated with this notification. + * @param clusterId The id of the cluster associated with the product notification. * @param recordMetrics Whether to record metrics using {@link NotificationUmaTracker}. Only * Chime notification code path should set this to true. */ - public void onNotificationActionClicked( - String actionId, String url, @Nullable String offerId, boolean recordMetrics) { + public void onNotificationActionClicked(String actionId, String url, @Nullable String offerId, + @Nullable String clusterId, boolean recordMetrics) { if (actionId.equals(ACTION_ID_VISIT_SITE) && recordMetrics) { NotificationUmaTracker.getInstance().onNotificationActionClick( NotificationUmaTracker.ActionType.PRICE_DROP_VISIT_SITE, NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS, NotificationIntentInterceptor.INVALID_CREATE_TIME); } else if (actionId.equals(ACTION_ID_TURN_OFF_ALERT)) { - if (offerId == null) return; + if (offerId == null && clusterId == null) return; SubscriptionsManagerImpl subscriptionsManager = (new CommerceSubscriptionsServiceFactory()) .getForLastUsedProfile() .getSubscriptionsManager(); - subscriptionsManager.unsubscribe( - new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId, - SubscriptionManagementType.CHROME_MANAGED, TrackingIdType.OFFER_ID), - (status) -> { - assert status - == SubscriptionsManager.StatusCode.OK - : "Failed to remove subscriptions."; - Log.e(TAG, - String.format(Locale.US, - "Failed to remove subscriptions. Status: %d", status)); - }); + Callback<Integer> callback = (status) -> { + assert status + == SubscriptionsManager.StatusCode.OK : "Failed to remove subscriptions."; + Log.e(TAG, + String.format( + Locale.US, "Failed to remove subscriptions. Status: %d", status)); + }; + if (offerId != null) { + subscriptionsManager.unsubscribe( + new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId, + SubscriptionManagementType.CHROME_MANAGED, TrackingIdType.OFFER_ID), + callback); + } + if (clusterId != null) { + subscriptionsManager.unsubscribe( + new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, clusterId, + SubscriptionManagementType.USER_MANAGED, + TrackingIdType.PRODUCT_CLUSTER_ID), + callback); + } if (recordMetrics) { NotificationUmaTracker.getInstance().onNotificationActionClick( NotificationUmaTracker.ActionType.PRICE_DROP_TURN_OFF_ALERT, @@ -250,14 +264,17 @@ * @param actionId the id used to identify certain action. * @param url of the tab which triggered the notification. * @param offerId The offer id of the product. + * @param clusterId The cluster id of the product. */ - public Intent getNotificationActionClickIntent(String actionId, String url, String offerId) { + public Intent getNotificationActionClickIntent( + String actionId, String url, String offerId, String clusterId) { if (ACTION_ID_VISIT_SITE.equals(actionId)) return getNotificationClickIntent(url); if (ACTION_ID_TURN_OFF_ALERT.equals(actionId)) { Intent intent = new Intent(mContext, TrampolineActivity.class); intent.putExtra(EXTRA_DESTINATION_URL, url); intent.putExtra(EXTRA_ACTION_ID, actionId); intent.putExtra(EXTRA_OFFER_ID, offerId); + intent.putExtra(EXTRA_PRODUCT_CLUSTER_ID, clusterId); return intent; } return null;
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java index 2ff303b..ac5b8fd 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java
@@ -42,12 +42,14 @@ static class NotificationData { public NotificationData(CharSequence title, CharSequence text, String iconUrl, - String destinationUrl, String offerId, List<ActionData> actions) { + String destinationUrl, String offerId, String productClusterId, + List<ActionData> actions) { this.title = title; this.text = text; this.iconUrl = iconUrl; this.destinationUrl = destinationUrl; this.offerId = offerId; + this.productClusterId = productClusterId; this.actions = actions; } @@ -74,6 +76,10 @@ */ public final String offerId; /** + * Associated cluster ID. + */ + public final String productClusterId; + /** * A list of button actions. */ public final List<ActionData> actions; @@ -170,8 +176,9 @@ PriceTrackingNotificationConfig.getNotificationTimeoutMs()); if (notificationData.actions != null) { for (ActionData action : notificationData.actions) { - PendingIntentProvider actionClickIntentProvider = createClickIntent( - action.actionId, notificationData.destinationUrl, notificationData.offerId); + PendingIntentProvider actionClickIntentProvider = + createClickIntent(action.actionId, notificationData.destinationUrl, + notificationData.offerId, notificationData.productClusterId); notificationBuilder.addAction(0, action.text, actionClickIntentProvider, actionIdToUmaActionType(action.actionId)); } @@ -197,9 +204,10 @@ mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } - private PendingIntentProvider createClickIntent(String actionId, String url, String offerId) { + private PendingIntentProvider createClickIntent( + String actionId, String url, String offerId, String clusterId) { Intent intent = mPriceDropNotificationManager.getNotificationActionClickIntent( - actionId, url, offerId); + actionId, url, offerId, clusterId); return PendingIntentProvider.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); }
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java index 3ddba7d..1565b881 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java
@@ -111,11 +111,12 @@ // Use UnsignedLongs to convert OfferId to avoid overflow. String offerId = UnsignedLongs.toString(priceDropPayload.getOfferId()); + String clusterId = UnsignedLongs.toString(priceDropPayload.getProductClusterId()); ChromeMessage chromeMessage = chromeNotification.getChromeMessage(); PriceDropNotifier.NotificationData notificationData = new PriceDropNotifier.NotificationData(title, text, chromeMessage.hasIconImageUrl() ? chromeMessage.getIconImageUrl() : null, - priceDropPayload.getDestinationUrl(), offerId, + priceDropPayload.getDestinationUrl(), offerId, clusterId, parseActions(chromeNotification)); mNotifier.showNotification(notificationData); }
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java index e3db2da..2c20ad02 100644 --- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java +++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java
@@ -77,6 +77,7 @@ private static final String ACTION_ID_TURN_OFF_ALERT = "turn_off_alert"; private static final String TEST_URL = "www.test.com"; private static final String OFFER_ID = "offer_id"; + private static final String PRODUCT_CLUSTER_ID = "cluster_id"; private MockNotificationManagerProxy mMockNotificationManager; private PriceDropNotificationManager mPriceDropNotificationManager; @@ -220,12 +221,15 @@ @MediumTest public void testGetNotificationActionClickIntent() { verifyClickIntent(mPriceDropNotificationManager.getNotificationActionClickIntent( - ACTION_ID_VISIT_SITE, TEST_URL, OFFER_ID)); + ACTION_ID_VISIT_SITE, TEST_URL, OFFER_ID, PRODUCT_CLUSTER_ID)); Intent turnOffAlertIntent = mPriceDropNotificationManager.getNotificationActionClickIntent( - ACTION_ID_TURN_OFF_ALERT, TEST_URL, OFFER_ID); + ACTION_ID_TURN_OFF_ALERT, TEST_URL, OFFER_ID, PRODUCT_CLUSTER_ID); assertNotNull(turnOffAlertIntent); assertEquals(PriceDropNotificationManager.TrampolineActivity.class.getName(), turnOffAlertIntent.getComponent().getClassName()); + assertEquals(PRODUCT_CLUSTER_ID, + IntentUtils.safeGetStringExtra( + turnOffAlertIntent, PriceDropNotificationManager.EXTRA_PRODUCT_CLUSTER_ID)); assertEquals(OFFER_ID, IntentUtils.safeGetStringExtra( turnOffAlertIntent, PriceDropNotificationManager.EXTRA_OFFER_ID)); @@ -252,12 +256,12 @@ SubscriptionManagementType.CHROME_MANAGED, TrackingIdType.OFFER_ID); mPriceDropNotificationManager.onNotificationActionClicked( - ACTION_ID_TURN_OFF_ALERT, TEST_URL, null, false); + ACTION_ID_TURN_OFF_ALERT, TEST_URL, null, null, false); verify(mMockSubscriptionsManager, times(0)) .unsubscribe(eq(commerceSubscription), any(Callback.class)); mPriceDropNotificationManager.onNotificationActionClicked( - ACTION_ID_TURN_OFF_ALERT, TEST_URL, offerId, false); + ACTION_ID_TURN_OFF_ALERT, TEST_URL, offerId, null, false); verify(mMockSubscriptionsManager, times(1)) .unsubscribe(eq(commerceSubscription), any(Callback.class)); }
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java index e3dcb517..fc7d5d10 100644 --- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java +++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java
@@ -68,6 +68,7 @@ private static final String ICON_URL = "http://www.example.com/icon"; private static final String DESTINATION_URL = "http://www.example.com/destination"; private static final String OFFER_ID = "offer_id"; + private static final String PRODUCT_CLUSTER_ID = "cluster_id"; private static final String ACTION_TEXT_0 = "action_text_0"; private static final String ACTION_TEXT_1 = "action_text_1"; @@ -166,8 +167,8 @@ } private void showNotification(List<ActionData> actionDataList) { - PriceDropNotifier.NotificationData data = new NotificationData( - TITLE, TEXT, ICON_URL, DESTINATION_URL, OFFER_ID, actionDataList); + PriceDropNotifier.NotificationData data = new NotificationData(TITLE, TEXT, ICON_URL, + DESTINATION_URL, OFFER_ID, PRODUCT_CLUSTER_ID, actionDataList); mPriceDropNotifier.showNotification(data); } @@ -205,7 +206,7 @@ @Test public void testShowNotificationNoIconURL() { PriceDropNotifier.NotificationData data = new NotificationData( - TITLE, TEXT, /*iconUrl=*/null, DESTINATION_URL, OFFER_ID, null); + TITLE, TEXT, /*iconUrl=*/null, DESTINATION_URL, OFFER_ID, PRODUCT_CLUSTER_ID, null); mPriceDropNotifier.showNotification(data); verify(mNotificationBuilder, times(0)).setLargeIcon(any()); verify(mNotificationBuilder, times(0)).setBigPictureStyle(any(), any());
diff --git a/chrome/browser/commerce/price_tracking/proto/notifications.proto b/chrome/browser/commerce/price_tracking/proto/notifications.proto index a8cf97d..475c6d0c 100644 --- a/chrome/browser/commerce/price_tracking/proto/notifications.proto +++ b/chrome/browser/commerce/price_tracking/proto/notifications.proto
@@ -58,4 +58,5 @@ optional string destination_url = 3; optional commerce.ProductPrice current_price = 4; optional commerce.ProductPrice previous_price = 5; + optional uint64 product_cluster_id = 6; }
diff --git a/chrome/browser/commerce/shopping_list/shopping_data_provider.cc b/chrome/browser/commerce/shopping_list/shopping_data_provider.cc index 8fedd72..4ccc15f 100644 --- a/chrome/browser/commerce/shopping_list/shopping_data_provider.cc +++ b/chrome/browser/commerce/shopping_list/shopping_data_provider.cc
@@ -241,6 +241,9 @@ if (data.has_image_url()) shopping_specifics->set_image_url(data.image_url()); + if (data.has_offer_id()) + shopping_specifics->set_offer_id(data.offer_id()); + if (data.has_product_cluster_id()) shopping_specifics->set_product_cluster_id(data.product_cluster_id());
diff --git a/chrome/browser/commerce/shopping_list/shopping_data_provider_unittest.cc b/chrome/browser/commerce/shopping_list/shopping_data_provider_unittest.cc index 5d9e07c..efda0f0 100644 --- a/chrome/browser/commerce/shopping_list/shopping_data_provider_unittest.cc +++ b/chrome/browser/commerce/shopping_list/shopping_data_provider_unittest.cc
@@ -19,6 +19,7 @@ const char kMainTitle[] = "Title"; const char kFallbackTitle[] = "Fallback Title"; +const uint64_t kOfferId = 12345; const uint64_t kClusterId = 67890; TEST(ShoppingDataProviderTest, TestDataMergeWithLeadImage) { @@ -84,6 +85,7 @@ product.set_product_cluster_id(kClusterId); product.mutable_current_price()->set_amount_micros(100L); product.mutable_current_price()->set_currency_code(kCurrencyCode); + product.set_offer_id(kOfferId); power_bookmarks::ShoppingSpecifics out_specifics; @@ -94,6 +96,7 @@ EXPECT_EQ(kClusterId, out_specifics.product_cluster_id()); EXPECT_EQ(100L, out_specifics.current_price().amount_micros()); EXPECT_EQ(kCurrencyCode, out_specifics.current_price().currency_code()); + EXPECT_EQ(kOfferId, out_specifics.offer_id()); } TEST(ShoppingDataProviderTest, TestPopulateShoppingSpecificsMissingData) {
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java index ad2a9ea..4cd08e236 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java
@@ -82,16 +82,16 @@ } @TrackingIdType - String getTrackingIdType() { + public String getTrackingIdType() { return mTrackingIdType; } - String getTrackingId() { + public String getTrackingId() { return mTrackingId; } @SubscriptionManagementType - String getManagementType() { + public String getManagementType() { return mManagementType; }
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java index eb978ad..9065ec7 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java
@@ -26,6 +26,23 @@ int INVALID_ARGUMENT = 4; } + /** An observer for notification about a product be tracked or untracked. */ + interface SubscriptionObserver { + /** + * A notification that a user has subscribed to product updated. + * + * @param subscriptions The list of subscriptions being added. + */ + void onSubscribe(List<CommerceSubscription> subscriptions); + + /** + * A notification that a user has unsubscribed to product updated. + * + * @param subscriptions The list of subscriptions being removed. + */ + void onUnsubscribe(List<CommerceSubscription> subscriptions); + } + /** * Creates a new subscription on the server if needed. * @param subscription The {@link CommerceSubscription} to add. @@ -63,4 +80,18 @@ * @param callback The callback to receive the result. */ void isSubscribed(CommerceSubscription subscription, Callback<Boolean> callback); + + /** + * Add an observer of subscribe and unsubscribe events. + * + * @param observer The observer to add. + */ + void addObserver(SubscriptionObserver observer); + + /** + * Remove an observer of subscribe and unsubscribe events. + * + * @param observer The observer to remove. + */ + void removeObserver(SubscriptionObserver observer); }
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java index 5cee50d..e3ee81f 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java
@@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; +import org.chromium.base.ObserverList; import org.chromium.chrome.browser.profiles.Profile; import java.lang.annotation.Retention; @@ -37,6 +38,7 @@ private static List<CommerceSubscription> sRemoteSubscriptionsForTesting; private boolean mCanHandleRequests; private Queue<DeferredSubscriptionOperation> mDeferredTasks; + private final ObserverList<SubscriptionObserver> mObservers; private static class DeferredSubscriptionOperation { private final @Operation int mOperation; @@ -76,6 +78,17 @@ mDeferredTasks = new LinkedList<>(); mCanHandleRequests = false; initTypes(this::onInitComplete); + mObservers = new ObserverList<>(); + } + + @Override + public void addObserver(SubscriptionObserver observer) { + mObservers.addObserver(observer); + } + + @Override + public void removeObserver(SubscriptionObserver observer) { + mObservers.removeObserver(observer); } /** @@ -107,25 +120,37 @@ callback.onResult(SubscriptionsManager.StatusCode.OK); return; } + + // Wrap the callback in one that allows us to trigger the observers. + Callback<Integer> wrappedCallback = (status) -> { + if (status == StatusCode.OK) { + for (SubscriptionObserver o : mObservers) { + o.onSubscribe(subscriptions); + } + } + callback.onResult(status); + }; + String type = subscriptions.get(0).getType(); if (!isSubscriptionTypeSupported(type)) { - callback.onResult(SubscriptionsManager.StatusCode.INVALID_ARGUMENT); + wrappedCallback.onResult(SubscriptionsManager.StatusCode.INVALID_ARGUMENT); return; } if (!mCanHandleRequests) { mDeferredTasks.add(new DeferredSubscriptionOperation( - Operation.SUBSCRIBE, subscriptions, callback)); + Operation.SUBSCRIBE, subscriptions, wrappedCallback)); return; } getUniqueSubscriptions(subscriptions, (list) -> { if (list.size() == 0) { - callback.onResult(SubscriptionsManager.StatusCode.OK); + wrappedCallback.onResult(SubscriptionsManager.StatusCode.OK); } else { mServiceProxy.create(list, (didSucceed) - -> handleUpdateSubscriptionsResponse(didSucceed, type, callback)); + -> handleUpdateSubscriptionsResponse( + didSucceed, type, wrappedCallback)); } }); } @@ -208,16 +233,26 @@ return; } + // Wrap the callback in one that allows us to trigger the observers. + Callback<Integer> wrappedCallback = (status) -> { + if (status == StatusCode.OK) { + for (SubscriptionObserver o : mObservers) { + o.onUnsubscribe(subscriptions); + } + } + callback.onResult(status); + }; + if (!mCanHandleRequests) { mDeferredTasks.add(new DeferredSubscriptionOperation( - Operation.UNSUBSCRIBE, subscriptions, callback)); + Operation.UNSUBSCRIBE, subscriptions, wrappedCallback)); return; } Map<String, CommerceSubscription> subscriptionsMap = getSubscriptionsMap(subscriptions); mStorage.loadWithPrefix(String.valueOf(type), localSubscriptions -> { if (localSubscriptions.size() == 0) { - callback.onResult(SubscriptionsManager.StatusCode.OK); + wrappedCallback.onResult(SubscriptionsManager.StatusCode.OK); return; } @@ -232,12 +267,14 @@ } if (subscriptionsToDelete.size() == 0) { - callback.onResult(SubscriptionsManager.StatusCode.OK); + wrappedCallback.onResult(SubscriptionsManager.StatusCode.OK); return; } mServiceProxy.delete(subscriptionsToDelete, - (didSucceed) -> handleUpdateSubscriptionsResponse(didSucceed, type, callback)); + (didSucceed) + -> handleUpdateSubscriptionsResponse( + didSucceed, type, wrappedCallback)); }); }
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index c6cce2f8..ef4c62b6 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -551,8 +551,7 @@ base::TerminationStatus status) override; void ReadyToCommitNavigation( content::NavigationHandle* navigation_handle) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; @@ -628,9 +627,8 @@ } void DevToolsUIBindings::FrontendWebContentsObserver:: - DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { - devtools_bindings_->DocumentOnLoadCompletedInMainFrame(); + DocumentOnLoadCompletedInPrimaryMainFrame() { + devtools_bindings_->DocumentOnLoadCompletedInPrimaryMainFrame(); } void DevToolsUIBindings::FrontendWebContentsObserver::DidFinishNavigation( @@ -653,6 +651,10 @@ return nullptr; } +std::string DevToolsUIBindings::GetTypeForMetrics() { + return "DevTools"; +} + DevToolsUIBindings::DevToolsUIBindings(content::WebContents* web_contents) : profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), android_bridge_(DevToolsAndroidBridge::Factory::GetForProfile(profile_)), @@ -1711,7 +1713,7 @@ content::DevToolsFrontendHost::SetupExtensionsAPI(frame, script); } -void DevToolsUIBindings::DocumentOnLoadCompletedInMainFrame() { +void DevToolsUIBindings::DocumentOnLoadCompletedInPrimaryMainFrame() { FrontendLoaded(); }
diff --git a/chrome/browser/devtools/devtools_ui_bindings.h b/chrome/browser/devtools/devtools_ui_bindings.h index 04fff069..2ec9c93 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.h +++ b/chrome/browser/devtools/devtools_ui_bindings.h
@@ -80,6 +80,8 @@ ~DevToolsUIBindings() override; + std::string GetTypeForMetrics() override; + content::WebContents* web_contents() { return web_contents_; } Profile* profile() { return profile_; } content::DevToolsAgentHost* agent_host() { return agent_host_.get(); } @@ -207,7 +209,7 @@ const base::Value& targets); void ReadyToCommitNavigation(content::NavigationHandle* navigation_handle); - void DocumentOnLoadCompletedInMainFrame(); + void DocumentOnLoadCompletedInPrimaryMainFrame(); void DidNavigateMainFrame(); void FrontendLoaded();
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h index 234299de..b6acaf1 100644 --- a/chrome/browser/devtools/devtools_window.h +++ b/chrome/browser/devtools/devtools_window.h
@@ -267,7 +267,7 @@ // - Toggle/Open: client call; // - Create; // - ScheduleShow: setup window to be functional, but not yet show; - // - DocumentOnLoadCompletedInMainFrame: frontend loaded; + // - DocumentOnLoadCompletedInPrimaryMainFrame: frontend loaded; // - SetIsDocked: frontend decided on docking state; // - OnLoadCompleted: ready to present frontend; // - Show: actually placing frontend WebContents to a Browser or docked place;
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc index 698c078fb..563460e5 100644 --- a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -209,8 +209,8 @@ EXPECT_EQ(nullptr, DevToolsWindow::FindDevToolsWindow(agent_host_.get())); } -// Failing consistently on mac builds crbug.com/1284536 -#if defined(OS_MAC) +// Flaky/failing on Linux/CrOS/Mac builds: crbug.com/1284536 +#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MAC) #define MAYBE_NoPendingUrlShownWhenAttachedToBrowserInitiatedFailedNavigation \ DISABLED_NoPendingUrlShownWhenAttachedToBrowserInitiatedFailedNavigation #else
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index d04a83d..d483835 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -65,6 +65,7 @@ #include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -5440,6 +5441,12 @@ actual_report.type()); EXPECT_EQ(safe_browsing::ClientDownloadResponse::UNCOMMON, actual_report.download_verdict()); + std::string actual_population_serialized; + actual_report.population().SerializeToString(&actual_population_serialized); + std::string expected_population_serialized; + safe_browsing::GetUserPopulationForProfile(browser()->profile()) + .SerializeToString(&expected_population_serialized); + EXPECT_EQ(expected_population_serialized, actual_population_serialized); EXPECT_EQ(download_url.spec(), actual_report.url()); EXPECT_TRUE(actual_report.did_proceed());
diff --git a/chrome/browser/download/download_danger_prompt.cc b/chrome/browser/download/download_danger_prompt.cc index 1c84918b..af0cae60 100644 --- a/chrome/browser/download/download_danger_prompt.cc +++ b/chrome/browser/download/download_danger_prompt.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_functions.h" #include "base/strings/stringprintf.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -95,6 +96,8 @@ report->set_download_verdict(download_verdict); report->set_url(download.GetURL().spec()); report->set_did_proceed(did_proceed); + *report->mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile); std::string token = safe_browsing::DownloadProtectionService::GetDownloadPingToken(&download); if (!token.empty())
diff --git a/chrome/browser/download/download_danger_prompt_browsertest.cc b/chrome/browser/download/download_danger_prompt_browsertest.cc index 19db377..37df0c8 100644 --- a/chrome/browser/download/download_danger_prompt_browsertest.cc +++ b/chrome/browser/download/download_danger_prompt_browsertest.cc
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "chrome/browser/download/download_danger_prompt.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/ui/browser.h" @@ -148,6 +149,8 @@ else expected_report.set_type( ClientSafeBrowsingReportRequest::DANGEROUS_DOWNLOAD_RECOVERY); + *expected_report.mutable_population() = + safe_browsing::GetUserPopulationForProfile(browser()->profile()); expected_report.set_download_verdict(download_verdict); expected_report.set_did_proceed(did_proceed); if (!token.empty())
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index d004235..c38db06 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/enterprise/connectors/common.h" #include "chrome/browser/enterprise/connectors/connectors_manager.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/download_protection/deep_scanning_request.h" #include "chrome/browser/safe_browsing/download_protection/download_feedback_service.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -726,6 +727,8 @@ safe_browsing::ClientDownloadResponse::UNCOMMON); report->set_url(GetURL().spec()); report->set_did_proceed(true); + *report->mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); std::string token = safe_browsing::DownloadProtectionService::GetDownloadPingToken( download_);
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc index 6757f8b..6a70d93 100644 --- a/chrome/browser/download/download_request_limiter_unittest.cc +++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -160,8 +160,8 @@ } void LoadCompleted() { - mock_permission_prompt_factory_->DocumentOnLoadCompletedInMainFrame( - main_rfh()); + mock_permission_prompt_factory_ + ->DocumentOnLoadCompletedInPrimaryMainFrame(); } int AskAllowCount() { return mock_permission_prompt_factory_->show_count(); }
diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc index 6fb0f361..01bdb48 100644 --- a/chrome/browser/engagement/important_sites_util.cc +++ b/chrome/browser/engagement/important_sites_util.cc
@@ -102,9 +102,8 @@ }; void RecordIgnore(base::DictionaryValue* dict) { - int times_ignored = 0; - dict->GetInteger(kNumTimesIgnoredName, ×_ignored); - dict->SetInteger(kNumTimesIgnoredName, ++times_ignored); + int times_ignored = dict->FindIntKey(kNumTimesIgnoredName).value_or(0); + dict->SetIntKey(kNumTimesIgnoredName, ++times_ignored); dict->SetDoubleKey(kTimeLastIgnored, base::Time::Now().ToDoubleT()); }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc index d1c8090..5687457 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
@@ -561,7 +561,7 @@ switch (dialog_state_) { case State::SUCCESS: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case State::PENDING: text_id = IDS_DEEP_SCANNING_DIALOG_CANCEL_UPLOAD_BUTTON; break;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h index 2dd833bb..c6709ce 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h
@@ -15,17 +15,19 @@ // implementation for each platform and also for tests. class KeyNetworkDelegate { public: + using HttpResponseCode = int; + virtual ~KeyNetworkDelegate() = default; // Sends `body`, which is a serialized DeviceManagementRequest, to DM // server at `url`. `dm_token` authn the local machine. Only the // BrowserPublicKeyUploadRequest member is expected to be initialized. // - // The return value is a string that can be parsed into - // DeviceManagementResponse. - virtual std::string SendPublicKeyToDmServerSync(const GURL& url, - const std::string& dm_token, - const std::string& body) = 0; + // The return value is the upload response's HTTP status code. + virtual HttpResponseCode SendPublicKeyToDmServerSync( + const GURL& url, + const std::string& dm_token, + const std::string& body) = 0; }; } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h index 41eb8812..b1d6acef 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h
@@ -19,7 +19,7 @@ MockKeyNetworkDelegate(); ~MockKeyNetworkDelegate() override; - MOCK_METHOD(std::string, + MOCK_METHOD(HttpResponseCode, SendPublicKeyToDmServerSync, (const GURL&, const std::string&, const std::string&), (override));
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc index 8f300d6..8076b12 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
@@ -4,6 +4,11 @@ #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h" +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" #include "base/callback_helpers.h" #include "base/containers/flat_map.h" #include "base/memory/scoped_refptr.h" @@ -17,10 +22,11 @@ WinKeyNetworkDelegate::WinKeyNetworkDelegate() = default; WinKeyNetworkDelegate::~WinKeyNetworkDelegate() = default; -std::string WinKeyNetworkDelegate::SendPublicKeyToDmServerSync( - const GURL& url, - const std::string& dm_token, - const std::string& body) { +KeyNetworkDelegate::HttpResponseCode +WinKeyNetworkDelegate::SendPublicKeyToDmServerSync(const GURL& url, + const std::string& dm_token, + const std::string& body) { + DCHECK(!response_code_.has_value()); base::flat_map<std::string, std::string> headers; headers.emplace("Authorization", "GoogleDMToken token=" + dm_token); @@ -34,11 +40,27 @@ proxy_config); base::RunLoop run_loop; - fetcher->PostRequest(url, body, std::string(), headers, base::DoNothing(), - base::DoNothing(), run_loop.QuitClosure()); + auto completion_callback = + base::BindOnce(&WinKeyNetworkDelegate::FetchCompleted, + weak_factory_.GetWeakPtr()) + .Then(run_loop.QuitClosure()); + + fetcher->PostRequest( + url, body, std::string(), headers, + /*fetch_started_callback=*/base::DoNothing(), + /*fetch_progress_callback=*/base::DoNothing(), + /*fetch_completed_callback=*/std::move(completion_callback)); + run_loop.Run(); - return fetcher->GetResponseBody(); + // Clean-up the state for future calls before returning the code. + auto response_code = response_code_.value_or(0); + response_code_.reset(); + return response_code; +} + +void WinKeyNetworkDelegate::FetchCompleted(int response_code) { + response_code_ = response_code; } } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h index 12524d6..a66d3c0 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_WIN_KEY_NETWORK_DELEGATE_H_ #define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_WIN_KEY_NETWORK_DELEGATE_H_ +#include "base/memory/weak_ptr.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace enterprise_connectors { @@ -16,9 +18,20 @@ ~WinKeyNetworkDelegate() override; // KeyNetworkDelegate: - std::string SendPublicKeyToDmServerSync(const GURL& url, - const std::string& dm_token, - const std::string& body) override; + HttpResponseCode SendPublicKeyToDmServerSync( + const GURL& url, + const std::string& dm_token, + const std::string& body) override; + + private: + // Invoked when the network fetch has completed. `response_code` represents + // the HTTP status code for the response. + void FetchCompleted(int response_code); + + // Used to capture the `response_code` received via FetchCompleted. + absl::optional<int> response_code_; + + base::WeakPtrFactory<WinKeyNetworkDelegate> weak_factory_{this}; }; } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc index 24c7977..1db65c2 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h" #include "base/check.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_functions.h" #include "base/threading/platform_thread.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h" @@ -38,17 +38,30 @@ void RecordRotationStatus(const std::string& nonce, KeyRotationManager::RotationStatus status) { if (nonce.empty()) { - UMA_HISTOGRAM_ENUMERATION( + base::UmaHistogramEnumeration( "Enterprise.DeviceTrust.RotateSigningKey.NoNonce.Status", status); } else { - UMA_HISTOGRAM_ENUMERATION( + base::UmaHistogramEnumeration( "Enterprise.DeviceTrust.RotateSigningKey.WithNonce.Status", status); } } void RecordRotationTryCount(int count) { - UMA_HISTOGRAM_CUSTOM_COUNTS("Enterprise.DeviceTrust.RotateSigningKey.Tries", - count, 1, kMaxRetryCount, kMaxRetryCount + 1); + base::UmaHistogramCustomCounts( + "Enterprise.DeviceTrust.RotateSigningKey.Tries", count, 1, kMaxRetryCount, + kMaxRetryCount + 1); +} + +void RecordUploadCode(const std::string& nonce, int status_code) { + if (nonce.empty()) { + base::UmaHistogramSparse( + "Enterprise.DeviceTrust.RotateSigningKey.NoNonce.UploadCode", + status_code); + } else { + base::UmaHistogramSparse( + "Enterprise.DeviceTrust.RotateSigningKey.WithNonce.UploadCode", + status_code); + } } } // namespace @@ -136,14 +149,24 @@ // Any attempt to reuse a nonce will result in an INVALID_SIGNATURE error // being returned by the server. This will cause the loop to break early. - std::string response_str = network_delegate_->SendPublicKeyToDmServerSync( - dm_server_url, dm_token, request_str); - enterprise_management::DeviceManagementResponse response; - rc = (!response_str.empty() && response.ParseFromString(response_str) && - response.has_browser_public_key_upload_response() && - response.browser_public_key_upload_response().has_response_code()) - ? response.browser_public_key_upload_response().response_code() - : BPKUP::UNDEFINED; + KeyNetworkDelegate::HttpResponseCode response_code = + network_delegate_->SendPublicKeyToDmServerSync(dm_server_url, dm_token, + request_str); + + RecordUploadCode(nonce, response_code); + + int status_leading_digit = response_code / 100; + if (status_leading_digit == 2) { + // 2xx response codes are treated as success. + rc = BPKUP::SUCCESS; + } else if (status_leading_digit == 4) { + // 4xx response codes are treated as hard fails (no retries). + rc = BPKUP::INVALID_SIGNATURE; + } else { + // The rest are treated as retriable errors. + rc = BPKUP::UNDEFINED; + } + boe.InformOfRequest(rc == BPKUP::SUCCESS); }
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc index 856c0e9a..e5952651 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
@@ -34,20 +34,16 @@ using test::MockKeyNetworkDelegate; using test::MockKeyPersistenceDelegate; +using HttpResponseCode = KeyNetworkDelegate::HttpResponseCode; namespace { const char kDmServerUrl[] = "dmserver.example.com"; const char kDmToken[] = "dm_token"; -std::string CreateResponse(BPKUP::ResponseCode response_code = BPKUP::SUCCESS) { - enterprise_management::DeviceManagementResponse response; - response.mutable_browser_public_key_upload_response()->set_response_code( - response_code); - std::string response_str; - response.SerializeToString(&response_str); - return response_str; -} +constexpr HttpResponseCode kSuccessCode = 200; +constexpr HttpResponseCode kHardFailureCode = 400; +constexpr HttpResponseCode kTransientFailureCode = 500; KeyPersistenceDelegate::KeyInfo CreateEmptyKeyPair() { return {BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()}; @@ -76,6 +72,12 @@ : "Enterprise.DeviceTrust.RotateSigningKey.WithNonce.Status"; } + const char* http_code_histogram_name() const { + return use_nonce() + ? "Enterprise.DeviceTrust.RotateSigningKey.WithNonce.UploadCode" + : "Enterprise.DeviceTrust.RotateSigningKey.NoNonce.UploadCode"; + } + test::ScopedKeyPersistenceDelegateFactory scoped_factory_; }; @@ -106,7 +108,7 @@ Invoke([&captured_body](const GURL& url, const std::string& dm_token, const std::string& body) { captured_body = body; - return CreateResponse(); + return kSuccessCode; })); auto manager = KeyRotationManager::CreateForTesting( @@ -130,6 +132,8 @@ histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); histogram_tester.ExpectUniqueSample( "Enterprise.DeviceTrust.RotateSigningKey.Tries", 1, 1); + histogram_tester.ExpectUniqueSample(http_code_histogram_name(), kSuccessCode, + 1); } // Tests a success key rotation flow when TPM key provider is available, but no @@ -153,7 +157,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse())); + .WillOnce(Return(kSuccessCode)); auto manager = KeyRotationManager::CreateForTesting( std::move(mock_network_delegate), std::move(mock_persistence_delegate)); @@ -186,7 +190,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse())); + .WillOnce(Return(kSuccessCode)); auto manager = KeyRotationManager::CreateForTesting( std::move(mock_network_delegate), std::move(mock_persistence_delegate)); @@ -227,7 +231,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse(BPKUP::INVALID_SIGNATURE))); + .WillOnce(Return(kHardFailureCode)); EXPECT_CALL( *mock_persistence_delegate, @@ -247,6 +251,8 @@ histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); histogram_tester.ExpectUniqueSample( "Enterprise.DeviceTrust.RotateSigningKey.Tries", 1, 1); + histogram_tester.ExpectUniqueSample(http_code_histogram_name(), + kHardFailureCode, 1); } // Tests a failed key rotation flow when a TPM key provider is available @@ -277,7 +283,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillRepeatedly(Return(CreateResponse(BPKUP::UNDEFINED))); + .WillRepeatedly(Return(kTransientFailureCode)); EXPECT_CALL( *mock_persistence_delegate, @@ -299,6 +305,8 @@ histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); histogram_tester.ExpectUniqueSample( "Enterprise.DeviceTrust.RotateSigningKey.Tries", 10, 1); + histogram_tester.ExpectUniqueSample(http_code_histogram_name(), + kTransientFailureCode, 10); } // Tests a failed key rotation flow when a TPM key provider is available @@ -327,8 +335,8 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse(BPKUP::UNDEFINED))) - .WillOnce(Return(CreateResponse(BPKUP::INVALID_SIGNATURE))); + .WillOnce(Return(kTransientFailureCode)) + .WillOnce(Return(kHardFailureCode)); EXPECT_CALL( *mock_persistence_delegate, @@ -350,6 +358,12 @@ histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); histogram_tester.ExpectUniqueSample( "Enterprise.DeviceTrust.RotateSigningKey.Tries", 2, 1); + + histogram_tester.ExpectTotalCount(http_code_histogram_name(), 2); + histogram_tester.ExpectBucketCount(http_code_histogram_name(), + kTransientFailureCode, 1); + histogram_tester.ExpectBucketCount(http_code_histogram_name(), + kHardFailureCode, 1); } // Tests a success key rotation flow when a TPM key provider is not available @@ -369,7 +383,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse())); + .WillOnce(Return(kSuccessCode)); auto manager = KeyRotationManager::CreateForTesting( std::move(mock_network_delegate), std::move(mock_persistence_delegate)); @@ -440,8 +454,8 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse(BPKUP::UNDEFINED))) - .WillOnce(Return(CreateResponse(BPKUP::SUCCESS))); + .WillOnce(Return(kTransientFailureCode)) + .WillOnce(Return(kSuccessCode)); auto manager = KeyRotationManager::CreateForTesting( std::move(mock_network_delegate), std::move(mock_persistence_delegate)); @@ -479,7 +493,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse(BPKUP::INVALID_SIGNATURE))); + .WillOnce(Return(kHardFailureCode)); auto manager = KeyRotationManager::CreateForTesting( std::move(mock_network_delegate), std::move(mock_persistence_delegate)); @@ -522,8 +536,8 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillOnce(Return(CreateResponse(BPKUP::UNDEFINED))) - .WillOnce(Return(CreateResponse(BPKUP::INVALID_SIGNATURE))); + .WillOnce(Return(kTransientFailureCode)) + .WillOnce(Return(kHardFailureCode)); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, original_key_wrapped)) @@ -568,7 +582,7 @@ auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) - .WillRepeatedly(Return(CreateResponse(BPKUP::UNDEFINED))); + .WillRepeatedly(Return(kTransientFailureCode)); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, original_key_wrapped))
diff --git a/chrome/browser/enterprise/connectors/file_system/box_uploader.cc b/chrome/browser/enterprise/connectors/file_system/box_uploader.cc index 318698bb..bd21c2d 100644 --- a/chrome/browser/enterprise/connectors/file_system/box_uploader.cc +++ b/chrome/browser/enterprise/connectors/file_system/box_uploader.cc
@@ -367,7 +367,8 @@ } DLOG(WARNING) << "Box upload failed for file " << target_file_name_; LogUniquifierCountToUma(); - FALLTHROUGH; // Also OnOnApiCallFlowFailure() to surface this to user. + [[fallthrough]]; // Also OnOnApiCallFlowFailure() to surface this to + // user. default: // Unexpected error. Notify failure to download thread. OnApiCallFlowFailure(response);
diff --git a/chrome/browser/enterprise/remote_commands/cbcm_remote_commands_factory.cc b/chrome/browser/enterprise/remote_commands/cbcm_remote_commands_factory.cc index e47f103..496d5c05 100644 --- a/chrome/browser/enterprise/remote_commands/cbcm_remote_commands_factory.cc +++ b/chrome/browser/enterprise/remote_commands/cbcm_remote_commands_factory.cc
@@ -5,25 +5,45 @@ #include "chrome/browser/enterprise/remote_commands/cbcm_remote_commands_factory.h" #include "base/notreached.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/enterprise/remote_commands/clear_browsing_data_job.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/policy/core/common/remote_commands/remote_command_job.h" +#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC) +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h" +#include "chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.h" +#include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h" +#include "components/enterprise/browser/device_trust/device_trust_key_manager.h" +#endif // defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC) + namespace enterprise_commands { std::unique_ptr<policy::RemoteCommandJob> CBCMRemoteCommandsFactory::BuildJobForType( enterprise_management::RemoteCommand_Type type, policy::RemoteCommandsService* service) { - switch (type) { - case enterprise_management::RemoteCommand_Type_BROWSER_CLEAR_BROWSING_DATA: - return std::make_unique<ClearBrowsingDataJob>( - g_browser_process->profile_manager()); - default: - NOTREACHED() << "Received an unsupported remote command type: " << type; - return nullptr; + if (type == + enterprise_management::RemoteCommand_Type_BROWSER_CLEAR_BROWSING_DATA) { + return std::make_unique<ClearBrowsingDataJob>( + g_browser_process->profile_manager()); } + +#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC) + if (enterprise_connectors::IsDeviceTrustConnectorFeatureEnabled() && + type == enterprise_management:: + RemoteCommand_Type_BROWSER_ROTATE_ATTESTATION_CREDENTIAL) { + return std::make_unique<RotateAttestationCredentialJob>( + g_browser_process->browser_policy_connector() + ->chrome_browser_cloud_management_controller() + ->GetDeviceTrustKeyManager()); + } +#endif // defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC) + + NOTREACHED() << "Received an unsupported remote command type: " << type; + return nullptr; } } // namespace enterprise_commands
diff --git a/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.cc b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.cc new file mode 100644 index 0000000..a4964bf5 --- /dev/null +++ b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.cc
@@ -0,0 +1,109 @@ +// 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/enterprise/remote_commands/rotate_attestation_credential_job.h" + +#include "base/bind.h" +#include "base/check.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/values.h" +#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command.h" + +namespace enterprise_commands { + +using DeviceTrustKeyManager = enterprise_connectors::DeviceTrustKeyManager; +using KeyRotationResult = DeviceTrustKeyManager::KeyRotationResult; + +namespace { + +const char kNoncePathField[] = "nonce"; +const char kResultFieldName[] = "result"; + +std::string ResultToString(KeyRotationResult result) { + switch (result) { + case KeyRotationResult::SUCCESS: + return "success"; + case KeyRotationResult::FAILURE: + return "failure"; + case KeyRotationResult::CANCELLATION: + return "cancellation"; + } +} + +} // namespace + +RotateAttestationCredentialJob::ResultPayload::ResultPayload( + KeyRotationResult result) + : result_(result) { + base::DictionaryValue root_dict; + root_dict.SetString(kResultFieldName, ResultToString(result_)); + base::JSONWriter::Write(root_dict, &payload_); +} + +std::unique_ptr<std::string> +RotateAttestationCredentialJob::ResultPayload::Serialize() { + return std::make_unique<std::string>(payload_); +} + +RotateAttestationCredentialJob::RotateAttestationCredentialJob( + DeviceTrustKeyManager* key_manager) + : key_manager_(key_manager) { + DCHECK(key_manager_); +} + +RotateAttestationCredentialJob::~RotateAttestationCredentialJob() = default; + +enterprise_management::RemoteCommand_Type +RotateAttestationCredentialJob::GetType() const { + return enterprise_management:: + RemoteCommand_Type_BROWSER_ROTATE_ATTESTATION_CREDENTIAL; +} + +bool RotateAttestationCredentialJob::ParseCommandPayload( + const std::string& command_payload) { + absl::optional<base::Value> root(base::JSONReader::Read(command_payload)); + if (!root) + return false; + + if (!root->is_dict()) + return false; + + std::string* nonce_ptr = root->FindStringKey(kNoncePathField); + + if (nonce_ptr && !nonce_ptr->empty()) { + nonce_ = *nonce_ptr; + return true; + } + return false; +} + +void RotateAttestationCredentialJob::RunImpl( + CallbackWithResult succeeded_callback, + CallbackWithResult failed_callback) { + DCHECK(nonce_.has_value()); + + key_manager_->RotateKey( + nonce_.value(), + base::BindOnce(&RotateAttestationCredentialJob::OnKeyRotated, + weak_factory_.GetWeakPtr(), std::move(succeeded_callback), + std::move(failed_callback))); +} + +void RotateAttestationCredentialJob::OnKeyRotated( + CallbackWithResult succeeded_callback, + CallbackWithResult failed_callback, + KeyRotationResult rotation_result) { + auto payload = + std::make_unique<RotateAttestationCredentialJob::ResultPayload>( + rotation_result); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(payload->IsSuccess() ? succeeded_callback + : failed_callback), + std::move(payload))); +} + +} // namespace enterprise_commands
diff --git a/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.h b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.h new file mode 100644 index 0000000..b1ed9d56 --- /dev/null +++ b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job.h
@@ -0,0 +1,74 @@ +// 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_BROWSER_ENTERPRISE_REMOTE_COMMANDS_ROTATE_ATTESTATION_CREDENTIAL_JOB_H_ +#define CHROME_BROWSER_ENTERPRISE_REMOTE_COMMANDS_ROTATE_ATTESTATION_CREDENTIAL_JOB_H_ + +#include <string> + +#include "base/files/file_path.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "components/enterprise/browser/device_trust/device_trust_key_manager.h" +#include "components/policy/core/common/remote_commands/remote_command_job.h" +#include "content/public/browser/browsing_data_remover.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace enterprise_commands { + +// A remote command for rotating the device's existing attestation credential. +class RotateAttestationCredentialJob : public policy::RemoteCommandJob { + public: + explicit RotateAttestationCredentialJob( + enterprise_connectors::DeviceTrustKeyManager* key_manager); + ~RotateAttestationCredentialJob() override; + + private: + class ResultPayload : public RemoteCommandJob::ResultPayload { + public: + explicit ResultPayload( + enterprise_connectors::DeviceTrustKeyManager::KeyRotationResult result); + + ResultPayload(const ResultPayload&) = delete; + ResultPayload& operator=(const ResultPayload&) = delete; + + ~ResultPayload() override = default; + + bool IsSuccess() const { + return result_ == enterprise_connectors::DeviceTrustKeyManager:: + KeyRotationResult::SUCCESS; + } + + // RemoteCommandJob::ResultPayload: + std::unique_ptr<std::string> Serialize() override; + + private: + enterprise_connectors::DeviceTrustKeyManager::KeyRotationResult result_; + std::string payload_; + }; + + // RemoteCommandJob: + enterprise_management::RemoteCommand_Type GetType() const override; + bool ParseCommandPayload(const std::string& command_payload) override; + void RunImpl(CallbackWithResult succeeded_callback, + CallbackWithResult failed_callback) override; + + void OnKeyRotated( + CallbackWithResult succeeded_callback, + CallbackWithResult failed_callback, + enterprise_connectors::DeviceTrustKeyManager::KeyRotationResult + rotation_result); + + absl::optional<std::string> nonce_; + + // Non-owned pointer to the DeviceTrustKeyManager of the current browser + // process. + raw_ptr<enterprise_connectors::DeviceTrustKeyManager> key_manager_; + + base::WeakPtrFactory<RotateAttestationCredentialJob> weak_factory_{this}; +}; + +} // namespace enterprise_commands + +#endif // CHROME_BROWSER_ENTERPRISE_REMOTE_COMMANDS_ROTATE_ATTESTATION_CREDENTIAL_JOB_H_
diff --git a/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc new file mode 100644 index 0000000..5ac4ff6 --- /dev/null +++ b/chrome/browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc
@@ -0,0 +1,152 @@ +// 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/enterprise/remote_commands/rotate_attestation_credential_job.h" + +#include "base/callback.h" +#include "base/json/json_writer.h" +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "base/values.h" +#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/mock_device_trust_key_manager.h" +#include "components/enterprise/browser/device_trust/device_trust_key_manager.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using KeyRotationResult = + enterprise_connectors::DeviceTrustKeyManager::KeyRotationResult; + +using testing::_; +using testing::Invoke; + +namespace enterprise_commands { + +namespace { + +constexpr policy::RemoteCommandJob::UniqueIDType kUniqueID = 123456789; + +const char kNonceField[] = "nonce"; +const char kNonceValue[] = "some nonce value"; + +enterprise_management::RemoteCommand CreateCommand() { + enterprise_management::RemoteCommand command_proto; + command_proto.set_type( + enterprise_management:: + RemoteCommand_Type_BROWSER_ROTATE_ATTESTATION_CREDENTIAL); + command_proto.set_command_id(kUniqueID); + return command_proto; +} + +std::string GetPayloadWithNonce() { + base::Value root(base::Value::Type::DICTIONARY); + root.SetStringKey(kNonceField, kNonceValue); + + std::string payload; + base::JSONWriter::Write(root, &payload); + return payload; +} + +std::string GetEmptyPayload() { + return "{}"; +} + +} // namespace + +class RotateAttestationCredentialJobTest : public testing::Test { + protected: + void MockKeyRotationWith(KeyRotationResult result) { + EXPECT_CALL(mock_key_manager_, RotateKey(kNonceValue, _)) + .WillOnce(Invoke( + [result](const std::string& nonce, + base::OnceCallback<void(KeyRotationResult)> callback) { + std::move(callback).Run(result); + })); + } + + std::unique_ptr<RotateAttestationCredentialJob> CreateJob( + enterprise_management::RemoteCommand command_proto) { + auto job = + std::make_unique<RotateAttestationCredentialJob>(&mock_key_manager_); + EXPECT_TRUE(job->Init(base::TimeTicks::Now(), command_proto, + enterprise_management::SignedData{})); + EXPECT_EQ(kUniqueID, job->unique_id()); + EXPECT_EQ(policy::RemoteCommandJob::NOT_STARTED, job->status()); + + return job; + } + + base::test::SingleThreadTaskEnvironment task_environment_; + testing::StrictMock<enterprise_connectors::test::MockDeviceTrustKeyManager> + mock_key_manager_; +}; + +// Tests that a job conveys a successful key rotation properly. +TEST_F(RotateAttestationCredentialJobTest, SuccessRun) { + MockKeyRotationWith(KeyRotationResult::SUCCESS); + + auto command_proto = CreateCommand(); + auto json_payload = GetPayloadWithNonce(); + command_proto.set_payload(json_payload); + + base::RunLoop run_loop; + auto job = CreateJob(std::move(command_proto)); + + EXPECT_TRUE(job->Run(base::Time::Now(), base::TimeTicks::Now(), + run_loop.QuitClosure())); + run_loop.Run(); + + EXPECT_EQ(job->status(), policy::RemoteCommandJob::SUCCEEDED); +} + +// Tests that a job conveys a failed key rotation properly. +TEST_F(RotateAttestationCredentialJobTest, FailedRun) { + MockKeyRotationWith(KeyRotationResult::FAILURE); + + auto command_proto = CreateCommand(); + auto json_payload = GetPayloadWithNonce(); + command_proto.set_payload(json_payload); + + base::RunLoop run_loop; + auto job = CreateJob(std::move(command_proto)); + + EXPECT_TRUE(job->Run(base::Time::Now(), base::TimeTicks::Now(), + run_loop.QuitClosure())); + run_loop.Run(); + + EXPECT_EQ(job->status(), policy::RemoteCommandJob::FAILED); +} + +// Tests that a job conveys a cancelled key rotation properly. +TEST_F(RotateAttestationCredentialJobTest, CancelledRun) { + MockKeyRotationWith(KeyRotationResult::CANCELLATION); + + auto command_proto = CreateCommand(); + auto json_payload = GetPayloadWithNonce(); + command_proto.set_payload(json_payload); + + base::RunLoop run_loop; + auto job = CreateJob(std::move(command_proto)); + + EXPECT_TRUE(job->Run(base::Time::Now(), base::TimeTicks::Now(), + run_loop.QuitClosure())); + run_loop.Run(); + + EXPECT_EQ(job->status(), policy::RemoteCommandJob::FAILED); +} + +// Tests that a job handles a bad payload properly. +TEST_F(RotateAttestationCredentialJobTest, BadPayload) { + auto command_proto = CreateCommand(); + auto json_payload = GetEmptyPayload(); + command_proto.set_payload(json_payload); + + auto job = + std::make_unique<RotateAttestationCredentialJob>(&mock_key_manager_); + EXPECT_FALSE(job->Init(base::TimeTicks::Now(), command_proto, + enterprise_management::SignedData{})); +} + +} // namespace enterprise_commands
diff --git a/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc b/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc index 8d7fa32a..8ae1c36 100644 --- a/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc +++ b/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc
@@ -247,7 +247,7 @@ VerifyBrowserVersionAndChannel(report.get()); VerifyBuildState(report.get()); VerifyExtendedStableChannel(report.get()); - VerifyPlugins(report.get()); + EXPECT_LE(0, report->plugins_size()); // There should be no profile information. EXPECT_EQ(0, report->chrome_user_profile_infos_size());
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index e4c1e03..3306c9a 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -881,6 +881,7 @@ "//extensions/browser:core_api_provider", "//extensions/browser/api:api_implementations", "//extensions/browser/updater", + "//extensions/browser/updater:keepalive", "//extensions/buildflags", "//extensions/common", "//extensions/common:mojom",
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc index c282cf47..0bc695c 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc
@@ -143,9 +143,8 @@ SCOPED_TRACE("settings"); std::unique_ptr<base::Value> result = RunFunctionAndReturnSingleResult( function.get(), std::string("[]"), browser()); - EXPECT_TRUE(result->is_dict()); - EXPECT_TRUE(result->FindDoublePath("options.since")); + ASSERT_TRUE(result->FindDoublePath("options.since")); double since = *result->FindDoublePath("options.since"); double expected_since = 0;
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc index 896c92f..d86acae1 100644 --- a/chrome/browser/extensions/api/commands/command_service.cc +++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -553,7 +553,7 @@ void CommandService::RemoveDefunctExtensionSuggestedCommandPrefs( const Extension* extension) { ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); - const base::DictionaryValue* current_prefs = NULL; + const base::DictionaryValue* current_prefs = nullptr; extension_prefs->ReadPrefAsDictionary(extension->id(), kCommands, ¤t_prefs); @@ -602,20 +602,21 @@ ui::Accelerator suggested_key; absl::optional<bool> suggested_key_was_assigned; ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); - const base::DictionaryValue* commands_prefs = NULL; - const base::DictionaryValue* suggested_key_prefs = NULL; - if (extension_prefs->ReadPrefAsDictionary(extension->id(), - kCommands, - &commands_prefs) && - commands_prefs->GetDictionary(command_name, &suggested_key_prefs)) { - std::string suggested_key_string; - if (suggested_key_prefs->GetString(kSuggestedKey, &suggested_key_string)) { - suggested_key = Command::StringToAccelerator(suggested_key_string, - command_name); + const base::DictionaryValue* commands_prefs = nullptr; + if (extension_prefs->ReadPrefAsDictionary(extension->id(), kCommands, + &commands_prefs)) { + const base::Value* suggested_key_prefs = + commands_prefs->FindDictPath(command_name); + if (suggested_key_prefs) { + const std::string* suggested_key_string = + suggested_key_prefs->FindStringKey(kSuggestedKey); + if (suggested_key_string) { + suggested_key = + Command::StringToAccelerator(*suggested_key_string, command_name); + } + suggested_key_was_assigned = + suggested_key_prefs->FindBoolKey(kSuggestedKeyWasAssigned); } - - suggested_key_was_assigned = - suggested_key_prefs->FindBoolKey(kSuggestedKeyWasAssigned); } // Get the active shortcut from the prefs, if any. @@ -628,8 +629,7 @@ void CommandService::RemoveKeybindingPrefs(const std::string& extension_id, const std::string& command_name) { - DictionaryPrefUpdate updater(profile_->GetPrefs(), - prefs::kExtensionCommands); + DictionaryPrefUpdate updater(profile_->GetPrefs(), prefs::kExtensionCommands); base::DictionaryValue* bindings = updater.Get(); typedef std::vector<std::string> KeysToRemove; @@ -719,8 +719,8 @@ } template <> -void -BrowserContextKeyedAPIFactory<CommandService>::DeclareFactoryDependencies() { +void BrowserContextKeyedAPIFactory< + CommandService>::DeclareFactoryDependencies() { DependsOn(ExtensionCommandsGlobalRegistry::GetFactoryInstance()); }
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc similarity index 100% rename from chrome/browser/extensions/extension_context_menu_browsertest.cc rename to chrome/browser/extensions/api/context_menus/extension_context_menu_browsertest.cc
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc index 64d69702..46cd7b8 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
@@ -260,9 +260,7 @@ bool* out_result) { if (bubble_action != permissions::PermissionRequestManager::NONE) { prompt_factory_->set_response_type(bubble_action); - auto* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0); - prompt_factory_->DocumentOnLoadCompletedInMainFrame( - web_contents->GetMainFrame()); + prompt_factory_->DocumentOnLoadCompletedInPrimaryMainFrame(); } auto function = base::MakeRefCounted< @@ -295,9 +293,7 @@ bool* out_result) { if (bubble_action != permissions::PermissionRequestManager::NONE) { prompt_factory_->set_response_type(bubble_action); - auto* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0); - prompt_factory_->DocumentOnLoadCompletedInMainFrame( - web_contents->GetMainFrame()); + prompt_factory_->DocumentOnLoadCompletedInPrimaryMainFrame(); } auto function = base::MakeRefCounted<
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc index 83c0bbe..9b9e1aa 100644 --- a/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -189,6 +189,8 @@ ~ExtensionDevToolsClientHost() override; + std::string GetTypeForMetrics() override { return "Extension"; } + bool Attach(); const std::string& extension_id() { return extension_->id(); } DevToolsAgentHost* agent_host() { return agent_host_.get(); }
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc index bca2ffe..b71326a 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -406,10 +406,10 @@ } gfx::ImageSkia icon; - const base::DictionaryValue* canvas_set = NULL; - if (dict->GetDictionary("imageData", &canvas_set) && - ExtensionAction::ParseIconFromCanvasDictionary(*canvas_set, &icon) != - ExtensionAction::IconParseResult::kSuccess) { + const base::Value* canvas_set = dict->FindDictKey("imageData"); + if (canvas_set && ExtensionAction::ParseIconFromCanvasDictionary( + base::Value::AsDictionaryValue(*canvas_set), &icon) != + ExtensionAction::IconParseResult::kSuccess) { *error = kInvalidIconDictionary; return nullptr; }
diff --git a/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc b/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc index 5732af6..19fe3a6 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc
@@ -22,6 +22,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/user_script_manager.h" #include "extensions/common/api/declarative/declarative_constants.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/value_builder.h" @@ -143,7 +144,7 @@ } class ParameterizedDeclarativeContentActionTest - : public ::testing::TestWithParam<ExtensionBuilder::ActionType> {}; + : public ::testing::TestWithParam<ActionInfo::Type> {}; TEST_P(ParameterizedDeclarativeContentActionTest, ShowAction) { TestExtensionEnvironment env; @@ -176,7 +177,7 @@ auto* action_manager = ExtensionActionManager::Get(env.profile()); ExtensionAction* action = action_manager->GetExtensionAction(*extension); ASSERT_TRUE(action); - if (GetParam() == ExtensionBuilder::ActionType::BROWSER_ACTION) { + if (GetParam() == ActionInfo::TYPE_BROWSER) { EXPECT_EQ(ActionInfo::TYPE_BROWSER, action->action_type()); // Switch the default so we properly see the action toggling. action->SetIsVisible(ExtensionAction::kDefaultTabId, false); @@ -211,11 +212,10 @@ EXPECT_FALSE(action->GetIsVisible(tab_id)); } -INSTANTIATE_TEST_SUITE_P( - All, - ParameterizedDeclarativeContentActionTest, - testing::Values(ExtensionBuilder::ActionType::BROWSER_ACTION, - ExtensionBuilder::ActionType::PAGE_ACTION)); +INSTANTIATE_TEST_SUITE_P(All, + ParameterizedDeclarativeContentActionTest, + testing::Values(ActionInfo::TYPE_BROWSER, + ActionInfo::TYPE_PAGE)); TEST(DeclarativeContentActionTest, SetIcon) { enum Mode { Base64, Mojo, MojoHuge };
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc index 5b0cdff..a24ea50 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -52,6 +52,7 @@ #include "extensions/common/error_utils.h" #include "extensions/common/file_util.h" #include "extensions/common/install_warning.h" +#include "extensions/common/manifest_constants.h" #include "extensions/common/url_pattern.h" #include "extensions/common/value_builder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -97,6 +98,25 @@ dnr_api::DNRInfo::kRuleResources); } +// Returns the vector of install warnings, filtering out the one associated with +// a deprecated manifest version. +// TODO(https://crbug.com/1269161): Remove this method when the associated tests +// are updated to MV3. +std::vector<InstallWarning> GetFilteredInstallWarnings( + const Extension& extension) { + std::vector<InstallWarning> filtered_warnings; + // InstallWarning isn't copyable (but is movable), so we have to do a bit of + // extra legwork to get a vector here. + for (const auto& warning : extension.install_warnings()) { + if (warning.message == manifest_errors::kManifestV2IsDeprecatedWarning) { + continue; + } + filtered_warnings.emplace_back(warning.message, warning.key, + warning.specific); + } + return filtered_warnings; +} + // Base test fixture to test indexing of rulesets. class DeclarativeNetRequestUnittest : public DNRTestBase { public: @@ -655,8 +675,8 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - const std::vector<InstallWarning>& expected_warnings = - extension()->install_warnings(); + std::vector<InstallWarning> expected_warnings = + GetFilteredInstallWarnings(*extension()); ASSERT_EQ(1u + kMaxUnparsedRulesWarnings, expected_warnings.size()); InstallWarning warning(""); @@ -714,10 +734,12 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - ASSERT_EQ(2u, extension()->install_warnings().size()); + std::vector<InstallWarning> install_warnings = + GetFilteredInstallWarnings(*extension()); + ASSERT_EQ(2u, install_warnings.size()); std::vector<InstallWarning> expected_warnings; - for (const auto& warning : extension()->install_warnings()) { + for (const auto& warning : install_warnings) { EXPECT_EQ(dnr_api::ManifestKeys::kDeclarativeNetRequest, warning.key); EXPECT_EQ(dnr_api::DNRInfo::kRuleResources, warning.specific); EXPECT_THAT(warning.message, ::testing::HasSubstr("Parse error")); @@ -770,7 +792,9 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - ASSERT_EQ(2u, extension()->install_warnings().size()); + std::vector<InstallWarning> install_warnings = + GetFilteredInstallWarnings(*extension()); + ASSERT_EQ(2u, install_warnings.size()); std::vector<InstallWarning> expected_warnings; expected_warnings.emplace_back( @@ -785,7 +809,7 @@ "'id': expected id, got string"), dnr_api::ManifestKeys::kDeclarativeNetRequest, dnr_api::DNRInfo::kRuleResources); - EXPECT_EQ(expected_warnings, extension()->install_warnings()); + EXPECT_EQ(expected_warnings, install_warnings); } } @@ -824,7 +848,7 @@ if (GetParam() != ExtensionLoadType::PACKED) { InstallWarning warning_1 = GetLargeRegexWarning(kMinValidID + 5); InstallWarning warning_2 = GetLargeRegexWarning(kMinValidID + 6); - EXPECT_THAT(extension()->install_warnings(), + EXPECT_THAT(GetFilteredInstallWarnings(*extension()), UnorderedElementsAre(::testing::Eq(std::cref(warning_1)), ::testing::Eq(std::cref(warning_2)))); } @@ -873,11 +897,14 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - ASSERT_EQ(1u, extension()->install_warnings().size()); + std::vector<InstallWarning> install_warnings = + GetFilteredInstallWarnings(*extension()); + + ASSERT_EQ(1u, install_warnings.size()); EXPECT_EQ(InstallWarning(GetErrorWithFilename(kRegexRuleCountExceeded), dnr_api::ManifestKeys::kDeclarativeNetRequest, dnr_api::DNRInfo::kRuleResources), - extension()->install_warnings()[0]); + install_warnings[0]); } } @@ -1167,7 +1194,9 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - ASSERT_EQ(1u, extension()->install_warnings().size()); + std::vector<InstallWarning> install_warnings = + GetFilteredInstallWarnings(*extension()); + ASSERT_EQ(1u, install_warnings.size()); InstallWarning expected_warning = InstallWarning(GetErrorWithFilename(ErrorUtils::FormatErrorMessage( kIndexingRuleLimitExceeded, @@ -1175,7 +1204,7 @@ dnr_api::ManifestKeys::kDeclarativeNetRequest, dnr_api::DNRInfo::kRuleResources); - EXPECT_EQ(expected_warning, extension()->install_warnings()[0]); + EXPECT_EQ(expected_warning, install_warnings[0]); } // The ruleset's ID should be persisted in the ignored rulesets pref. @@ -1475,8 +1504,8 @@ // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, // which causes it to lose the install warning. This should be fixed. if (GetParam() != ExtensionLoadType::PACKED) { - const std::vector<InstallWarning>& warnings = - extension()->install_warnings(); + std::vector<InstallWarning> warnings = + GetFilteredInstallWarnings(*extension()); std::vector<std::string> warning_strings; for (const InstallWarning& warning : warnings) warning_strings.push_back(warning.message); @@ -1527,7 +1556,7 @@ // Installing the extension causes an install warning since the set of enabled // rulesets exceed the regex rules limit. if (GetParam() != ExtensionLoadType::PACKED) { - EXPECT_THAT(extension()->install_warnings(), + EXPECT_THAT(GetFilteredInstallWarnings(*extension()), UnorderedElementsAre(Field(&InstallWarning::message, kEnabledRegexRuleCountExceeded))); } @@ -1820,7 +1849,7 @@ std::to_string(static_sources[0].id().value())), kId1); - EXPECT_THAT(extension()->install_warnings(), + EXPECT_THAT(GetFilteredInstallWarnings(*extension()), UnorderedElementsAre( Field(&InstallWarning::message, expected_warning))); }
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc index 7216a9e4..232c112 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
@@ -52,9 +52,9 @@ api::desktop_capture::ChooseDesktopMedia::Params::Create(args()); EXTENSION_FUNCTION_VALIDATE(params.get()); - // |web_contents| is the WebContents for which the stream is created, and will - // also be used to determine where to show the picker's UI. - content::WebContents* web_contents = NULL; + // |target_render_frame_host| is the RenderFrameHost for which the stream is + // created, and will also be used to determine where to show the picker's UI. + content::RenderFrameHost* target_render_frame_host = nullptr; std::u16string target_name; GURL origin; if (params->target_tab) { @@ -81,21 +81,25 @@ return RespondNow(Error(kDesktopCaptureApiNoTabIdError)); } + content::WebContents* web_contents = nullptr; if (!ExtensionTabUtil::GetTabById( *(params->target_tab->id), Profile::FromBrowserContext(browser_context()), true, &web_contents)) { return RespondNow(Error(kDesktopCaptureApiInvalidTabIdError)); } - DCHECK(web_contents); + // The |target_render_frame_host| is the main frame of the tab that + // was requested for capture. + target_render_frame_host = web_contents->GetMainFrame(); } else { origin = extension()->url(); target_name = base::UTF8ToUTF16(GetExtensionTargetName()); - web_contents = GetSenderWebContents(); - DCHECK(web_contents); + target_render_frame_host = render_frame_host(); } + DCHECK(target_render_frame_host); - return Execute(params->sources, web_contents, origin, target_name); + return Execute(params->sources, target_render_frame_host, origin, + target_name); } std::string DesktopCaptureChooseDesktopMediaFunction::GetExtensionTargetName()
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index 43a98077..a37c1b4 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -42,6 +42,7 @@ namespace { +const char kTargetNotActiveError[] = "The specified target is not active."; const char kInvalidSourceNameError[] = "Invalid source type specified."; DesktopMediaPickerFactory* g_picker_factory = nullptr; @@ -54,6 +55,10 @@ g_picker_factory = factory; } +const char + DesktopCaptureChooseDesktopMediaFunctionBase::kTargetNotFoundError[] = + "The specified target is not found."; + DesktopCaptureChooseDesktopMediaFunctionBase:: DesktopCaptureChooseDesktopMediaFunctionBase() = default; @@ -77,11 +82,19 @@ ExtensionFunction::ResponseAction DesktopCaptureChooseDesktopMediaFunctionBase::Execute( const std::vector<api::desktop_capture::DesktopCaptureSourceType>& sources, - content::WebContents* web_contents, + content::RenderFrameHost* render_frame_host, const GURL& origin, const std::u16string target_name) { DCHECK(!picker_controller_); + if (!render_frame_host->IsActive()) + return RespondNow(Error(kTargetNotActiveError)); + + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host); + if (!web_contents) + return RespondNow(Error(kTargetNotFoundError)); + gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow(); // In case of coming from background extension page, |parent_window| will // be null. We are going to make the picker modal to the current browser
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h index e89aa53..f54da5d 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h
@@ -34,6 +34,8 @@ protected: ~DesktopCaptureChooseDesktopMediaFunctionBase() override; + static const char kTargetNotFoundError[]; + // |web_contents| is the WebContents for which the stream is created, and will // also be used to determine where to show the picker's UI. // |origin| is the origin for which the stream is created. @@ -41,7 +43,7 @@ ResponseAction Execute( const std::vector<api::desktop_capture::DesktopCaptureSourceType>& sources, - content::WebContents* web_contents, + content::RenderFrameHost* render_frame_host, const GURL& origin, const std::u16string target_name);
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc index 7ab5d9be..188a76c 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -259,16 +259,16 @@ DictionaryBuilder() .Set("name", kName) .Set("version", kVersion) - .Set("manifest_version", 2) + .Set("manifest_version", 3) .Set("description", "an extension") - .Set("permissions", ListBuilder() - .Append("file://*/*") - .Append("tabs") - .Append("*://*.google.com/*") - .Append("*://*.example.com/*") - .Append("*://*.foo.bar/*") - .Append("*://*.chromium.org/*") - .Build()) + .Set("host_permissions", ListBuilder() + .Append("file://*/*") + .Append("*://*.google.com/*") + .Append("*://*.example.com/*") + .Append("*://*.foo.bar/*") + .Append("*://*.chromium.org/*") + .Build()) + .Set("permissions", ListBuilder().Append("tabs").Build()) .Build(); std::unique_ptr<base::DictionaryValue> manifest_copy(manifest->DeepCopy()); scoped_refptr<const Extension> extension = @@ -814,13 +814,11 @@ struct { const char* name; const char* command_key; - ExtensionBuilder::ActionType action_type; + ActionInfo::Type action_type; } test_cases[] = { - {"browser action", "_execute_browser_action", - ExtensionBuilder::ActionType::BROWSER_ACTION}, - {"page action", "_execute_page_action", - ExtensionBuilder::ActionType::PAGE_ACTION}, - {"action", "_execute_action", ExtensionBuilder::ActionType::ACTION}, + {"browser action", "_execute_browser_action", ActionInfo::TYPE_BROWSER}, + {"page action", "_execute_page_action", ActionInfo::TYPE_PAGE}, + {"action", "_execute_action", ActionInfo::TYPE_ACTION}, }; for (const auto& test_case : test_cases) {
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc index 9b65fd2..5d51224 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -41,6 +41,7 @@ #include "extensions/browser/extension_registry.h" #include "extensions/common/api/test.h" #include "extensions/common/extension_id.h" +#include "extensions/common/manifest_constants.h" #include "extensions/common/switches.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" @@ -328,11 +329,15 @@ ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); const Extension* extension = GetExtensionByPath(registry->enabled_extensions(), extension_path); - ASSERT_FALSE(extension->install_warnings().empty()); + ASSERT_EQ(2u, extension->install_warnings().size()); + // TODO(https://crbug.com/1269161): Remove the check for the deprecated + // manifest version when the test extension is updated to MV3. + EXPECT_EQ(extensions::manifest_errors::kManifestV2IsDeprecatedWarning, + extension->install_warnings()[0].message); EXPECT_EQ( "'enterprise.platformKeys' is not allowed for specified install " "location.", - extension->install_warnings()[0].message); + extension->install_warnings()[1].message); } class EnterprisePlatformKeysLoginScreenTest
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc index f175648..66d2bcd 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -380,12 +380,13 @@ // setIcon can take a variant argument: either a dictionary of canvas // ImageData, or an icon index. - base::DictionaryValue* canvas_set = NULL; - if (details_->GetDictionary("imageData", &canvas_set)) { + base::Value* canvas_set = details_->FindDictKey("imageData"); + if (canvas_set) { gfx::ImageSkia icon; ExtensionAction::IconParseResult parse_result = - ExtensionAction::ParseIconFromCanvasDictionary(*canvas_set, &icon); + ExtensionAction::ParseIconFromCanvasDictionary( + base::Value::AsDictionaryValue(*canvas_set), &icon); if (parse_result != ExtensionAction::IconParseResult::kSuccess) { switch (parse_result) {
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index 1963eb1..7b9aefd 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -449,8 +449,7 @@ chrome.test.assertTrue(tab.id > 0); chrome.test.assertTrue(tab.index > -1); chrome.test.notifyPass(); - }); - chrome.test.sendMessage('ready');)"; + });)"; const char* background_specification = GetParam() == ActionInfo::TYPE_ACTION @@ -472,10 +471,8 @@ ExtensionActionTestHelper::Create(browser()); EXPECT_EQ(0, toolbar_helper->NumberOfBrowserActions()); - ExtensionTestMessageListener listener("ready", /*will_reply=*/false); const Extension* extension = LoadExtension(test_dir.UnpackedPath()); ASSERT_TRUE(extension); - ASSERT_TRUE(listener.WaitUntilSatisfied()); ASSERT_EQ(1, toolbar_helper->NumberOfBrowserActions()); EXPECT_TRUE(toolbar_helper->HasAction(extension->id()));
diff --git a/chrome/browser/extensions/page_action_browsertest.cc b/chrome/browser/extensions/api/extension_action/page_action_browsertest.cc similarity index 100% rename from chrome/browser/extensions/page_action_browsertest.cc rename to chrome/browser/extensions/api/extension_action/page_action_browsertest.cc
diff --git a/chrome/browser/extensions/api/file_manager/file_browser_handler_api_ash_test.cc b/chrome/browser/extensions/api/file_manager/file_browser_handler_api_ash_test.cc index a15b205..e1e4fb3 100644 --- a/chrome/browser/extensions/api/file_manager/file_browser_handler_api_ash_test.cc +++ b/chrome/browser/extensions/api/file_manager/file_browser_handler_api_ash_test.cc
@@ -341,8 +341,7 @@ "[{\"suggestedName\": \"some_file_name.txt\"}]", browser()))); EXPECT_FALSE(extensions::api_test_utils::GetBoolean(result.get(), "success")); - base::DictionaryValue* entry_info; - EXPECT_FALSE(result->GetDictionary("entry", &entry_info)); + EXPECT_FALSE(result->FindDictKey("entry")); } // Tests that user cannot be suggested a full file path when selecting a file, @@ -366,8 +365,7 @@ browser()))); EXPECT_FALSE(extensions::api_test_utils::GetBoolean(result.get(), "success")); - base::DictionaryValue* entry_info; - EXPECT_FALSE(result->GetDictionary("entry", &entry_info)); + EXPECT_FALSE(result->FindDictKey("entry")); } } // namespace
diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/api/gcm/extension_gcm_app_handler_unittest.cc similarity index 100% rename from chrome/browser/extensions/extension_gcm_app_handler_unittest.cc rename to chrome/browser/extensions/api/gcm/extension_gcm_app_handler_unittest.cc
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/api/messaging/messaging_apitest.cc similarity index 100% rename from chrome/browser/extensions/extension_messages_apitest.cc rename to chrome/browser/extensions/api/messaging/messaging_apitest.cc
diff --git a/chrome/browser/extensions/service_worker_messaging_apitest.cc b/chrome/browser/extensions/api/messaging/service_worker_messaging_apitest.cc similarity index 100% rename from chrome/browser/extensions/service_worker_messaging_apitest.cc rename to chrome/browser/extensions/api/messaging/service_worker_messaging_apitest.cc
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api.cc b/chrome/browser/extensions/api/omnibox/omnibox_api.cc index 84bcc31c..ff8cc48 100644 --- a/chrome/browser/extensions/api/omnibox/omnibox_api.cc +++ b/chrome/browser/extensions/api/omnibox/omnibox_api.cc
@@ -21,7 +21,8 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/common/extensions/api/omnibox.h" #include "chrome/common/extensions/api/omnibox/omnibox_handler.h" -#include "components/omnibox/browser/omnibox_watcher.h" +#include "components/omnibox/browser/omnibox_input_watcher.h" +#include "components/omnibox/browser/omnibox_suggestions_watcher.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" #include "content/public/browser/notification_details.h" @@ -154,7 +155,7 @@ EventRouter::Get(profile) ->DispatchEventToExtension(extension_id, std::move(event)); - OmniboxWatcher::GetForBrowserContext(profile)->NotifyInputEntered(); + OmniboxInputWatcher::GetForBrowserContext(profile)->NotifyInputEntered(); } // static @@ -277,11 +278,10 @@ SendSuggestions::Params::Create(args())); EXTENSION_FUNCTION_VALIDATE(params); - content::NotificationService::current()->Notify( - extensions::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, - content::Source<Profile>( - Profile::FromBrowserContext(browser_context())->GetOriginalProfile()), - content::Details<SendSuggestions::Params>(params.get())); + Profile* profile = + Profile::FromBrowserContext(browser_context())->GetOriginalProfile(); + OmniboxSuggestionsWatcher::GetForBrowserContext(profile) + ->NotifySuggestionsReady(params.get()); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/extensions/printer_provider_apitest.cc b/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc similarity index 100% rename from chrome/browser/extensions/printer_provider_apitest.cc rename to chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
diff --git a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc index fd4e2e9..61e84f00 100644 --- a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc +++ b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc
@@ -211,9 +211,8 @@ std::string* out, std::string* error, bool* bad_message) { - const base::DictionaryValue* proxy_rules = NULL; - proxy_config->GetDictionary(proxy_api_constants::kProxyConfigRules, - &proxy_rules); + const base::Value* proxy_rules = + proxy_config->FindDictKey(proxy_api_constants::kProxyConfigRules); if (!proxy_rules) return true; @@ -227,13 +226,14 @@ // singleProxy that will supersede per-URL proxies, but it's worth it to keep // the code simple and extensible. for (size_t i = 0; i <= proxy_api_constants::SCHEME_MAX; ++i) { - const base::DictionaryValue* proxy_dict = NULL; - has_proxy[i] = proxy_rules->GetDictionary( - proxy_api_constants::field_name[i], &proxy_dict); + const base::Value* proxy_dict = + proxy_rules->FindDictPath(proxy_api_constants::field_name[i]); + has_proxy[i] = proxy_dict != nullptr; if (has_proxy[i]) { net::ProxyServer::Scheme default_scheme = net::ProxyServer::SCHEME_HTTP; - if (!GetProxyServer(proxy_dict, default_scheme, - &proxy_server[i], error, bad_message)) { + if (!GetProxyServer(&base::Value::AsDictionaryValue(*proxy_dict), + default_scheme, &proxy_server[i], error, + bad_message)) { // Don't set |error| here, as GetProxyServer takes care of that. return false; }
diff --git a/chrome/browser/extensions/api/scripting/OWNERS b/chrome/browser/extensions/api/scripting/OWNERS new file mode 100644 index 0000000..c66e2301 --- /dev/null +++ b/chrome/browser/extensions/api/scripting/OWNERS
@@ -0,0 +1,2 @@ +kelvinjiang@chromium.org +rdevlin.cronin@chromium.org
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc index ed2b459..735e05df 100644 --- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -124,11 +124,11 @@ EXPECT_TRUE(session_value.is_dict()); const base::DictionaryValue& session = base::Value::AsDictionaryValue(session_value); - const base::DictionaryValue* window = nullptr; - EXPECT_TRUE(session.GetDictionary("window", &window)); + const base::Value* window = session.FindDictKey("window"); + EXPECT_TRUE(window); // Only the tabs are interesting. - const base::ListValue* tabs = nullptr; - EXPECT_TRUE(window->GetList("tabs", &tabs)); + const base::Value* tabs = window->FindListKey("tabs"); + EXPECT_TRUE(tabs); EXPECT_EQ(base::size(kTabIDs), tabs->GetList().size()); for (size_t j = 0; j < tabs->GetList().size(); ++j) { const base::Value& tab_value = tabs->GetList()[j]; @@ -325,11 +325,10 @@ base::ListValue* windows = result.get(); EXPECT_EQ(2u, windows->GetList().size()); - base::DictionaryValue* restored_window = nullptr; - EXPECT_TRUE( - restored_window_session->GetDictionary("window", &restored_window)); + base::Value* restored_window = restored_window_session->FindDictKey("window"); + EXPECT_TRUE(restored_window); const base::DictionaryValue* window = nullptr; - int restored_id = api_test_utils::GetInteger(restored_window, "id"); + int restored_id = restored_window->FindIntKey("id").value_or(0); for (const base::Value& window_value : windows->GetList()) { EXPECT_TRUE(window_value.is_dict()); window = &base::Value::AsDictionaryValue(window_value);
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 2388b896..6e856c14 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -631,15 +631,14 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; // Quick Answers. - (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersEnabled] = + (*s_allowlist)[quick_answers::prefs::kQuickAnswersEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; - (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersDefinitionEnabled] = + (*s_allowlist)[quick_answers::prefs::kQuickAnswersDefinitionEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; - (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersTranslationEnabled] = + (*s_allowlist)[quick_answers::prefs::kQuickAnswersTranslationEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; - (*s_allowlist) - [ash::quick_answers::prefs::kQuickAnswersUnitConverstionEnabled] = - settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_allowlist)[quick_answers::prefs::kQuickAnswersUnitConverstionEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Misc. (*s_allowlist)[::prefs::kUse24HourClock] =
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/api/tabs/execute_script_apitest.cc similarity index 100% rename from chrome/browser/extensions/execute_script_apitest.cc rename to chrome/browser/extensions/api/tabs/execute_script_apitest.cc
diff --git a/chrome/browser/extensions/extension_tabs_apitest.cc b/chrome/browser/extensions/api/tabs/tabs_apitest.cc similarity index 100% rename from chrome/browser/extensions/extension_tabs_apitest.cc rename to chrome/browser/extensions/api/tabs/tabs_apitest.cc
diff --git a/chrome/browser/extensions/window_open_interactive_apitest.cc b/chrome/browser/extensions/api/tabs/window_open_interactive_apitest.cc similarity index 100% rename from chrome/browser/extensions/window_open_interactive_apitest.cc rename to chrome/browser/extensions/api/tabs/window_open_interactive_apitest.cc
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc index 81157277..875c5a0 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc
@@ -12,7 +12,6 @@ #include "base/lazy_instance.h" #include "base/strings/string_number_conversions.h" #include "base/task/task_runner_util.h" -#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "content/public/browser/audio_service.h" #include "content/public/browser/browser_context.h"
diff --git a/chrome/browser/extensions/api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.cc b/chrome/browser/extensions/api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.cc index 3a8bcf9..fcfbf29 100644 --- a/chrome/browser/extensions/api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.cc +++ b/chrome/browser/extensions/api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.cc
@@ -19,7 +19,6 @@ namespace { -const char kTargetNotFoundError[] = "The specified target is not found."; const char kUrlNotSecure[] = "URL scheme for the specified target is not secure."; @@ -69,15 +68,9 @@ ? net::GetHostAndOptionalPort(origin) : origin.spec()); - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(rfh); - if (!web_contents) { - return RespondNow(Error(kTargetNotFoundError)); - } - using Sources = std::vector<api::desktop_capture::DesktopCaptureSourceType>; Sources* sources = reinterpret_cast<Sources*>(¶ms->sources); - return Execute(*sources, web_contents, origin, target_name); + return Execute(*sources, rfh, origin, target_name); } WebrtcDesktopCapturePrivateCancelChooseDesktopMediaFunction::
diff --git a/chrome/browser/extensions/browser_extension_window_controller.cc b/chrome/browser/extensions/browser_extension_window_controller.cc index 34edf935..a7c5aa99 100644 --- a/chrome/browser/extensions/browser_extension_window_controller.cc +++ b/chrome/browser/extensions/browser_extension_window_controller.cc
@@ -6,7 +6,6 @@ #include <string> -#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/extensions/chrome_app_icon.cc b/chrome/browser/extensions/chrome_app_icon.cc index 7a8e0dc..86dfa311 100644 --- a/chrome/browser/extensions/chrome_app_icon.cc +++ b/chrome/browser/extensions/chrome_app_icon.cc
@@ -157,12 +157,10 @@ } #endif - const Extension* extension = - ExtensionRegistry::Get(browser_context_)->GetInstalledExtension(app_id_); - bool from_bookmark = extension && extension->from_bookmark(); - + // TODO(crbug.com/1065748): Remove arg `from_bookmark` from ApplyEffects() + // function signature. ApplyEffects(resource_size_in_dip_, resize_function_, app_launchable, - from_bookmark, badge_type, &image_skia_); + /*from_bookmark=*/false, badge_type, &image_skia_); delegate_->OnIconUpdated(this); }
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index c9f87a0..f7078c9c4 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -246,12 +246,9 @@ // also that we must not return an invalid effective URL here, since that // might lead to incorrect security decisions - see // https://crbug.com/1016954. - // - // Bookmark apps do not use the hosted app process model, and should be - // treated as normal URLs. const Extension* hosted_app = registry->enabled_extensions().GetHostedAppByURL(url); - if (hosted_app && !hosted_app->from_bookmark()) + if (hosted_app) return hosted_app->url(); // If this is a chrome-extension: URL, check whether a corresponding
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index 88d3b14..37b944f 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -37,6 +37,8 @@ #include "chrome/browser/extensions/updater/chrome_update_client_config.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h" +#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" @@ -64,6 +66,7 @@ #include "extensions/browser/extension_util.h" #include "extensions/browser/extensions_browser_interface_binders.h" #include "extensions/browser/pref_names.h" +#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h" #include "extensions/browser/url_request_util.h" #include "extensions/common/extension_urls.h" #include "extensions/common/features/feature_channel.h" @@ -98,6 +101,16 @@ command_line.HasSwitch(::switches::kDisableExtensionsExcept); } +class UpdaterKeepAlive : public ScopedExtensionUpdaterKeepAlive { + public: + UpdaterKeepAlive(Profile* profile, ProfileKeepAliveOrigin origin) + : profile_keep_alive_(profile, origin) {} + ~UpdaterKeepAlive() override = default; + + private: + ScopedProfileKeepAlive profile_keep_alive_; +}; + } // namespace ChromeExtensionsBrowserClient::ChromeExtensionsBrowserClient() { @@ -464,6 +477,14 @@ ChromeUpdateClientConfig::Create(context, override_url)); } +std::unique_ptr<ScopedExtensionUpdaterKeepAlive> +ChromeExtensionsBrowserClient::CreateUpdaterKeepAlive( + content::BrowserContext* context) { + return std::make_unique<UpdaterKeepAlive>( + Profile::FromBrowserContext(context), + ProfileKeepAliveOrigin::kExtensionUpdater); +} + bool ChromeExtensionsBrowserClient::IsActivityLoggingEnabled( content::BrowserContext* context) { ActivityLog* activity_log = ActivityLog::GetInstance(context);
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h index 626bfc79..4051f87 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.h +++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -34,6 +34,7 @@ class ChromeComponentExtensionResourceManager; class ChromeExtensionsAPIClient; class ChromeProcessManagerDelegate; +class ScopedExtensionUpdaterKeepAlive; // Implementation of BrowserClient for Chrome, which includes // knowledge of Profiles, BrowserContexts and incognito. @@ -137,6 +138,8 @@ mojom::ViewType view_type) override; scoped_refptr<update_client::UpdateClient> CreateUpdateClient( content::BrowserContext* context) override; + std::unique_ptr<ScopedExtensionUpdaterKeepAlive> CreateUpdaterKeepAlive( + content::BrowserContext* context) override; bool IsActivityLoggingEnabled(content::BrowserContext* context) override; void GetTabAndWindowIdForWebContents(content::WebContents* web_contents, int* tab_id,
diff --git a/chrome/browser/extensions/chrome_test_extension_loader.cc b/chrome/browser/extensions/chrome_test_extension_loader.cc index d5722162a..8130a37 100644 --- a/chrome/browser/extensions/chrome_test_extension_loader.cc +++ b/chrome/browser/extensions/chrome_test_extension_loader.cc
@@ -27,6 +27,7 @@ #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/browser/user_script_loader.h" #include "extensions/browser/user_script_manager.h" +#include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/content_scripts_handler.h" #include "extensions/common/manifest_handlers/incognito_info.h" @@ -337,16 +338,24 @@ const Extension& extension) { if (ignore_manifest_warnings_) return true; + const std::vector<InstallWarning>& install_warnings = extension.install_warnings(); - if (install_warnings.empty()) + std::string install_warnings_string; + for (const InstallWarning& warning : install_warnings) { + // Don't fail on the manifest v2 deprecation warning in tests for now. + // TODO(https://crbug.com/1269161): Stop skipping this warning when all + // tests are updated to MV3. + if (warning.message == manifest_errors::kManifestV2IsDeprecatedWarning) + continue; + install_warnings_string += " " + warning.message + "\n"; + } + + if (install_warnings_string.empty()) return true; - std::string install_warnings_message = "Unexpected warnings for extension:\n"; - for (const InstallWarning& warning : install_warnings) - install_warnings_message += " " + warning.message + "\n"; - - ADD_FAILURE() << install_warnings_message; + ADD_FAILURE() << "Unexpected warnings for extension:\n" + << install_warnings_string; return false; }
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 182a896..5643078a 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -371,13 +371,11 @@ l10n_util::GetStringUTF16(IDS_EXTENSION_MANIFEST_INVALID)); } - // The checks below are skipped for themes, external installs, and bookmark - // apps. + // The checks below are skipped for themes and external installs. // TODO(pamg): After ManagementPolicy refactoring is complete, remove this // and other uses of install_source_ that are no longer needed now that the // SandboxedUnpacker sets extension->location. - if (extension->is_theme() || extension->from_bookmark() || - Manifest::IsExternalLocation(install_source_)) { + if (extension->is_theme() || Manifest::IsExternalLocation(install_source_)) { return absl::nullopt; } @@ -653,12 +651,6 @@ } } - // Skip the checks if the extension is a bookmark app. - if (extension()->from_bookmark()) { - ConfirmInstall(); - return; - } - // Run the policy, requirements and blocklist checks in parallel. check_group_ = std::make_unique<PreloadCheckGroup>(); @@ -863,13 +855,6 @@ creation_flags_ |= Extension::FROM_WEBSTORE; } - // Bookmark apps being updated is kind of a contradiction, but that's because - // we mark the default apps as bookmark apps, and they're hosted in the web - // store, thus they can get updated. See http://crbug.com/101605 for more - // details. - if (extension->from_bookmark()) - creation_flags_ |= Extension::FROM_BOOKMARK; - if (extension->was_installed_by_default()) creation_flags_ |= Extension::WAS_INSTALLED_BY_DEFAULT;
diff --git a/chrome/browser/extensions/error_console/error_console_browsertest.cc b/chrome/browser/extensions/error_console/error_console_browsertest.cc index 30ba2fd..62be1729 100644 --- a/chrome/browser/extensions/error_console/error_console_browsertest.cc +++ b/chrome/browser/extensions/error_console/error_console_browsertest.cc
@@ -127,6 +127,15 @@ manifest_error->manifest_specific()); } +// Checks that a given `error` refers to an error for using a deprecated +// manifest version. +void CheckDeprecatedManifestVersionError(const ExtensionError* error, + const std::string& id) { + CheckManifestError(error, id, manifest_errors::kManifestV2IsDeprecatedWarning, + manifest_keys::kManifestVersion, + std::string() /* no manifest_specific bit */); +} + } // namespace class ErrorConsoleBrowserTest : public ExtensionBrowserTest { @@ -412,8 +421,9 @@ const Extension* extension = nullptr; LoadExtensionAndCheckErrors( "browser_action_runtime_error", {.ignore_manifest_warnings = false}, - 1u, // One error: A reference error from within the browser action. - ACTION_BROWSER_ACTION, &extension); + // Two errors: An error for running a deprecated manifest version and + // a reference error from within the browser action. + 2u, ACTION_BROWSER_ACTION, &extension); std::string script_url = extension->GetResourceURL("browser_action.js").spec(); @@ -421,18 +431,20 @@ const ErrorList& errors = error_console()->GetErrorsForExtension(extension->id()); + CheckDeprecatedManifestVersionError(errors[0].get(), extension->id()); + // TODO(devlin): The specific event name (here, 'browserAction.onClicked') // may or may not be worth preserving. In most cases, it's unnecessary with // the line number, but it could be useful in some cases. std::string message = "Error in event handler: ReferenceError: baz is not defined"; - CheckRuntimeError(errors[0].get(), extension->id(), script_url, + CheckRuntimeError(errors[1].get(), extension->id(), script_url, false, // not incognito message, logging::LOG_ERROR, extension->GetResourceURL(kBackgroundPageName), 1u); - const StackTrace& stack_trace = GetStackTraceFromError(errors[0].get()); + const StackTrace& stack_trace = GetStackTraceFromError(errors[1].get()); // Note: This test used to have a stack trace of length 6 that contains stack // frames in the extension code, but since crbug.com/404406 was fixed only // stack frames within user-defined extension code are printed. @@ -445,23 +457,26 @@ const Extension* extension = nullptr; LoadExtensionAndCheckErrors( "bad_api_arguments_runtime_error", {.ignore_manifest_warnings = false}, - 1, // One error: call an API with improper arguments. - ACTION_NONE, &extension); + // Two errors: An error for running a deprecated manifest version and an + // error for calling an API with improper arguments. + 2, ACTION_NONE, &extension); const ErrorList& errors = error_console()->GetErrorsForExtension(extension->id()); + CheckDeprecatedManifestVersionError(errors[0].get(), extension->id()); + std::string source = extension->GetResourceURL("background.js").spec(); std::string message = "Uncaught TypeError: Error in invocation of tabs.get" "(integer tabId, function callback): No matching signature."; - CheckRuntimeError(errors[0].get(), extension->id(), source, + CheckRuntimeError(errors[1].get(), extension->id(), source, false, // not incognito message, logging::LOG_ERROR, extension->GetResourceURL(kBackgroundPageName), 1u); - const StackTrace& stack_trace = GetStackTraceFromError(errors[0].get()); + const StackTrace& stack_trace = GetStackTraceFromError(errors[1].get()); ASSERT_EQ(1u, stack_trace.size()); CheckStackFrame(stack_trace[0], source, kAnonymousFunction); } @@ -472,23 +487,26 @@ const Extension* extension = nullptr; LoadExtensionAndCheckErrors( "bad_api_permissions_runtime_error", {.ignore_manifest_warnings = false}, - 1, // One error: we try to call addUrl() on chrome.history without - // permission, which results in a TypeError. - ACTION_NONE, &extension); + // Two errors: an error for running a deprecated manifest version and an + // error for trying to call addUrl() on chrome.history without permission + // which results in a TypeError. + 2, ACTION_NONE, &extension); std::string script_url = extension->GetResourceURL("background.js").spec(); const ErrorList& errors = error_console()->GetErrorsForExtension(extension->id()); - CheckRuntimeError(errors[0].get(), extension->id(), script_url, + CheckDeprecatedManifestVersionError(errors[0].get(), extension->id()); + + CheckRuntimeError(errors[1].get(), extension->id(), script_url, false, // not incognito "Uncaught TypeError: Cannot read properties of undefined " "(reading 'addUrl')", logging::LOG_ERROR, extension->GetResourceURL(kBackgroundPageName), 1u); - const StackTrace& stack_trace = GetStackTraceFromError(errors[0].get()); + const StackTrace& stack_trace = GetStackTraceFromError(errors[1].get()); ASSERT_EQ(1u, stack_trace.size()); CheckStackFrame(stack_trace[0], script_url,
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc index f7d7d55..10e83cc 100644 --- a/chrome/browser/extensions/extension_apitest.cc +++ b/chrome/browser/extensions/extension_apitest.cc
@@ -129,17 +129,23 @@ return false; } - // If there is a page_url to load, navigate it. + GURL url_to_open; if (run_options.page_url) { - GURL url(run_options.page_url); - + url_to_open = GURL(run_options.page_url); // Note: We use is_valid() here in the expectation that the provided url // may lack a scheme & host and thus be a relative url within the loaded // extension. - if (!url.is_valid()) - url = extension->GetResourceURL(run_options.page_url); + // TODO(https://crbug.com/1284691): Update callers passing relative paths + // for page URLs to instead use extension_url. + if (!url_to_open.is_valid()) + url_to_open = extension->GetResourceURL(run_options.page_url); + } else if (run_options.extension_url) { + url_to_open = extension->GetResourceURL(run_options.extension_url); + } - OpenURL(url, run_options.open_in_incognito); + // If there is a page_url to load, navigate it. + if (!url_to_open.is_empty()) { + OpenURL(url_to_open, run_options.open_in_incognito); } else if (run_options.launch_as_platform_app) { apps::AppLaunchParams params(extension->id(), LaunchContainer::kLaunchContainerNone,
diff --git a/chrome/browser/extensions/extension_browser_window_helper.cc b/chrome/browser/extensions/extension_browser_window_helper.cc index 1bab1e7..0e8c88c7 100644 --- a/chrome/browser/extensions/extension_browser_window_helper.cc +++ b/chrome/browser/extensions/extension_browser_window_helper.cc
@@ -27,15 +27,6 @@ bool ShouldCloseTabOnExtensionUnload(const Extension* extension, Browser* browser, content::WebContents* web_contents) { - // Bookmark app extensions are handled by WebAppBrowserController, if enabled. - // TODO(crbug.com/1065748): Remove app_controller() part of the condition - // after unified browser controller launch. - if (extension->from_bookmark() && - (!browser->app_controller() || - browser->app_controller()->AsWebAppBrowserController())) { - return false; - } - // Case 1: A "regular" extension page, e.g. chrome-extension://<id>/page.html. // Note: we check the tuple or precursor tuple in order to close any // windows with opaque origins that were opened by extensions, and may
diff --git a/chrome/browser/extensions/extension_browsertest_browsertest.cc b/chrome/browser/extensions/extension_browsertest_browsertest.cc index e0a8fd53..386bfb0 100644 --- a/chrome/browser/extensions/extension_browsertest_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest_browsertest.cc
@@ -87,11 +87,10 @@ ExtensionHostQueue::GetInstance().SetCustomDelayForTesting(base::Seconds(0)); } -// TODO(devlin): Add support for ServiceWorker-based extensions here as well. -// Currently, we have no good way to wait for the ServiceWorker to be ready. INSTANTIATE_TEST_SUITE_P(All, MultiBackgroundExtensionBrowserTestBrowserTest, testing::Values(BackgroundType::kPersistentPage, - BackgroundType::kLazyPage)); + BackgroundType::kLazyPage, + BackgroundType::kWorker)); } // namespace extensions
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc index d5f9b39ff..c641ea3 100644 --- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc +++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -99,22 +99,10 @@ scoped_refptr<const Extension> BuildExtensionWithActionType( ActionInfo::Type type) { - ExtensionBuilder builder("extension"); - switch (type) { - case ActionInfo::TYPE_BROWSER: - builder.SetAction(ExtensionBuilder::ActionType::BROWSER_ACTION); - break; - case ActionInfo::TYPE_PAGE: - builder.SetAction(ExtensionBuilder::ActionType::PAGE_ACTION); - break; - case ActionInfo::TYPE_ACTION: - builder.SetAction(ExtensionBuilder::ActionType::ACTION); - break; - } - - builder.SetManifestVersion(GetManifestVersionForActionType(type)); - - return builder.Build(); + return ExtensionBuilder("extension") + .SetAction(type) + .SetManifestVersion(GetManifestVersionForActionType(type)) + .Build(); } // Label for test extension menu item. @@ -1588,9 +1576,7 @@ InitializeEmptyExtensionService(); scoped_refptr<const Extension> extension = - ExtensionBuilder("extension") - .SetAction(ExtensionBuilder::ActionType::BROWSER_ACTION) - .Build(); + ExtensionBuilder("extension").SetAction(ActionInfo::TYPE_BROWSER).Build(); InitializeAndAddExtension(*extension); MenuManager* const manager = CreateMenuManager();
diff --git a/chrome/browser/extensions/extension_l10n_browsertest.cc b/chrome/browser/extensions/extension_l10n_browsertest.cc new file mode 100644 index 0000000..d851198b --- /dev/null +++ b/chrome/browser/extensions/extension_l10n_browsertest.cc
@@ -0,0 +1,85 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/file_util.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "extensions/test/test_extension_dir.h" + +namespace extensions { + +using ExtensionL10nBrowserTest = ExtensionApiTest; + +// Tests that extension CSS files are localized. +// See also ContentScriptApiTest.ContentScriptCSSLocalization, which +// tests the localization of content script CSS. We need both of these, +// because the localization happens at different times (content scripts +// are localized as they are loaded into shared memory). +IN_PROC_BROWSER_TEST_F(ExtensionL10nBrowserTest, CSSFilesAreLocalized) { + constexpr char kManifest[] = + R"({ + "name": "CSS Localization Test", + "version": "1", + "manifest_version": 3, + "default_locale": "en" + })"; + constexpr char kStyleCss[] = + R"(p { + /* We have two entries here so that, if the localized one is invalid, + we fall back to the literal. This identifies whether the failure + is in the localization or the CSS file failing to be applied. */ + color: "purple"; + color: __MSG_text_color__; + })"; + constexpr char kPageHtml[] = + R"(<!doctype html> + <html> + <head> + <link href="style.css" rel="stylesheet" type="text/css"> + </head> + <body> + <p id="paragraph">Hello world!</p> + </body> + <script src="test.js"></script> + </html>)"; + constexpr char kTestJs[] = + R"(chrome.test.runTests([ + function checkColor() { + const p = document.getElementById('paragraph'); + chrome.test.assertTrue(!!p); + const color = getComputedStyle(p).color; + const expectedColor = 'rgb(0, 128, 0)'; // "green" + chrome.test.assertEq(expectedColor, color); + chrome.test.succeed(); + } + ]);)"; + constexpr char kMessages[] = + R"({ + "text_color": { "message": "green" } + })"; + TestExtensionDir test_dir; + test_dir.WriteManifest(kManifest); + test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtml); + test_dir.WriteFile(FILE_PATH_LITERAL("style.css"), kStyleCss); + test_dir.WriteFile(FILE_PATH_LITERAL("test.js"), kTestJs); + { + // TODO(https://crbug.com/1135378): It's a bit clunky to write to nested + // files in a TestExtensionDir. + base::ScopedAllowBlockingForTesting allow_blocking; + base::FilePath locales = test_dir.UnpackedPath().AppendASCII("_locales"); + base::FilePath locales_en = locales.AppendASCII("en"); + base::FilePath messages_path = locales_en.AppendASCII("messages.json"); + ASSERT_TRUE(base::CreateDirectory(locales)); + ASSERT_TRUE(base::CreateDirectory(locales_en)); + ASSERT_TRUE(base::WriteFile(messages_path, kMessages)); + } + + ASSERT_TRUE(RunExtensionTest(test_dir.UnpackedPath(), + {.extension_url = "page.html"}, {})) + << message_; +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc index 76ad82b..89d0b19d 100644 --- a/chrome/browser/extensions/extension_service_test_base.cc +++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -53,6 +53,7 @@ #include "extensions/common/extensions_client.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/extensions/install_limiter.h" #endif @@ -153,7 +154,12 @@ ExtensionServiceTestBase::~ExtensionServiceTestBase() { // Why? Because |profile_| has to be destroyed before |at_exit_manager_|, but // is declared above it in the class definition since it's protected. + // TODO(1269752): Since we're getting rid of at_exit_manager_, perhaps + // we don't need this call? profile_.reset(); +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash::KioskAppManager::ResetForTesting(); +#endif } ExtensionServiceTestBase::ExtensionServiceInitParams
diff --git a/chrome/browser/extensions/extension_service_test_base.h b/chrome/browser/extensions/extension_service_test_base.h index 50616cf..84b3b7e 100644 --- a/chrome/browser/extensions/extension_service_test_base.h +++ b/chrome/browser/extensions/extension_service_test_base.h
@@ -10,7 +10,6 @@ #include <memory> #include <string> -#include "base/at_exit.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/raw_ptr.h" @@ -171,10 +170,6 @@ // directory so as to ensure files are closed before cleanup. base::ScopedTempDir temp_dir_; - // Destroying at_exit_manager_ will delete all LazyInstances, so it must come - // after task_environment_ in the destruction order. - base::ShadowingAtExitManager at_exit_manager_; - // The MessageLoop is used by RenderViewHostTestEnabler, so this must be // created before it. std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 434bbc1..6bbe91d2 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -4821,7 +4821,6 @@ registry()->disabled_extensions().GetByID(good_crx); EXPECT_TRUE(extension->from_webstore()); EXPECT_TRUE(extension->was_installed_by_default()); - EXPECT_FALSE(extension->from_bookmark()); // Extension counts shouldn't change. EXPECT_EQ(0u, registry()->enabled_extensions().size());
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc index 8f22dbd..fde411df 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.cc +++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -187,9 +187,8 @@ bool ExtensionSpecialStoragePolicy::NeedsProtection( const extensions::Extension* extension) { - // We only consider "protecting" storage for hosted apps (excluding bookmark - // apps, which are only hosted apps as an implementation detail). - if (!extension->is_hosted_app() || extension->from_bookmark()) + // We only consider "protecting" storage for hosted apps. + if (!extension->is_hosted_app()) return false; // Default-installed apps don't have protected storage.
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc index a29a5c19..cbc00cbb 100644 --- a/chrome/browser/extensions/extension_sync_data.cc +++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -110,26 +110,12 @@ disable_reasons_(disable_reasons), incognito_enabled_(incognito_enabled), remote_install_(remote_install), - version_(extension.from_bookmark() ? base::Version("0") - : extension.version()), + version_(extension.version()), update_url_(update_url), name_(extension.non_localized_name()), app_launch_ordinal_(app_launch_ordinal), page_ordinal_(page_ordinal), - launch_type_(launch_type) { - if (is_app_ && extension.from_bookmark()) { - // TODO(crbug/1065748): remove this dead code. - NOTREACHED(); - extensions::LinkedAppIcons icons = - LinkedAppIcons::GetLinkedAppIcons(&extension); - for (const auto& icon : icons.icons) { - LinkedAppIconInfo linked_icon; - linked_icon.url = icon.url; - linked_icon.size = icon.size; - linked_icons_.push_back(linked_icon); - } - } -} + launch_type_(launch_type) {} ExtensionSyncData::ExtensionSyncData(const ExtensionSyncData& other) = default;
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc index fdd1f57..6f179d2 100644 --- a/chrome/browser/extensions/extension_sync_service.cc +++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -8,6 +8,7 @@ #include "base/auto_reset.h" #include "base/callback_helpers.h" +#include "base/metrics/histogram_functions.h" #include "base/one_shot_event.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_management.h" @@ -183,7 +184,7 @@ std::unique_ptr<ExtensionSet> all_extensions = registry->GenerateInstalledExtensionsSet(); for (const auto& extension : *all_extensions) { - if (extension->from_bookmark()) { + if (extension->from_desprecated_bookmark()) { // Deleting deprecated bookmark apps. const std::string& id = extension->id(); std::u16string error; @@ -193,6 +194,7 @@ LOG(WARNING) << "Failed to uninstall bookmark apps with id '" << id << "' : " << error; } + base::UmaHistogramBoolean("Extensions.UninstallBookmarkApp", uninstalled); } }
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 3d85575..d8b78c0 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/tab_groups/tab_groups_util.h" -#include "chrome/browser/extensions/api/tabs/tabs_api.h" #include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/browser_extension_window_controller.h" #include "chrome/browser/extensions/chrome_extension_function_details.h"
diff --git a/chrome/browser/extensions/extension_tab_util_unittest.cc b/chrome/browser/extensions/extension_tab_util_unittest.cc index bca4bc019..df9befa6 100644 --- a/chrome/browser/extensions/extension_tab_util_unittest.cc +++ b/chrome/browser/extensions/extension_tab_util_unittest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/api/tabs/tabs_constants.h" -#include "chrome/common/extensions/api/tabs.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.cc b/chrome/browser/extensions/extension_uninstall_dialog.cc index c91d7171..3e803f5 100644 --- a/chrome/browser/extensions/extension_uninstall_dialog.cc +++ b/chrome/browser/extensions/extension_uninstall_dialog.cc
@@ -116,8 +116,6 @@ show_report_abuse_checkbox_ = extension_management->UpdatesFromWebstore(*extension_); - show_remove_data_checkbox_ = extension_->from_bookmark(); - // Track that extension uninstalled externally. registry_observation_.Observe(ExtensionRegistry::Get(profile_)); @@ -197,26 +195,18 @@ } bool ExtensionUninstallDialog::ShouldShowCheckbox() const { - return show_report_abuse_checkbox_ || show_remove_data_checkbox_; + return show_report_abuse_checkbox_; } std::u16string ExtensionUninstallDialog::GetCheckboxLabel() const { DCHECK(ShouldShowCheckbox()); - if (show_report_abuse_checkbox_) { - return triggering_extension_.get() - ? l10n_util::GetStringFUTF16( - IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE_FROM_EXTENSION, - base::UTF8ToUTF16(extension_->name())) - : l10n_util::GetStringUTF16( - IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE); - } - - DCHECK(show_remove_data_checkbox_); - return l10n_util::GetStringFUTF16( - IDS_EXTENSION_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX, - url_formatter::FormatUrlForSecurityDisplay( - GetLaunchURL(), url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); + return triggering_extension_.get() + ? l10n_util::GetStringFUTF16( + IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE_FROM_EXTENSION, + base::UTF8ToUTF16(extension_->name())) + : l10n_util::GetStringUTF16( + IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE); } void ExtensionUninstallDialog::OnDialogClosed(CloseAction action) { @@ -224,12 +214,6 @@ // closed. registry_observation_.Reset(); - if (show_remove_data_checkbox_) { - // TODO(crbug.com/1065748): Delete Webapp recording in extensions dialog. - UMA_HISTOGRAM_ENUMERATION("Webapp.UninstallDialogAction", action, - CLOSE_ACTION_LAST); - } - bool success = false; std::u16string error; switch (action) { @@ -240,24 +224,12 @@ "Extensions.UninstallDialogReportAbuseChecked")); base::RecordAction( base::UserMetricsAction("Extensions.UninstallDialogRemoveClick")); - if (show_remove_data_checkbox_) { - content::ClearSiteData( - base::BindRepeating( - [](content::BrowserContext* browser_context) { - return browser_context; - }, - base::Unretained(profile_)), - url::Origin::Create(GetLaunchURL()), true /*clear_cookies*/, - true /*clear_storage*/, true /*clear_cache*/, - false /*avoid_closing_connections*/, base::DoNothing()); - } else { - // If the extension specifies a custom uninstall page via - // chrome.runtime.setUninstallURL, then at uninstallation its uninstall - // page opens. To ensure that the CWS Report Abuse page is the active - // tab at uninstallation, HandleReportAbuse() is called after - // Uninstall(). - HandleReportAbuse(); - } + // If the extension specifies a custom uninstall page via + // chrome.runtime.setUninstallURL, then at uninstallation its uninstall + // page opens. To ensure that the CWS Report Abuse page is the active + // tab at uninstallation, HandleReportAbuse() is called after + // Uninstall(). + HandleReportAbuse(); break; case CLOSE_ACTION_UNINSTALL: base::RecordAction(
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.h b/chrome/browser/extensions/extension_uninstall_dialog.h index b9429831..5f8b66bb 100644 --- a/chrome/browser/extensions/extension_uninstall_dialog.h +++ b/chrome/browser/extensions/extension_uninstall_dialog.h
@@ -180,9 +180,6 @@ // True if a checkbox for reporting abuse is shown. bool show_report_abuse_checkbox_ = false; - // True if a checkbox for removing associated data is shown. - bool show_remove_data_checkbox_ = false; - // Whether the extension was uninstalled before the user closed the dialog // (e.g. by another source). bool extension_uninstalled_early_ = false;
diff --git a/chrome/browser/extensions/external_provider_impl.cc b/chrome/browser/extensions/external_provider_impl.cc index 74f300e..23e3198 100644 --- a/chrome/browser/extensions/external_provider_impl.cc +++ b/chrome/browser/extensions/external_provider_impl.cc
@@ -211,12 +211,12 @@ std::set<std::string> removed_extensions; // Find extensions that were removed by this ExternalProvider. - for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) { - const std::string& extension_id = i.key(); + for (const auto kv : prefs_->DictItems()) { + const std::string& extension_id = kv.first; // Don't bother about invalid ids. if (!crx_file::id_util::IdIsValid(extension_id)) continue; - if (!prefs->HasKey(extension_id)) + if (!prefs->FindKey(extension_id)) removed_extensions.insert(extension_id); } @@ -534,7 +534,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); CHECK(prefs_.get()); CHECK(ready_); - return prefs_->HasKey(id); + return prefs_->FindKey(id); } bool ExternalProviderImpl::GetExtensionDetails( @@ -549,18 +549,19 @@ return false; ManifestLocation loc = ManifestLocation::kInvalidLocation; - if (extension->HasKey(kExternalUpdateUrl)) { + if (extension->FindKey(kExternalUpdateUrl)) { loc = download_location_; - } else if (extension->HasKey(kExternalCrx)) { + } else if (extension->FindKey(kExternalCrx)) { loc = crx_location_; - std::string external_version; - if (!extension->GetString(kExternalVersion, &external_version)) + const std::string* external_version = + extension->FindStringKey(kExternalVersion); + if (!external_version) return false; if (version) - *version = std::make_unique<base::Version>(external_version); + *version = std::make_unique<base::Version>(*external_version); } else { NOTREACHED(); // Chrome should not allow prefs to get into this state.
diff --git a/chrome/browser/extensions/install_signer.cc b/chrome/browser/extensions/install_signer.cc index 5b477ac0..627f300 100644 --- a/chrome/browser/extensions/install_signer.cc +++ b/chrome/browser/extensions/install_signer.cc
@@ -206,11 +206,10 @@ // Note: earlier versions of the code did not write out a timestamp value // so older entries will not necessarily have this. - if (value.HasKey(kTimestampKey)) { - std::string timestamp; + if (const base::Value* timestamp = value.FindKey(kTimestampKey)) { int64_t timestamp_value = 0; - if (!value.GetString(kTimestampKey, ×tamp) || - !base::StringToInt64(timestamp, ×tamp_value)) { + if (!timestamp->is_string() || + !base::StringToInt64(timestamp->GetString(), ×tamp_value)) { result.reset(); return result; }
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index 3f3baf0..78c0a286 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc
@@ -888,10 +888,6 @@ base::BindOnce(&MenuManager::ReadFromStorage, AsWeakPtr(), extension->id())); } - - if (extension->from_bookmark() && UrlHandlers::GetUrlHandlers(extension)) { - icon_manager_.LoadIcon(browser_context_, extension); - } } void MenuManager::OnExtensionUnloaded(content::BrowserContext* browser_context,
diff --git a/chrome/browser/extensions/native_bindings_apitest.cc b/chrome/browser/extensions/native_bindings_apitest.cc index 99be6a85..460b14e 100644 --- a/chrome/browser/extensions/native_bindings_apitest.cc +++ b/chrome/browser/extensions/native_bindings_apitest.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/extensions/standard_management_policy_provider.cc b/chrome/browser/extensions/standard_management_policy_provider.cc index 10ce34263fa..bee1544 100644 --- a/chrome/browser/extensions/standard_management_policy_provider.cc +++ b/chrome/browser/extensions/standard_management_policy_provider.cc
@@ -83,14 +83,6 @@ if (extension->is_shared_module()) return true; - // Always allow bookmark apps. The fact that bookmark apps are an extension is - // an internal implementation detail and hence they should not be controlled - // by extension management policies. See crbug.com/786061. - // TODO(calamity): This special case should be removed by removing bookmark - // apps from external sources. See crbug.com/788245. - if (extension->from_bookmark()) - return true; - // Check whether the extension type is allowed. // // If you get a compile error here saying that the type you added is not
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 0192928..8ff6a58 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -216,7 +216,6 @@ if (extension) { DCHECK(extension->is_app()); - DCHECK(!extension->from_bookmark()); } extension_app_ = extension; @@ -318,8 +317,7 @@ ExtensionRegistry::EVERYTHING); if (extension && AppLaunchInfo::GetFullLaunchURL(extension).is_valid()) { DCHECK(extension->is_app()); - if (!extension->from_bookmark()) - SetExtensionApp(extension); + SetExtensionApp(extension); } } else { UpdateExtensionAppIcon(
diff --git a/chrome/browser/extensions/window_controller.cc b/chrome/browser/extensions/window_controller.cc index 7ffbd0ec..4eb8e3e8 100644 --- a/chrome/browser/extensions/window_controller.cc +++ b/chrome/browser/extensions/window_controller.cc
@@ -9,7 +9,6 @@ #include <memory> #include "base/values.h" -#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/windows.h"
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc index 399481f6..d08741de 100644 --- a/chrome/browser/extensions/window_open_apitest.cc +++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -32,6 +32,7 @@ #include "extensions/browser/process_manager.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" +#include "extensions/common/manifest_constants.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/dns/mock_host_resolver.h" @@ -543,10 +544,14 @@ test_data_dir_.AppendASCII("locked_fullscreen/with_permission"), {.ignore_manifest_warnings = true}); ASSERT_TRUE(extension); - EXPECT_EQ(1u, extension->install_warnings().size()); + EXPECT_EQ(2u, extension->install_warnings().size()); + // TODO(https://crbug.com/1269161): Remove the check for the deprecated + // manifest version when the test extension is updated to MV3. + EXPECT_EQ(manifest_errors::kManifestV2IsDeprecatedWarning, + extension->install_warnings()[0].message); EXPECT_EQ(std::string("'lockWindowFullscreenPrivate' " "is not allowed for specified platform."), - extension->install_warnings().front().message); + extension->install_warnings()[1].message); } #endif
diff --git a/chrome/browser/file_select_helper.h b/chrome/browser/file_select_helper.h index b886b862..c46f7be7 100644 --- a/chrome/browser/file_select_helper.h +++ b/chrome/browser/file_select_helper.h
@@ -89,6 +89,7 @@ FRIEND_TEST_ALL_PREFIXES(FileSelectHelperTest, ContentAnalysisCompletionCallback_OKBadFiles); FRIEND_TEST_ALL_PREFIXES(FileSelectHelperTest, GetFileTypesFromAcceptType); + FRIEND_TEST_ALL_PREFIXES(FileSelectHelperTest, MultipleFileExtensionsForMime); explicit FileSelectHelper(Profile* profile); ~FileSelectHelper() override;
diff --git a/chrome/browser/file_select_helper_unittest.cc b/chrome/browser/file_select_helper_unittest.cc index 6ad321c..635cade 100644 --- a/chrome/browser/file_select_helper_unittest.cc +++ b/chrome/browser/file_select_helper_unittest.cc
@@ -394,4 +394,37 @@ ASSERT_EQ(expected_extensions, file_type_info->extensions); } +// This test depends on platform-specific mappings from mime types to file +// extensions in PlatformMimeUtil. It would seem that Linux does not offer a way +// to get extensions, and our Windows implementation still needs to be updated. +#if defined(OS_MAC) +TEST_F(FileSelectHelperTest, MultipleFileExtensionsForMime) { + content::BrowserTaskEnvironment task_environment; + TestingProfile profile; + scoped_refptr<FileSelectHelper> file_select_helper = + new FileSelectHelper(&profile); + + std::vector<std::u16string> accept_types{u"application/vnd.ms-powerpoint"}; + std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> file_type_info = + file_select_helper->GetFileTypesFromAcceptType(accept_types); + + std::vector<base::FilePath::StringType> expected_extensions { +#if defined(OS_WIN) + L"ppt", L"pot", L"pps" + }; +#else + "ppt", "pot", "pps" + }; +#endif + std::sort(expected_extensions.begin(), expected_extensions.end()); + + ASSERT_EQ(file_type_info->extensions.size(), 1u); + std::vector<base::FilePath::StringType> actual_extensions = + file_type_info->extensions[0]; + std::sort(actual_extensions.begin(), actual_extensions.end()); + + EXPECT_EQ(expected_extensions, actual_extensions); +} +#endif + #endif // BUILDFLAG(FULL_SAFE_BROWSING)
diff --git a/chrome/browser/file_system_access/file_system_access_permission_request_manager.cc b/chrome/browser/file_system_access/file_system_access_permission_request_manager.cc index 79a9262..8339f3e 100644 --- a/chrome/browser/file_system_access/file_system_access_permission_request_manager.cc +++ b/chrome/browser/file_system_access/file_system_access_permission_request_manager.cc
@@ -95,7 +95,7 @@ bool FileSystemAccessPermissionRequestManager::CanShowRequest() const { // Deley showing requests until the main frame is fully loaded. // ScheduleShowRequest() will be called again when that happens. - return web_contents()->IsDocumentOnLoadCompletedInMainFrame() && + return web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame() && !queued_requests_.empty() && !current_request_; } @@ -131,8 +131,7 @@ } void FileSystemAccessPermissionRequestManager:: - DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { + DocumentOnLoadCompletedInPrimaryMainFrame() { // This is scheduled because while all calls to the browser have been // issued at DOMContentLoaded, they may be bouncing around in scheduled // callbacks finding the UI thread still. This makes sure we allow those
diff --git a/chrome/browser/file_system_access/file_system_access_permission_request_manager.h b/chrome/browser/file_system_access/file_system_access_permission_request_manager.h index aca9665..67bc2cf7 100644 --- a/chrome/browser/file_system_access/file_system_access_permission_request_manager.h +++ b/chrome/browser/file_system_access/file_system_access_permission_request_manager.h
@@ -93,8 +93,7 @@ void DequeueAndShowRequest(); // WebContentsObserver - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void OnPermissionDialogResult(permissions::PermissionAction result);
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index 407d8270..18e21abc 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc
@@ -369,7 +369,7 @@ } bool IsOnWelcomePage(content::WebContents* contents) { - return contents->GetURL().GetWithEmptyPath() == + return contents->GetVisibleURL().GetWithEmptyPath() == GURL(chrome::kChromeUIWelcomeURL); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 2f4631ac..0a06ac8 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -438,6 +438,11 @@ "expiry_milestone": 102 }, { + "name": "autofill-enable-update-virtual-card-enrollment", + "owners": [ "siyua", "jsaul@google.com" ], + "expiry_milestone": 105 + }, + { "name": "autofill-enable-virtual-card", "owners": [ "siyua", "jsaul@google.com", "aneeshali@google.com" ], "expiry_milestone": 100 @@ -2187,7 +2192,7 @@ { "name": "enable-input-in-diagnostics-app", "owners": [ "//ash/webui/diagnostics_ui/OWNERS" ], - "expiry_milestone": 98 + "expiry_milestone": 104 }, { "name": "enable-input-noise-cancellation-ui", @@ -2395,11 +2400,6 @@ "expiry_milestone": 100 }, { - "name": "enable-oop-rasterization", - "owners": [ "sunnyps", "vasilyt" ], - "expiry_milestone": 86 - }, - { "name": "enable-oop-rasterization-ddl", "owners": [ "robertphillips", "penghuang" ], "expiry_milestone": 87 @@ -3035,7 +3035,7 @@ { "name": "enhanced_clipboard_screenshot_nudge", "owners":["anasalazar@chromium.org", "gzadina@google.com"], - "expiry_milestone": 94 + "expiry_milestone": 101 }, { "name": "enhanced-network-voices", @@ -5607,8 +5607,8 @@ }, { "name": "use-search-click-for-right-click", - "owners": [ "zentaro", "cros-peripherals@google.com" ], - "expiry_milestone": 95 + "owners": [ "zentaro", "jimmyxgong", "cros-peripherals@google.com" ], + "expiry_milestone": 105 }, { "name": "use-sf-symbols-samples", @@ -5671,6 +5671,12 @@ "expiry_milestone": 100 }, { + "name": "verbose-logging-in-nacl", + "owners": [ "fabiansommer", "native-client-dev@googlegroups.com" ], + // This flag is useful for debugging NaCl-related issues. + "expiry_milestone": 128 + }, + { "name": "vertical-snap", "owners": [ "cattalyya", "afakhry", "nupurjain", "fanafan"], "expiry_milestone": 100
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index a4e7868..db11876 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -350,6 +350,14 @@ "When enabled, Autofill data related icon will be shown in the status " "chip next to the profile avatar icon in the toolbar."; +const char kAutofillEnableUpdateVirtualCardEnrollmentName[] = + "Enable Update Virtual Card Enrollment"; +const char kAutofillEnableUpdateVirtualCardEnrollmentDescription[] = + "When enabled, the user will have the ability to update the virtual card " + "enrollment of a credit card through their chrome browser after certain " + "autofill flows (for example, downstream and upstream), and from the " + "settings page."; + const char kAutofillEnableVirtualCardName[] = "Offer to use cloud token virtual card in Autofill"; const char kAutofillEnableVirtualCardDescription[] = @@ -1838,11 +1846,6 @@ "Allow the default search engine to specify prefetch behavior for " "suggestions to search results pages."; -const char kOopRasterizationName[] = "Out-of-process rasterization"; -const char kOopRasterizationDescription[] = - "Perform Ganesh raster in the GPU Process instead of the renderer. " - "Must also enable GPU rasterization"; - const char kOopRasterizationDDLName[] = "Out of process rasterization using DDLs"; const char kOopRasterizationDDLDescription[] = @@ -2194,11 +2197,6 @@ "Shows a link to manage the user's devices below the device list when " "sharing"; -extern const char kSendTabToSelfV2Name[] = "Send tab to self 2.0"; -extern const char kSendTabToSelfV2Description[] = - "Enables new received tab " - "UI shown next to the profile icon instead of using system notifications."; - const char kShoppingListName[] = "Shopping List"; const char kShoppingListDescription[] = "Enable shopping list in bookmarks."; @@ -3479,6 +3477,11 @@ const char kSecurePaymentConfirmationAndroidDescription[] = "Enables Secure Payment Confirmation on Android."; +const char kSendTabToSelfV2Name[] = "Send tab to self 2.0"; +const char kSendTabToSelfV2Description[] = + "Enables new received tab " + "UI shown next to the profile icon instead of using system notifications."; + const char kSetMarketUrlForTestingName[] = "Set market URL for testing"; const char kSetMarketUrlForTestingDescription[] = "When enabled, sets the market URL for use in testing the update menu " @@ -4432,12 +4435,6 @@ "Enable Zero State App Reinstall Suggestions feature in launcher, which " "will show app reinstall recommendations at end of zero state list."; -const char kEnableAssistantLauncherIntegrationName[] = - "Assistant & Launcher integration"; -const char kEnableAssistantLauncherIntegrationDescription[] = - "Combine Launcher search with the power of Assistant to provide the most " - "useful answer for each query. Requires Assistant to be enabled."; - const char kEnableAssistantRoutinesName[] = "Assistant Routines"; const char kEnableAssistantRoutinesDescription[] = "Enable Assistant Routines."; @@ -5449,6 +5446,16 @@ const char kNaclDescription[] = "Support Native Client for all web applications, even those that were not " "installed from the Chrome Web Store."; +const char kVerboseLoggingInNaclName[] = "Verbose logging in Native Client"; +const char kVerboseLoggingInNaclDescription[] = + "Control the level of verbose logging in Native Client modules for " + "debugging purposes."; +const char kVerboseLoggingInNaclChoiceDefault[] = "Default"; +const char kVerboseLoggingInNaclChoiceLow[] = "Low"; +const char kVerboseLoggingInNaclChoiceMedium[] = "Medium"; +const char kVerboseLoggingInNaclChoiceHigh[] = "High"; +const char kVerboseLoggingInNaclChoiceHighest[] = "Highest"; +const char kVerboseLoggingInNaclChoiceDisabled[] = "Disabled"; #endif // ENABLE_NACL #if BUILDFLAG(ENABLE_OOP_PRINTING)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index cf3bb4e8..b42399db 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -207,6 +207,9 @@ extern const char kAutofillEnableToolbarStatusChipName[]; extern const char kAutofillEnableToolbarStatusChipDescription[]; +extern const char kAutofillEnableUpdateVirtualCardEnrollmentName[]; +extern const char kAutofillEnableUpdateVirtualCardEnrollmentDescription[]; + extern const char kAutofillEnableVirtualCardName[]; extern const char kAutofillEnableVirtualCardDescription[]; @@ -1262,9 +1265,6 @@ extern const char kSendTabToSelfManageDevicesLinkName[]; extern const char kSendTabToSelfManageDevicesLinkDescription[]; -extern const char kSendTabToSelfV2Name[]; -extern const char kSendTabToSelfV2Description[]; - extern const char kShoppingListName[]; extern const char kShoppingListDescription[]; @@ -2000,6 +2000,9 @@ extern const char kSecurePaymentConfirmationAndroidName[]; extern const char kSecurePaymentConfirmationAndroidDescription[]; +extern const char kSendTabToSelfV2Name[]; +extern const char kSendTabToSelfV2Description[]; + extern const char kSetMarketUrlForTestingName[]; extern const char kSetMarketUrlForTestingDescription[]; @@ -2548,9 +2551,6 @@ extern const char kEnableAppReinstallZeroStateName[]; extern const char kEnableAppReinstallZeroStateDescription[]; -extern const char kEnableAssistantLauncherIntegrationName[]; -extern const char kEnableAssistantLauncherIntegrationDescription[]; - extern const char kEnableAssistantRoutinesName[]; extern const char kEnableAssistantRoutinesDescription[]; @@ -3168,6 +3168,15 @@ #if BUILDFLAG(ENABLE_NACL) extern const char kNaclName[]; extern const char kNaclDescription[]; + +extern const char kVerboseLoggingInNaclName[]; +extern const char kVerboseLoggingInNaclDescription[]; +extern const char kVerboseLoggingInNaclChoiceDefault[]; +extern const char kVerboseLoggingInNaclChoiceLow[]; +extern const char kVerboseLoggingInNaclChoiceMedium[]; +extern const char kVerboseLoggingInNaclChoiceHigh[]; +extern const char kVerboseLoggingInNaclChoiceHighest[]; +extern const char kVerboseLoggingInNaclChoiceDisabled[]; #endif // ENABLE_NACL #if BUILDFLAG(ENABLE_OOP_PRINTING)
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index f7b75e4..ddfeffdc 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -213,6 +213,7 @@ &kContextualTriggersSelectionMenu, &kContextualTriggersSelectionSize, &kDirectActions, + &kDisableCompositedProgressBar, &kDownloadFileProvider, &kDownloadNotificationBadge, &kDownloadProgressInfoBar, @@ -578,6 +579,9 @@ const base::Feature kDirectActions{"DirectActions", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kDisableCompositedProgressBar{ + "DisableCompositedProgressBar", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kDownloadAutoResumptionThrottling{ "DownloadAutoResumptionThrottling", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 83ad0a9..c9bf5c9 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -79,6 +79,7 @@ extern const base::Feature kContextualTriggersSelectionSize; extern const base::Feature kQuickActionSearchWidgetAndroidDinoVariant; extern const base::Feature kDirectActions; +extern const base::Feature kDisableCompositedProgressBar; extern const base::Feature kDontPrefetchLibraries; extern const base::Feature kDownloadAutoResumptionThrottling; extern const base::Feature kDownloadFileProvider;
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 bb26fde..2d6b15f 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
@@ -305,6 +305,7 @@ "DarkenWebsitesCheckboxInThemesSetting"; public static final String DETAILED_LANGUAGE_SETTINGS = "DetailedLanguageSettings"; public static final String DIRECT_ACTIONS = "DirectActions"; + public static final String DISABLE_COMPOSITED_PROGRESS_BAR = "DisableCompositedProgressBar"; public static final String DNS_OVER_HTTPS = "DnsOverHttps"; public static final String DOWNLOAD_FILE_PROVIDER = "DownloadFileProvider"; public static final String DOWNLOAD_NOTIFICATION_BADGE = "DownloadNotificationBadge";
diff --git a/chrome/browser/fullscreen/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenOptions.java b/chrome/browser/fullscreen/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenOptions.java index 939c927..e29e0bad 100644 --- a/chrome/browser/fullscreen/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenOptions.java +++ b/chrome/browser/fullscreen/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenOptions.java
@@ -10,6 +10,10 @@ public class FullscreenOptions { private boolean mShowNavigationBar; + // Used by FullscreenHtmlApiHandler internally to indicate that the fullscreen request + // associated with this option got canceled at the pending state. + private boolean mCanceled; + /** * Constructs FullscreenOptions. * @@ -26,6 +30,14 @@ return mShowNavigationBar; } + void setCanceled() { + mCanceled = true; + } + + boolean canceled() { + return mCanceled; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof FullscreenOptions)) {
diff --git a/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc index 0def27cc..c15627e 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_delegate_unittest.cc
@@ -72,7 +72,7 @@ permissions::PermissionRequestManager::FromWebContents(web_contents()); permissions::MockPermissionPromptFactory mock_prompt_factory(manager); NavigateAndCommit(requesting_frame); - manager->DocumentOnLoadCompletedInMainFrame(main_rfh()); + manager->DocumentOnLoadCompletedInPrimaryMainFrame(); base::RunLoop run_loop; PermissionManagerFactory::GetForProfile(profile())->RequestPermission(
diff --git a/chrome/browser/lifetime/browser_shutdown.cc b/chrome/browser/lifetime/browser_shutdown.cc index e78f218..d0c32e7 100644 --- a/chrome/browser/lifetime/browser_shutdown.cc +++ b/chrome/browser/lifetime/browser_shutdown.cc
@@ -262,7 +262,7 @@ case RestartMode::kRestartInBackground: new_cl.AppendSwitch(switches::kNoStartupWindow); - FALLTHROUGH; + [[fallthrough]]; case RestartMode::kRestartLastSession: // Relaunch the browser without any command line URLs or certain one-off
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 9da91e6..e2c953d3 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -716,6 +716,36 @@ LookalikeUrlMatchType::kFailedSpoofChecks); } +// The navigated domain will fall back to punycode because it fails standard +// ICU spoof checks in the IDN spoof checker. However, no interstitial will be +// shown as the domain name is single character. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest, + Punycode_ShortHostname_NoInterstitial) { + const GURL kNavigatedUrl = GetURL("τ.com"); + + TestInterstitialNotShown(browser(), kNavigatedUrl); + CheckNoUkm(); +} + +// Same as Punycode_ShortHostname_NoInterstitial but also has target embedding. +// Should show an interstitial this time. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest, + Punycode_ShortHostname_TargetEmbedding_Interstitial) { + if (!target_embedding_enabled()) { + return; + } + const GURL kNavigatedUrl = GetURL("google-com.τ.com"); + const GURL kExpectedSuggestedUrl = GetURLWithoutPath("google.com"); + + base::HistogramTester histograms; + TestMetricsRecordedAndInterstitialShown( + browser(), histograms, kNavigatedUrl, kExpectedSuggestedUrl, + NavigationSuggestionEvent::kMatchTargetEmbedding); + + CheckUkm({kNavigatedUrl}, "MatchType", + LookalikeUrlMatchType::kTargetEmbedding); +} + // The navigated domain will fall back to punycode because it fails spoof checks // in IDN spoof checker. The heuristic that changes this domain to punycode // (latin middle dot) is configured to show a punycode interstitial.
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc index 0b1030c3..e67b9ac 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc
@@ -351,7 +351,12 @@ void DialMediaSinkServiceImpl::BindLogger( mojo::PendingRemote<mojom::Logger> pending_remote) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Reset |logger_| if it is bound to a disconnected remote. + if (logger_.is_bound()) + return; logger_.Bind(std::move(pending_remote)); + logger_.reset_on_disconnect(); + logger_->LogInfo(mojom::LogCategory::kDiscovery, kLoggerComponent, "DialMediaSinkService has started.", "", "", ""); }
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc index 035f0c22..6d9e226 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -11,6 +11,7 @@ #include "base/timer/mock_timer.h" #include "chrome/browser/media/router/discovery/dial/dial_device_data.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" +#include "components/media_router/browser/logger_impl.h" #include "content/public/test/browser_task_environment.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -368,4 +369,25 @@ StartMonitoringAvailableSinksForApp("YouTube"); } +TEST_F(DialMediaSinkServiceImplTest, BindLogger) { + std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_1; + logger_1->Bind(pending_remote_1.InitWithNewPipeAndPassReceiver()); + media_sink_service_->BindLogger(std::move(pending_remote_1)); + + // Trying to bind another pending remote no-ops instead of causing + // a DCHECK failure from binding to a remote that's already bound. + std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_2; + logger_2->Bind(pending_remote_2.InitWithNewPipeAndPassReceiver()); + media_sink_service_->BindLogger(std::move(pending_remote_2)); + + // Trying to bind a disconnected receiver should work. + logger_1.reset(); + std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_3; + logger_3->Bind(pending_remote_3.InitWithNewPipeAndPassReceiver()); + media_sink_service_->BindLogger(std::move(pending_remote_3)); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc index ecd08db7..76c8f9f6 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -172,4 +172,8 @@ base::Unretained(impl_.get()), std::move(pending_remote))); } +void CastMediaSinkService::RemoveLogger() { + logger_impl_ = nullptr; +} + } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h index 8a58c66e..dc06a8fe 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -80,6 +80,8 @@ // Marked virtual for tests. virtual void BindLogger(LoggerImpl* logger_impl); + virtual void RemoveLogger(); + private: friend class CastMediaSinkServiceTest;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index d34ca3b..a0dbdb67 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -712,7 +712,11 @@ void CastMediaSinkServiceImpl::BindLogger( mojo::PendingRemote<mojom::Logger> pending_remote) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Reset |logger_| if it is bound to a disconnected remote. + if (logger_.is_bound()) + return; logger_.Bind(std::move(pending_remote)); + logger_.reset_on_disconnect(); } } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 2c3fd624..33a46535 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -22,6 +22,7 @@ #include "components/cast_channel/cast_socket.h" #include "components/cast_channel/cast_socket_service.h" #include "components/cast_channel/cast_test_util.h" +#include "components/media_router/browser/logger_impl.h" #include "components/media_router/common/test/test_helper.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_utils.h" @@ -1333,6 +1334,27 @@ open_params.liveness_timeout.InSeconds()); } +TEST_P(CastMediaSinkServiceImplTest, BindLogger) { + std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_1; + logger_1->Bind(pending_remote_1.InitWithNewPipeAndPassReceiver()); + media_sink_service_impl_.BindLogger(std::move(pending_remote_1)); + + // Trying to bind another pending remote no-ops instead of causing + // a DCHECK failure from binding to a remote that's already bound. + mojo::PendingRemote<mojom::Logger> pending_remote_2; + std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); + logger_2->Bind(pending_remote_2.InitWithNewPipeAndPassReceiver()); + media_sink_service_impl_.BindLogger(std::move(pending_remote_2)); + + // Trying to bind a disconnected receiver should work. + logger_1.reset(); + std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_3; + logger_3->Bind(pending_remote_3.InitWithNewPipeAndPassReceiver()); + media_sink_service_impl_.BindLogger(std::move(pending_remote_3)); +} + INSTANTIATE_TEST_SUITE_P(DialMediaSinkServiceEnabled, CastMediaSinkServiceImplTest, testing::Bool());
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index 0651386..9c0da42f 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -32,7 +32,9 @@ constexpr char kLoggerComponent[] = "MediaRouterDesktop"; #endif -MediaRouterDesktop::~MediaRouterDesktop() = default; +MediaRouterDesktop::~MediaRouterDesktop() { + media_sink_service_->RemoveLogger(); +} void MediaRouterDesktop::OnUserGesture() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc index dd070ed..c570007 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc
@@ -130,7 +130,11 @@ void CastAppDiscoveryServiceImpl::BindLogger( mojo::PendingRemote<mojom::Logger> pending_remote) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Reset |logger_| if it is bound to a disconnected remote. + if (logger_.is_bound()) + return; logger_.Bind(std::move(pending_remote)); + logger_.reset_on_disconnect(); } scoped_refptr<base::SequencedTaskRunner>
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc index 22935eb..cf2a2dc 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/test_simple_task_runner.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" #include "components/cast_channel/cast_test_util.h" +#include "components/media_router/browser/logger_impl.h" #include "components/media_router/common/discovery/media_sink_service_base.h" #include "components/media_router/common/providers/cast/cast_media_source.h" #include "components/media_router/common/test/test_helper.h" @@ -327,4 +328,24 @@ AddOrUpdateSink(sink1); } +TEST_F(CastAppDiscoveryServiceTest, BindLogger) { + std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_1; + logger_1->Bind(pending_remote_1.InitWithNewPipeAndPassReceiver()); + app_discovery_service_->BindLogger(std::move(pending_remote_1)); + + // Trying to bind another pending remote no-ops instead of causing + // a DCHECK failure from binding to a remote that's already bound. + std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_2; + logger_2->Bind(pending_remote_2.InitWithNewPipeAndPassReceiver()); + app_discovery_service_->BindLogger(std::move(pending_remote_2)); + + // Trying to bind a disconnected receiver should work. + logger_1.reset(); + std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); + mojo::PendingRemote<mojom::Logger> pending_remote_3; + logger_3->Bind(pending_remote_3.InitWithNewPipeAndPassReceiver()); + app_discovery_service_->BindLogger(std::move(pending_remote_3)); +} } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc index 66400250..e42a6b3d 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc
@@ -140,4 +140,11 @@ std::move(cast_discovery_pending_remote))); } +void DualMediaSinkService::RemoveLogger() { + if (!logger_is_bound_) + return; + logger_is_bound_ = false; + cast_media_sink_service_->RemoveLogger(); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h index 3d897ab..1026acc 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h
@@ -75,6 +75,8 @@ // Marked virtual for testing. virtual void BindLogger(LoggerImpl* logger_impl); + virtual void RemoveLogger(); + virtual void OnUserGesture(); // Starts mDNS discovery on |cast_media_sink_service_| if it is not already
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc index e1abf2d..66ab988a 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc
@@ -6,7 +6,10 @@ #include "base/bind.h" #include "base/memory/raw_ptr.h" +#include "base/run_loop.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" +#include "components/media_router/browser/logger_impl.h" +#include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,6 +68,9 @@ raw_ptr<MockDialMediaSinkService> dial_media_sink_service_ = nullptr; raw_ptr<MockCastAppDiscoveryService> cast_app_discovery_service_ = nullptr; std::unique_ptr<DualMediaSinkService> dual_media_sink_service_; + + private: + content::BrowserTaskEnvironment task_environment; }; TEST_F(DualMediaSinkServiceTest, OnUserGesture) { @@ -110,4 +116,29 @@ base::Unretained(this))); } +TEST_F(DualMediaSinkServiceTest, BindAndRemoveLogger) { + std::unique_ptr<LoggerImpl> logger = std::make_unique<LoggerImpl>(); + EXPECT_CALL(*cast_media_sink_service_, BindLogger(logger.get())); + EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)); + EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)); + dual_media_sink_service_->BindLogger(logger.get()); + base::RunLoop().RunUntilIdle(); + + // |dual_media_sink_service_| cannot bind a new logger if the old one is not + // removed. + EXPECT_CALL(*cast_media_sink_service_, BindLogger(_)).Times(0); + EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)).Times(0); + EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)).Times(0); + dual_media_sink_service_->BindLogger(logger.get()); + + EXPECT_CALL(*cast_media_sink_service_, RemoveLogger()); + dual_media_sink_service_->RemoveLogger(); + + EXPECT_CALL(*cast_media_sink_service_, BindLogger(logger.get())); + EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)); + EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)); + dual_media_sink_service_->BindLogger(logger.get()); + base::RunLoop().RunUntilIdle(); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/test/noop_dual_media_sink_service.h b/chrome/browser/media/router/test/noop_dual_media_sink_service.h index 81076443..edbe414 100644 --- a/chrome/browser/media/router/test/noop_dual_media_sink_service.h +++ b/chrome/browser/media/router/test/noop_dual_media_sink_service.h
@@ -24,6 +24,7 @@ void OnUserGesture() override {} void StartMdnsDiscovery() override {} void BindLogger(LoggerImpl* logger_impl) override {} + void RemoveLogger() override {} }; } // namespace media_router
diff --git a/chrome/browser/media/router/test/provider_test_helpers.h b/chrome/browser/media/router/test/provider_test_helpers.h index bde335c..bc213851 100644 --- a/chrome/browser/media/router/test/provider_test_helpers.h +++ b/chrome/browser/media/router/test/provider_test_helpers.h
@@ -52,6 +52,7 @@ void(const OnSinksDiscoveredCallback&, MediaSinkServiceBase*)); MOCK_METHOD0(OnUserGesture, void()); MOCK_METHOD1(BindLogger, void(LoggerImpl*)); + MOCK_METHOD0(RemoveLogger, void()); MOCK_METHOD0(StartMdnsDiscovery, void()); };
diff --git a/chrome/browser/metrics/extensions_metrics_provider.cc b/chrome/browser/metrics/extensions_metrics_provider.cc index ac2faae6d..4410e77 100644 --- a/chrome/browser/metrics/extensions_metrics_provider.cc +++ b/chrome/browser/metrics/extensions_metrics_provider.cc
@@ -319,7 +319,8 @@ install.set_is_from_store(extension.from_webstore()); install.set_updates_from_store( extension_management->UpdatesFromWebstore(extension)); - install.set_is_from_bookmark(extension.from_bookmark()); + // TODO(crbug.com/1065748): Remove this setter. + install.set_is_from_bookmark(false); install.set_is_converted_from_user_script( extension.converted_from_user_script()); install.set_is_default_installed(extension.was_installed_by_default());
diff --git a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc index 59f1015..d12d86a 100644 --- a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc
@@ -27,6 +27,7 @@ #include "extensions/browser/blocklist_extension_prefs.h" #include "extensions/browser/disable_reason.h" #include "extensions/browser/extension_prefs.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_set.h" @@ -274,7 +275,7 @@ scoped_refptr<const Extension> extension = ExtensionBuilder("browser_action") .SetLocation(ManifestLocation::kInternal) - .SetAction(ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .Build(); add_extension(extension.get()); ExtensionInstallProto install = ConstructProto(*extension); @@ -286,7 +287,7 @@ scoped_refptr<const Extension> extension = ExtensionBuilder("page_action") .SetLocation(ManifestLocation::kInternal) - .SetAction(ExtensionBuilder::ActionType::PAGE_ACTION) + .SetAction(extensions::ActionInfo::TYPE_PAGE) .Build(); add_extension(extension.get()); ExtensionInstallProto install = ConstructProto(*extension);
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index 66841b7..7005bc9 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -235,6 +235,8 @@ "wasted", EmitTo::kSizeInUmaOnly, nullptr}, {"malloc/partitions/allocator", "Malloc.Fragmentation", MetricSize::kPercentage, "fragmentation", EmitTo::kSizeInUmaOnly, nullptr}, + {"malloc", "Malloc.SyscallsPerMinute", MetricSize::kTiny, + "syscalls_per_minute", EmitTo::kSizeInUmaOnly, nullptr}, #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) {"mojo", "NumberOfMojoHandles", MetricSize::kSmall, MemoryAllocatorDump::kNameObjectCount, EmitTo::kCountsInUkmOnly,
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index 2dfcf70..92c7bd4 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -208,6 +208,11 @@ CheckMemoryMetric( std::string("Memory.Experimental.") + process_type + "2.Malloc.Wasted", histogram_tester, count, ValueRestriction::NONE, number_of_processes); + // Restriction: every process makes at least a system call. + CheckMemoryMetric(std::string("Memory.Experimental.") + process_type + + "2.Tiny.Malloc.SyscallsPerMinute", + histogram_tester, count, ValueRestriction::ABOVE_ZERO, + number_of_processes); #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) }
diff --git a/chrome/browser/metrics/structured/ash_structured_metrics_recorder.cc b/chrome/browser/metrics/structured/ash_structured_metrics_recorder.cc index 0db611d..d4e27788 100644 --- a/chrome/browser/metrics/structured/ash_structured_metrics_recorder.cc +++ b/chrome/browser/metrics/structured/ash_structured_metrics_recorder.cc
@@ -31,9 +31,7 @@ crosapi::CrosapiManager::Get()->crosapi_ash()->BindStructuredMetricsService( remote_.BindNewPipeAndPassReceiver()); is_initialized_ = true; - LogClientInitializationSuccessful(true); } else { - LogClientInitializationSuccessful(false); VLOG(2) << "Initialize() called before CrosApi is initialized."; } }
diff --git a/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc b/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc index 389bb44..9a414642 100644 --- a/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc +++ b/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc
@@ -81,13 +81,9 @@ auto* lacros_recorder = static_cast<LacrosStructuredMetricsRecorder*>(delegate_.get()); - const bool is_current_ui_thread_set = base::CurrentUIThread::IsSet(); - LogClientInitializationSuccessful(is_current_ui_thread_set); - // Ensure that the sequence is the ui thread. - DCHECK(is_current_ui_thread_set); + DCHECK(base::CurrentUIThread::IsSet()); lacros_recorder->SetSequence(base::SequencedTaskRunnerHandle::Get()); - LogClientInitializationSuccessful(true); LogInitializationInStructuredMetrics( StructuredMetricsPlatform::kLacrosChrome); } else {
diff --git a/chrome/browser/net/cookie_store_sameparty_browsertest.cc b/chrome/browser/net/cookie_store_sameparty_browsertest.cc index 2d8c3f1..b90a2c5a 100644 --- a/chrome/browser/net/cookie_store_sameparty_browsertest.cc +++ b/chrome/browser/net/cookie_store_sameparty_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/path_service.h" #include "base/strings/strcat.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -24,6 +25,10 @@ namespace { +using testing::Key; +using testing::Pair; +using testing::UnorderedElementsAre; + const char* kSamePartySameSiteLaxCookieName = "sameparty_samesite_lax_cookie"; const char* kSamePartySameSiteNoneCookieName = "sameparty_samesite_none_cookie"; const char* kSamePartySameSiteUnspecifiedCookieName = @@ -32,16 +37,25 @@ class CookieStoreSamePartyTest : public InProcessBrowserTest { public: - CookieStoreSamePartyTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + explicit CookieStoreSamePartyTest(bool enable_fps) + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS), + enable_fps_(enable_fps) { + if (!enable_fps) { + feature_list_.InitAndDisableFeature(net::features::kFirstPartySets); + } + // If FPS is to be enabled, that happens in `SetUpCommandLine` when the + // `kUseFirstPartySet` switch is provided. + } CookieStoreSamePartyTest(const CookieStoreSamePartyTest&) = delete; CookieStoreSamePartyTest& operator=(const CookieStoreSamePartyTest&) = delete; void SetUpCommandLine(base::CommandLine* command_line) override { InProcessBrowserTest::SetUpCommandLine(command_line); - command_line->AppendSwitchASCII(network::switches::kUseFirstPartySet, - "https://a.test,https://b.test"); + if (enable_fps_) { + command_line->AppendSwitchASCII(network::switches::kUseFirstPartySet, + "https://a.test,https://b.test"); + } } void SetUpOnMainThread() override { @@ -77,6 +91,17 @@ return content::EvalJs(frame, script).ExtractString(); } + std::string GetSamePartyAttributesViaCookieStore( + content::RenderFrameHost* frame) { + return content::EvalJs(frame, R"( + (async () => { + const cookies = await cookieStore.getAll(); + return cookies.map(c => `${c.name}=${c.sameParty}`).join(';'); + })(); + )") + .ExtractString(); + } + void SetSamePartyCookies(const std::string& host) { Profile* profile = browser()->profile(); ASSERT_TRUE(content::SetCookie( @@ -96,15 +121,79 @@ base::StrCat({kSameSiteNoneCookieName, "=1; samesite=none; secure"}))); } + std::string SetSamePartyCookieString(base::StringPiece name, + bool same_party, + base::StringPiece same_site) { + return content::JsReplace( + R"( + (async () => { + await cookieStore.set({name: $1, value: '1', + sameParty: $2, sameSite: $3}); + return true; + })(); + )", + name, same_party, same_site); + } + + void SetSamePartyCookiesViaCookieStore(content::RenderFrameHost* frame, + bool is_same_party_context, + bool site_is_in_fps) { + if (is_same_party_context) { + ASSERT_TRUE(site_is_in_fps); + } + + { + content::EvalJsResult result = content::EvalJs( + frame, SetSamePartyCookieString(kSamePartySameSiteLaxCookieName, true, + "lax")); + if (!is_same_party_context || !site_is_in_fps) { + // If the site is in an FPS and the context isn't same-party, the set + // will fail; otherwise, if the context is cross-site, the set will + // fail. We assume any call is from a cross-site context, so therefore + // any call where the site is not in an FPS should fail. + ASSERT_FALSE(result.error.empty()); + } else { + ASSERT_TRUE(result.ExtractBool()); + } + } + + { + content::EvalJsResult result = content::EvalJs( + frame, SetSamePartyCookieString(kSamePartySameSiteNoneCookieName, + true, "none")); + if (site_is_in_fps && !is_same_party_context) { + ASSERT_FALSE(result.error.empty()); + } else { + ASSERT_TRUE(result.ExtractBool()); + } + } + + // Can't test unspecified SameSite here, since the CookieStore supplies + // 'Strict' when SameSite is not provided explicitly. + + ASSERT_TRUE( + content::EvalJs(frame, SetSamePartyCookieString(kSameSiteNoneCookieName, + false, "none")) + .ExtractBool()); + } + const net::test_server::EmbeddedTestServer& https_server() const { return https_server_; } private: net::test_server::EmbeddedTestServer https_server_; + bool enable_fps_; + base::test::ScopedFeatureList feature_list_; }; -IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyTest, ReadCookies_SamePartyContext) { +class CookieStoreSamePartyEnabledTest : public CookieStoreSamePartyTest { + public: + CookieStoreSamePartyEnabledTest() : CookieStoreSamePartyTest(true) {} +}; + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, + ReadCookies_SamePartyContext) { SetSamePartyCookies("b.test"); ASSERT_TRUE(NavigateToURL( contents(), @@ -113,14 +202,14 @@ "a.test(b.test)"})))); EXPECT_THAT(GetCookiesViaCookieStore(GetDescendantFrame({0})), - net::CookieStringIs(testing::UnorderedElementsAre( - testing::Key(kSamePartySameSiteLaxCookieName), - testing::Key(kSamePartySameSiteNoneCookieName), - testing::Key(kSamePartySameSiteUnspecifiedCookieName), - testing::Key(kSameSiteNoneCookieName)))); + net::CookieStringIs(UnorderedElementsAre( + Key(kSamePartySameSiteLaxCookieName), + Key(kSamePartySameSiteNoneCookieName), + Key(kSamePartySameSiteUnspecifiedCookieName), + Key(kSameSiteNoneCookieName)))); } -IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyTest, +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, ReadCookies_CrossPartyContext) { SetSamePartyCookies("c.test"); ASSERT_TRUE(NavigateToURL( @@ -132,9 +221,9 @@ // c.test isn't in the FPS, so SameParty is ignored, so we get SameSite=None // cookies. EXPECT_THAT(GetCookiesViaCookieStore(GetDescendantFrame({0})), - net::CookieStringIs(testing::UnorderedElementsAre( - testing::Key(kSamePartySameSiteNoneCookieName), - testing::Key(kSameSiteNoneCookieName)))); + net::CookieStringIs( + UnorderedElementsAre(Key(kSamePartySameSiteNoneCookieName), + Key(kSameSiteNoneCookieName)))); ASSERT_EQ(4U, content::DeleteCookies(browser()->profile(), network::mojom::CookieDeletionFilter())); @@ -147,9 +236,139 @@ "a.test(c.test(b.test))"})))); // SameParty is not ignored, so we get the SameSite=None cookie. - EXPECT_THAT(GetCookiesViaCookieStore(GetDescendantFrame({0, 0})), - net::CookieStringIs(testing::UnorderedElementsAre( - testing::Key(kSameSiteNoneCookieName)))); + EXPECT_THAT( + GetCookiesViaCookieStore(GetDescendantFrame({0, 0})), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); +} + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, + ReadAttribute_SamePartyContext) { + SetSamePartyCookies("b.test"); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(b.test)"})))); + + EXPECT_THAT(GetSamePartyAttributesViaCookieStore(GetDescendantFrame({0})), + net::CookieStringIs(UnorderedElementsAre( + Pair(kSamePartySameSiteLaxCookieName, "true"), + Pair(kSamePartySameSiteNoneCookieName, "true"), + Pair(kSamePartySameSiteUnspecifiedCookieName, "true"), + Pair(kSameSiteNoneCookieName, "false")))); +} + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, + ReadAttribute_CrossPartyContext) { + SetSamePartyCookies("c.test"); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test)"})))); + + EXPECT_THAT(GetSamePartyAttributesViaCookieStore(GetDescendantFrame({0})), + net::CookieStringIs(UnorderedElementsAre( + Pair(kSamePartySameSiteNoneCookieName, "true"), + Pair(kSameSiteNoneCookieName, "false")))); + + ASSERT_EQ(4U, content::DeleteCookies(browser()->profile(), + network::mojom::CookieDeletionFilter())); + + SetSamePartyCookies("b.test"); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test(b.test))"})))); + + EXPECT_THAT(GetSamePartyAttributesViaCookieStore(GetDescendantFrame({0, 0})), + net::CookieStringIs(UnorderedElementsAre( + Pair(kSameSiteNoneCookieName, "false")))); +} + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, + WriteCookies_SamePartyContext) { + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(b.test)"})))); + SetSamePartyCookiesViaCookieStore(GetDescendantFrame({0}), + /*is_same_party_context=*/true, + /*site_is_in_fps=*/true); + + EXPECT_THAT(content::GetCookies(browser()->profile(), GURL("https://b.test")), + net::CookieStringIs( + UnorderedElementsAre(Key(kSamePartySameSiteLaxCookieName), + Key(kSamePartySameSiteNoneCookieName), + Key(kSameSiteNoneCookieName)))); +} + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyEnabledTest, + WriteCookies_CrossPartyContext) { + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test)"})))); + SetSamePartyCookiesViaCookieStore(GetDescendantFrame({0}), + /*is_same_party_context=*/false, + /*site_is_in_fps=*/false); + + EXPECT_THAT(content::GetCookies(browser()->profile(), GURL("https://c.test")), + net::CookieStringIs( + UnorderedElementsAre(Key(kSamePartySameSiteNoneCookieName), + Key(kSameSiteNoneCookieName)))); + + ASSERT_GE(2U, content::DeleteCookies(browser()->profile(), + network::mojom::CookieDeletionFilter())); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test(b.test))"})))); + SetSamePartyCookiesViaCookieStore(GetDescendantFrame({0, 0}), + /*is_same_party_context=*/false, + /*site_is_in_fps=*/true); + EXPECT_THAT( + content::GetCookies(browser()->profile(), GURL("https://b.test")), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); +} + +class CookieStoreSamePartyDisabledTest : public CookieStoreSamePartyTest { + public: + CookieStoreSamePartyDisabledTest() : CookieStoreSamePartyTest(false) {} +}; + +IN_PROC_BROWSER_TEST_F(CookieStoreSamePartyDisabledTest, + ReadAttribute_CrossPartyContext) { + SetSamePartyCookies("c.test"); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test)"})))); + + EXPECT_THAT(GetSamePartyAttributesViaCookieStore(GetDescendantFrame({0})), + net::CookieStringIs(UnorderedElementsAre( + Pair(kSamePartySameSiteNoneCookieName, "undefined"), + Pair(kSameSiteNoneCookieName, "undefined")))); + + ASSERT_EQ(4U, content::DeleteCookies(browser()->profile(), + network::mojom::CookieDeletionFilter())); + + SetSamePartyCookies("b.test"); + ASSERT_TRUE(NavigateToURL( + contents(), + https_server().GetURL("a.test", + base::StrCat({"/cross_site_iframe_factory.html?", + "a.test(c.test(b.test))"})))); + + EXPECT_THAT(GetSamePartyAttributesViaCookieStore(GetDescendantFrame({0, 0})), + net::CookieStringIs(UnorderedElementsAre( + Pair(kSamePartySameSiteNoneCookieName, "undefined"), + Pair(kSameSiteNoneCookieName, "undefined")))); } } // namespace
diff --git a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc index baef16dd..fe52aa5 100644 --- a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc +++ b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc
@@ -283,7 +283,7 @@ false /*update_db*/); break; case UserFeedback::kNoFeedback: - FALLTHROUGH; + [[fallthrough]]; default: // The user didn't interact with the notification yet. continue;
diff --git a/chrome/browser/offline_pages/background_loader_offliner.cc b/chrome/browser/offline_pages/background_loader_offliner.cc index 17d3369..d8e7b83 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.cc +++ b/chrome/browser/offline_pages/background_loader_offliner.cc
@@ -248,17 +248,16 @@ AddLoadingSignal("DocumentAvailableInMainFrame"); } -void BackgroundLoaderOffliner::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void BackgroundLoaderOffliner::DocumentOnLoadCompletedInPrimaryMainFrame() { if (!pending_request_.get()) { DVLOG(1) << "DidStopLoading called even though no pending request."; return; } // Add this signal to signal_data_. - AddLoadingSignal("DocumentOnLoadCompletedInMainFrame"); + AddLoadingSignal("DocumentOnLoadCompletedInPrimaryMainFrame"); - snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); + snapshot_controller_->DocumentOnLoadCompletedInPrimaryMainFrame(); } void BackgroundLoaderOffliner::PrimaryMainFrameRenderProcessGone(
diff --git a/chrome/browser/offline_pages/background_loader_offliner.h b/chrome/browser/offline_pages/background_loader_offliner.h index 1501afc..80927d4 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.h +++ b/chrome/browser/offline_pages/background_loader_offliner.h
@@ -81,8 +81,7 @@ // WebContentsObserver implementation. void DocumentAvailableInMainFrame( content::RenderFrameHost* render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void PrimaryMainFrameRenderProcessGone( base::TerminationStatus status) override; void WebContentsDestroyed() override;
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc index eda2a16..909f093d 100644 --- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc +++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -265,7 +265,7 @@ // Call complete loading. auto* main_frame = offliner()->web_contents()->GetMainFrame(); offliner()->DocumentAvailableInMainFrame(main_frame); - offliner()->DocumentOnLoadCompletedInMainFrame(main_frame); + offliner()->DocumentOnLoadCompletedInPrimaryMainFrame(); PumpLoop(); }
diff --git a/chrome/browser/offline_pages/recent_tab_helper.cc b/chrome/browser/offline_pages/recent_tab_helper.cc index 78439be..43b6bc2 100644 --- a/chrome/browser/offline_pages/recent_tab_helper.cc +++ b/chrome/browser/offline_pages/recent_tab_helper.cc
@@ -276,10 +276,9 @@ snapshot_controller_->DocumentAvailableInMainFrame(); } -void RecentTabHelper::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void RecentTabHelper::DocumentOnLoadCompletedInPrimaryMainFrame() { EnsureInitialized(); - snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); + snapshot_controller_->DocumentOnLoadCompletedInPrimaryMainFrame(); } void RecentTabHelper::WebContentsDestroyed() {
diff --git a/chrome/browser/offline_pages/recent_tab_helper.h b/chrome/browser/offline_pages/recent_tab_helper.h index ddefac3..75936c58 100644 --- a/chrome/browser/offline_pages/recent_tab_helper.h +++ b/chrome/browser/offline_pages/recent_tab_helper.h
@@ -58,8 +58,7 @@ content::NavigationHandle* navigation_handle) override; void DocumentAvailableInMainFrame( content::RenderFrameHost* render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void WebContentsDestroyed() override; void OnVisibilityChanged(content::Visibility visibility) override;
diff --git a/chrome/browser/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/offline_pages/recent_tab_helper_unittest.cc index 9238b74..a73d51ee 100644 --- a/chrome/browser/offline_pages/recent_tab_helper_unittest.cc +++ b/chrome/browser/offline_pages/recent_tab_helper_unittest.cc
@@ -341,7 +341,7 @@ const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); // Move the snapshot controller's time forward so it gets past timeouts. FastForwardSnapshotController(); EXPECT_EQ(0U, page_added_count()); @@ -369,7 +369,7 @@ ASSERT_EQ(0U, GetAllPages().size()); // Then allow the page to fully load. Nothing should be saved. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); // Move the snapshot controller's time forward so it gets past timeouts. FastForwardSnapshotController(); EXPECT_EQ(0U, page_added_count()); @@ -386,7 +386,7 @@ std::make_unique<TestDelegate>(this, kTabId, false)); NavigateAndCommit(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); recent_tab_helper()->ObserveAndDownloadCurrentPage(NewDownloadClientId(), @@ -408,7 +408,7 @@ // Navigate and finish loading then hide the tab. Nothing should be saved. NavigateAndCommit(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -433,7 +433,7 @@ // Navigate and finish loading then hide the tab. Nothing should be saved. NavigateAndCommit(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -486,7 +486,7 @@ // Set page loading state to the 2nd and last snapshot-able stage. No new // capture should happen. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); @@ -535,7 +535,7 @@ // Advance loading to the 2nd and final stage and then hide the tab. A new // capture is requested but its creation will fail. The exact same snapshot // from before should still be available. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -552,7 +552,7 @@ // Fully load the page. Hide the tab and check for a snapshot. const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -592,7 +592,7 @@ // Fully load the page then hide the tab. A capture is expected. const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -612,7 +612,7 @@ // Fully load the page once more then hide the tab again. A capture happens // and fails but no snapshot should remain. NavigateAndCommitTyped(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -630,7 +630,7 @@ const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -645,7 +645,7 @@ const GURL kOtherUrl("http://crazy.site/foo_other.html"); NavigateAndCommitTyped(kOtherUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(1U, model_removed_count()); @@ -675,7 +675,7 @@ FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -730,7 +730,7 @@ // with no offline pages for any requester. TEST_F(RecentTabHelperTest, NoCaptureOnErrorPage) { FailLoad(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); recent_tab_helper()->ObserveAndDownloadCurrentPage(NewDownloadClientId(), @@ -763,7 +763,7 @@ EXPECT_EQ(153L, early_page.offline_id); // Fully load the page. A second capture should replace the first one. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(2U, page_added_count()); EXPECT_EQ(1U, model_removed_count()); @@ -795,7 +795,7 @@ EXPECT_EQ(client_id, page.client_id); EXPECT_EQ(153L, page.offline_id); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(2U, page_added_count()); EXPECT_EQ(1U, model_removed_count()); @@ -809,7 +809,7 @@ TEST_F(RecentTabHelperTest, DownloadRequestAfterFullyLoad) { const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); ASSERT_EQ(0U, GetAllPages().size()); @@ -831,7 +831,7 @@ TEST_F(RecentTabHelperTest, DownloadRequestAfterFullyLoadWithOrigin) { const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); ASSERT_EQ(0U, GetAllPages().size()); @@ -853,7 +853,7 @@ TEST_F(RecentTabHelperTest, SimultaneousCapturesFromLastNAndDownloads) { const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); const int64_t download_offline_id = 153L; @@ -905,7 +905,7 @@ "OfflinePages.LastN.IsSavingSamePage", IsSavingSamePageEnum::kSamePageSameQuality, 1); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -943,7 +943,7 @@ 351L, ""); // Finish loading the page. Only the first request should be executed. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); @@ -978,7 +978,7 @@ // Navigates and load fully then hide the tab so that a snapshot is created. const GURL kTestUrl("http://mystery.site/foo.html"); NavigateAndCommit(kTestUrl); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -1024,7 +1024,7 @@ TEST_F(RecentTabHelperTest, ReloadIsTrackedAsNavigationAndSavedOnlyUponLoad) { // Navigates and load fully then hide the tab so that a snapshot is created. NavigateAndCommit(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -1043,7 +1043,7 @@ ASSERT_EQ(0U, GetAllPages().size()); // Finish loading and hide the tab. A new snapshot should be created. - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN); RunUntilIdle(); @@ -1061,7 +1061,7 @@ // Navigates and fully load then close and hide the tab. No snapshots are // expected. NavigateAndCommit(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); // Note: These two next calls are always expected to happen in this order. recent_tab_helper()->WillCloseTab(); @@ -1089,7 +1089,7 @@ // Navigate and finish loading, then move the snapshot controller's time // forward so it gets past timeouts. Nothing should be saved. NavigateAndCommitPost(GURL("http://mystery.site/foo.html")); - recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(main_rfh()); + recent_tab_helper()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardSnapshotController(); ASSERT_EQ(0U, GetAllPages().size());
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_manager.cc index 02913d2d..9834cbd5 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager.cc
@@ -418,7 +418,8 @@ proto::ModelInfo base_model_info; if (features::IsModelDownloadingEnabled()) { - // TODO(crbug/1204614): Remove v2.3* and 2.4 when server supports 2.7. + // TODO(crbug/1204614): Tidy these up so only the current version is sent to + // the server. base_model_info.add_supported_model_engine_versions( proto::MODEL_ENGINE_VERSION_TFLITE_2_3_0); base_model_info.add_supported_model_engine_versions( @@ -429,6 +430,8 @@ proto::MODEL_ENGINE_VERSION_TFLITE_2_7); base_model_info.add_supported_model_engine_versions( proto::MODEL_ENGINE_VERSION_TFLITE_2_8); + base_model_info.add_supported_model_engine_versions( + proto::MODEL_ENGINE_VERSION_TFLITE_2_9); } std::string debug_msg;
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc index e107b92f..03a5d1d 100644 --- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
@@ -680,11 +680,9 @@ EXPECT_TRUE(events[0]->GetArgAsValue("data", &arg)); base::DictionaryValue* arg_dict; EXPECT_TRUE(arg.GetAsDictionary(&arg_dict)); - int time; - EXPECT_TRUE(arg_dict->GetInteger("durationInMilliseconds", &time)); + int time = arg_dict->FindIntKey("durationInMilliseconds").value_or(0); EXPECT_EQ(600, time); - int size; - EXPECT_TRUE(arg_dict->GetInteger("size", &size)); + int size = arg_dict->FindIntKey("size").value_or(0); EXPECT_EQ(1000, size); std::string type; EXPECT_TRUE(arg_dict->GetString("type", &type));
diff --git a/chrome/browser/payments/secure_payment_confirmation_browsertest.cc b/chrome/browser/payments/secure_payment_confirmation_browsertest.cc index 80467e5..9b1ce08 100644 --- a/chrome/browser/payments/secure_payment_confirmation_browsertest.cc +++ b/chrome/browser/payments/secure_payment_confirmation_browsertest.cc
@@ -671,9 +671,7 @@ content::EvalJs( GetActiveWebContents(), content::JsReplace("getTotalAmountFromClientData($1, $2);", - second_credential_identifier, "0.01"), - // PaymentRequest.show() for SPC works without user gesture. - content::EXECUTE_SCRIPT_NO_USER_GESTURE)); + second_credential_identifier, "0.01"))); } // b.com cannot create a credential with RP = "a.com". @@ -702,17 +700,23 @@ GetDefaultIconURL())) .ExtractString(); - NavigateTo("b.com", "/iframe_poster.html"); + // Load a cross-origin iframe that can initiate SPC. + content::WebContents* tab = GetActiveWebContents(); + GURL iframe_url = https_server()->GetURL( + "b.com", "/secure_payment_confirmation_iframe.html"); + EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url)); + test_controller()->SetHasAuthenticator(true); confirm_payment_ = true; + + // Trigger SPC and capture the response. // EvalJs waits for JavaScript promise to resolve. + content::RenderFrameHost* iframe = content::FrameMatchingPredicate( + tab->GetPrimaryPage(), + base::BindRepeating(&content::FrameHasSourceUrl, iframe_url)); std::string response = - content::EvalJs( - GetActiveWebContents(), - content::JsReplace( - "postToIframe($1, $2);", - https_server()->GetURL("c.com", "/iframe_receiver.html").spec(), - credentialIdentifier)) + content::EvalJs(iframe, content::JsReplace("requestPayment($1);", + credentialIdentifier)) .ExtractString(); ASSERT_EQ(std::string::npos, response.find("Error")); @@ -726,7 +730,7 @@ std::string* origin = value->FindStringKey("origin"); ASSERT_NE(nullptr, origin) << response; - EXPECT_EQ(https_server()->GetURL("c.com", "/"), GURL(*origin)); + EXPECT_EQ(https_server()->GetURL("b.com", "/"), GURL(*origin)); absl::optional<bool> cross_origin = value->FindBoolKey("crossOrigin"); ASSERT_TRUE(cross_origin.has_value()) << response; @@ -738,7 +742,7 @@ std::string* top_origin = value->FindStringPath("payment.topOrigin"); ASSERT_NE(nullptr, top_origin) << response; - EXPECT_EQ(https_server()->GetURL("b.com", "/"), GURL(*top_origin)); + EXPECT_EQ(https_server()->GetURL("a.com", "/"), GURL(*top_origin)); std::string* rp = value->FindStringPath("payment.rp"); ASSERT_NE(nullptr, rp) << response;
diff --git a/chrome/browser/payments/site_per_process_payments_browsertest.cc b/chrome/browser/payments/site_per_process_payments_browsertest.cc index 710abba2..97d74ff 100644 --- a/chrome/browser/payments/site_per_process_payments_browsertest.cc +++ b/chrome/browser/payments/site_per_process_payments_browsertest.cc
@@ -71,6 +71,11 @@ https_server_->GetURL("b.com", "/payment_request_iframe.html"); EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url)); + content::RenderFrameHost* iframe = content::FrameMatchingPredicate( + tab->GetPrimaryPage(), + base::BindRepeating(&content::FrameHasSourceUrl, iframe_url)); + EXPECT_TRUE(content::ExecJs(iframe, "triggerPaymentRequest()")); + EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0); EXPECT_TRUE(frame);
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index b9a8143..f300450 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -139,6 +139,7 @@ #include "ui/base/clipboard/test/test_clipboard.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" #include "url/gurl.h" #if defined(TOOLKIT_VIEWS) && !defined(OS_MAC) @@ -515,12 +516,6 @@ content::GetFocusedWebContents(embedder_web_contents)); } -// TODO(crbug.com/1278357): Flaky on lacros. -#if BUILDFLAG(IS_CHROMEOS_LACROS) -#define MAYBE_PdfExtensionLoadedInGuest DISABLED_PdfExtensionLoadedInGuest -#else -#define MAYBE_PdfExtensionLoadedInGuest PdfExtensionLoadedInGuest -#endif // This test verifies that when a PDF is loaded, that (i) the embedder // WebContents' html consists of a single <embed> tag with appropriate // properties, and (ii) that the guest WebContents finishes loading and @@ -528,7 +523,7 @@ // TODO(wjmaclean): Are there any attributes we can/should test with respect to // the extension's loaded html? IN_PROC_BROWSER_TEST_P(PDFExtensionTestWithTestGuestViewManager, - MAYBE_PdfExtensionLoadedInGuest) { + PdfExtensionLoadedInGuest) { // Load test HTML, and verify the text area has focus. const GURL main_url(embedded_test_server()->GetURL("/pdf/test.pdf")); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); @@ -1591,7 +1586,14 @@ #endif } -class PDFExtensionKeyEventTest : public PDFExtensionTest { +class PDFExtensionScrollTest : public PDFExtensionTest { + public: + void SetUpOnMainThread() override { + PDFExtensionTest::SetUpOnMainThread(); + + GetActiveWebContents()->Resize({0, 0, 1024, 768}); + } + protected: class ScrollEventWaiter { public: @@ -1657,9 +1659,9 @@ }; // static -constexpr int PDFExtensionKeyEventTest::kScrollIncrement; +constexpr int PDFExtensionScrollTest::kScrollIncrement; -IN_PROC_BROWSER_TEST_P(PDFExtensionKeyEventTest, ScrollWithSpace) { +IN_PROC_BROWSER_TEST_P(PDFExtensionScrollTest, WithSpace) { WebContents* guest_contents = LoadPdfGetGuestContents( embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); SetInputFocusOnPlugin(guest_contents); @@ -1697,7 +1699,7 @@ EXPECT_EQ(viewport_height, GetViewportScrollPositionY(guest_contents)); } -IN_PROC_BROWSER_TEST_P(PDFExtensionKeyEventTest, ScrollWithPageDownUp) { +IN_PROC_BROWSER_TEST_P(PDFExtensionScrollTest, WithPageDownUp) { WebContents* guest_contents = LoadPdfGetGuestContents( embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); SetInputFocusOnPlugin(guest_contents); @@ -1737,7 +1739,7 @@ EXPECT_EQ(viewport_height, GetViewportScrollPositionY(guest_contents)); } -IN_PROC_BROWSER_TEST_P(PDFExtensionKeyEventTest, ScrollWithArrowLeftRight) { +IN_PROC_BROWSER_TEST_P(PDFExtensionScrollTest, WithArrowLeftRight) { WebContents* guest_contents = LoadPdfGetGuestContents( embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf#zoom=200")); SetInputFocusOnPlugin(guest_contents); @@ -1774,7 +1776,7 @@ EXPECT_EQ(kScrollIncrement, GetViewportScrollPositionX(guest_contents)); } -IN_PROC_BROWSER_TEST_P(PDFExtensionKeyEventTest, ScrollWithArrowDownUp) { +IN_PROC_BROWSER_TEST_P(PDFExtensionScrollTest, WithArrowDownUp) { WebContents* guest_contents = LoadPdfGetGuestContents( embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); SetInputFocusOnPlugin(guest_contents); @@ -1811,7 +1813,7 @@ EXPECT_EQ(kScrollIncrement, GetViewportScrollPositionY(guest_contents)); } -INSTANTIATE_TEST_SUITE_P(All, PDFExtensionKeyEventTest, testing::Values(true)); +INSTANTIATE_TEST_SUITE_P(All, PDFExtensionScrollTest, testing::Values(true)); IN_PROC_BROWSER_TEST_P(PDFExtensionTest, SelectAllShortcut) { content::WebContents* guest_contents =
diff --git a/chrome/browser/performance_manager/mechanisms/page_freezer_unittest.cc b/chrome/browser/performance_manager/mechanisms/page_freezer_unittest.cc index c35610e..d50481c 100644 --- a/chrome/browser/performance_manager/mechanisms/page_freezer_unittest.cc +++ b/chrome/browser/performance_manager/mechanisms/page_freezer_unittest.cc
@@ -137,7 +137,7 @@ permissions::PermissionRequestManager::FromWebContents(web_contents()); permissions::MockPermissionPromptFactory mock_prompt_factory(manager); NavigateAndCommit(GURL(kUrl)); - manager->DocumentOnLoadCompletedInMainFrame(main_rfh()); + manager->DocumentOnLoadCompletedInPrimaryMainFrame(); base::RunLoop run_loop; PermissionManagerFactory::GetForProfile(profile())->RequestPermission(
diff --git a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc index 4e3d66f..9b19518b 100644 --- a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc +++ b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc
@@ -107,7 +107,7 @@ } void WaitForBubbleToBeShown() { - manager_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + manager_->DocumentOnLoadCompletedInPrimaryMainFrame(); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 269ec76..7048f3d 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -906,8 +906,8 @@ { key::kFullscreenAlertEnabled, ash::prefs::kFullscreenAlertEnabled, base::Value::Type::BOOLEAN }, - { key::kFullscreenNotificationUrlExemptList, - ash::prefs::kFullscreenNotificationUrlExemptList, + { key::kKeepFullscreenWithoutNotificationUrlAllowList, + ash::prefs::kKeepFullscreenWithoutNotificationUrlAllowList, base::Value::Type::LIST }, { key::kFastPairEnabled, ash::prefs::kFastPairEnabled, @@ -1282,16 +1282,16 @@ ash::prefs::kDeskTemplatesEnabled, base::Value::Type::BOOLEAN }, { key::kQuickAnswersEnabled, - ash::quick_answers::prefs::kQuickAnswersEnabled, + quick_answers::prefs::kQuickAnswersEnabled, base::Value::Type::BOOLEAN }, { key::kQuickAnswersDefinitionEnabled, - ash::quick_answers::prefs::kQuickAnswersDefinitionEnabled, + quick_answers::prefs::kQuickAnswersDefinitionEnabled, base::Value::Type::BOOLEAN }, { key::kQuickAnswersTranslationEnabled, - ash::quick_answers::prefs::kQuickAnswersTranslationEnabled, + quick_answers::prefs::kQuickAnswersTranslationEnabled, base::Value::Type::BOOLEAN }, { key::kQuickAnswersUnitConverstionEnabled, - ash::quick_answers::prefs::kQuickAnswersUnitConverstionEnabled, + quick_answers::prefs::kQuickAnswersUnitConverstionEnabled, base::Value::Type::BOOLEAN }, { key::kChromadToCloudMigrationEnabled, ash::prefs::kChromadToCloudMigrationEnabled,
diff --git a/chrome/browser/policy/messaging_layer/proto/synced/crd_event.proto b/chrome/browser/policy/messaging_layer/proto/synced/crd_event.proto index a44ed5d..027078e 100644 --- a/chrome/browser/policy/messaging_layer/proto/synced/crd_event.proto +++ b/chrome/browser/policy/messaging_layer/proto/synced/crd_event.proto
@@ -12,6 +12,7 @@ CRD_CONNECTION_UNKNOWN = 0; CRD_CONNECTION_DIRECT = 1; CRD_CONNECTION_RELAY = 2; + CRD_CONNECTION_STUN = 3; } // To be reported when host is started.
diff --git a/chrome/browser/power_bookmarks/proto/shopping_specifics.proto b/chrome/browser/power_bookmarks/proto/shopping_specifics.proto index b1d3bf8..1abfe16 100644 --- a/chrome/browser/power_bookmarks/proto/shopping_specifics.proto +++ b/chrome/browser/power_bookmarks/proto/shopping_specifics.proto
@@ -28,6 +28,9 @@ // Whether the product is currently being tracked. optional bool is_price_tracked = 5; + + // The offer id for the product. + optional fixed64 offer_id = 6; } message ProductPrice {
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper.cc b/chrome/browser/predictors/loading_predictor_tab_helper.cc index 49f9aff7..091c49d 100644 --- a/chrome/browser/predictors/loading_predictor_tab_helper.cc +++ b/chrome/browser/predictors/loading_predictor_tab_helper.cc
@@ -397,13 +397,12 @@ page_data->navigation_id_, resource_load_info); } -void LoadingPredictorTabHelper::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void LoadingPredictorTabHelper::DocumentOnLoadCompletedInPrimaryMainFrame() { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!predictor_) return; - auto* page_data = PageData::GetForDocument(*render_frame_host); + auto* page_data = PageData::GetForDocument(*web_contents()->GetMainFrame()); if (!page_data) return;
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper.h b/chrome/browser/predictors/loading_predictor_tab_helper.h index cbb70098..bf4e378 100644 --- a/chrome/browser/predictors/loading_predictor_tab_helper.h +++ b/chrome/browser/predictors/loading_predictor_tab_helper.h
@@ -62,8 +62,7 @@ const GURL& url, const std::string& mime_type, network::mojom::RequestDestination request_destination) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; // Used by LoadingPredictorPageLoadMetricsObserver. void RecordFirstContentfulPaint(content::RenderFrameHost* render_frame_host, @@ -105,7 +104,7 @@ bool has_local_preconnect_predictions_for_current_navigation_ = false; // The optimization guide prediction for the current navigation. If set, - // this will be cleared on |DocumentOnLoadCompletedInMainFrame|. + // this will be cleared on |DocumentOnLoadCompletedInPrimaryMainFrame|. absl::optional<OptimizationGuidePrediction> last_optimization_guide_prediction_;
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc index eefbb0d..aca2929 100644 --- a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc +++ b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc
@@ -265,7 +265,7 @@ NavigateAndCommitInFrame("http://sub.test.org", subframe); EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, _)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); } // Tests that a resource load is correctly recorded. @@ -343,7 +343,7 @@ NavigateAndCommitInMainFrameAndVerifyMetrics("http://test.org"); // Trigger onLoad to get rid of previous prediction. EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, _)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); base::HistogramTester histogram_tester; @@ -364,7 +364,7 @@ null_optimization_guide_prediction; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete( _, null_optimization_guide_prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); histogram_tester.ExpectTotalCount( "LoadingPredictor.OptimizationHintsReceiveStatus", 0); @@ -410,7 +410,7 @@ GURL("http://other.org/resource2"), GURL("http://other.org/resource3")}; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); histogram_tester.ExpectUniqueSample( "LoadingPredictor.OptimizationHintsReceiveStatus", @@ -464,7 +464,7 @@ GURL("http://other.org/resource2"), GURL("http://other.org/resource3")}; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); // Optimization guide predictions came after commit. histogram_tester.ExpectUniqueSample( @@ -523,7 +523,7 @@ optimization_guide_prediction->decision = optimization_guide::OptimizationGuideDecision::kUnknown; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, _)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); histogram_tester.ExpectUniqueSample( "LoadingPredictor.OptimizationHintsReceiveStatus", @@ -553,7 +553,7 @@ prediction->decision = optimization_guide::OptimizationGuideDecision::kUnknown; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); // Histogram should not be recorded since prediction did not come back. histogram_tester.ExpectTotalCount( @@ -597,7 +597,7 @@ prediction->decision = optimization_guide::OptimizationGuideDecision::kUnknown; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); // Invoke callback after document completed in main frame.. std::move(callback).Run(optimization_guide::OptimizationGuideDecision::kTrue, @@ -639,7 +639,7 @@ OptimizationGuidePrediction(); prediction->decision = optimization_guide::OptimizationGuideDecision::kFalse; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); // Histogram should still be recorded even though no predictions were // returned. @@ -682,7 +682,7 @@ optimization_guide::OptimizationGuideDecision::kUnknown; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, optimization_guide_prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); // Histogram should still be recorded even though no predictions were // returned. @@ -762,7 +762,7 @@ GURL("http://test.org/resource1"), GURL("http://other.org/resource2"), GURL("http://other.org/resource3"), GURL("http://preconnectonly.com/")}; EXPECT_CALL(*mock_collector_, RecordMainFrameLoadComplete(_, prediction)); - tab_helper_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + tab_helper_->DocumentOnLoadCompletedInPrimaryMainFrame(); histogram_tester.ExpectUniqueSample( "LoadingPredictor.OptimizationHintsReceiveStatus",
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 048b846..fb4d668c 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1401,7 +1401,7 @@ ash::Preferences::RegisterProfilePrefs(registry); ash::EnterprisePrintersProvider::RegisterProfilePrefs(registry); ash::parent_access::ParentAccessService::RegisterProfilePrefs(registry); - ash::quick_answers::prefs::RegisterProfilePrefs(registry); + quick_answers::prefs::RegisterProfilePrefs(registry); ash::quick_unlock::RegisterProfilePrefs(registry); ash::RegisterSamlProfilePrefs(registry); ash::ScreenTimeController::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc index a80f5f8..bf2594c 100644 --- a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc +++ b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
@@ -663,13 +663,13 @@ case PROTECTION_ENABLED_ALL: case PROTECTION_ENABLED_EXTENSIONS: ++num_protected_prefs; - FALLTHROUGH; + [[fallthrough]]; case PROTECTION_ENABLED_DSE: ++num_protected_prefs; - FALLTHROUGH; + [[fallthrough]]; case PROTECTION_ENABLED_BASIC: num_protected_prefs += num_tracked_prefs() - num_null_values - 2; - FALLTHROUGH; + [[fallthrough]]; case PROTECTION_DISABLED_FOR_GROUP: case PROTECTION_DISABLED_ON_PLATFORM: // No protection.
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index d8f67ab..e3fb49f 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc
@@ -519,12 +519,6 @@ DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK_NE(page_number_, PageNumber::npos()); - // Preprocess. - if (printing_context_->NewPage() != mojom::ResultCode::kSuccess) { - OnFailure(); - return; - } - // Actual printing. if (document_->RenderPrintedPage(*page, printing_context_.get()) != mojom::ResultCode::kSuccess) { @@ -532,12 +526,6 @@ return; } - // Postprocess. - if (printing_context_->PageDone() != mojom::ResultCode::kSuccess) { - OnFailure(); - return; - } - // Signal everyone that the page is printed. DCHECK(print_job_); print_job_->PostTask(FROM_HERE,
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc index 96929c41..1cf3cbf 100644 --- a/chrome/browser/printing/print_preview_dialog_controller.cc +++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -34,6 +34,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_ui.h" +#include "content/public/common/url_constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/web_dialogs/web_dialog_delegate.h" @@ -272,6 +273,12 @@ url.host_piece() == chrome::kChromeUIPrintHost; } +// static +bool PrintPreviewDialogController::IsPrintPreviewContentURL(const GURL& url) { + return url.SchemeIs(content::kChromeUIUntrustedScheme) && + url.host_piece() == chrome::kChromeUIPrintHost; +} + void PrintPreviewDialogController::EraseInitiatorInfo( WebContents* preview_dialog) { auto it = preview_dialog_map_.find(preview_dialog);
diff --git a/chrome/browser/printing/print_preview_dialog_controller.h b/chrome/browser/printing/print_preview_dialog_controller.h index 952f302..b87db055 100644 --- a/chrome/browser/printing/print_preview_dialog_controller.h +++ b/chrome/browser/printing/print_preview_dialog_controller.h
@@ -41,9 +41,14 @@ // Call this instead of GetOrCreatePreviewDialog(). static void PrintPreview(content::WebContents* initiator); - // Returns true if |url| is a print preview url. + // Returns true if `url` is a Print Preview dialog URL (has `chrome://print` + // origin). static bool IsPrintPreviewURL(const GURL& url); + // Returns true if `url` is a Print Preview content URL (has + // `chrome-untrusted://print` origin). + static bool IsPrintPreviewContentURL(const GURL& url); + // Get/Create the print preview dialog for |initiator|. // Exposed for unit tests. content::WebContents* GetOrCreatePreviewDialog(
diff --git a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc index 1dffe5b..056be51 100644 --- a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc +++ b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
@@ -24,6 +24,8 @@ #include "content/public/test/navigation_simulator.h" #include "content/public/test/test_utils.h" #include "content/public/test/web_contents_tester.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" using content::WebContents; using content::WebContentsObserver; @@ -39,6 +41,20 @@ using PrintPreviewDialogControllerUnitTest = PrintPreviewTest; +TEST_F(PrintPreviewDialogControllerUnitTest, IsPrintPreviewURL) { + EXPECT_TRUE(PrintPreviewDialogController::IsPrintPreviewURL( + GURL("chrome://print/fake-path"))); + EXPECT_FALSE(PrintPreviewDialogController::IsPrintPreviewURL( + GURL("chrome-untrusted://print/fake-path"))); +} + +TEST_F(PrintPreviewDialogControllerUnitTest, IsPrintPreviewContentURL) { + EXPECT_TRUE(PrintPreviewDialogController::IsPrintPreviewContentURL( + GURL("chrome-untrusted://print/fake-path"))); + EXPECT_FALSE(PrintPreviewDialogController::IsPrintPreviewContentURL( + GURL("chrome://print/fake-path"))); +} + // Create/Get a preview dialog for initiator. TEST_F(PrintPreviewDialogControllerUnitTest, GetOrCreatePreviewDialog) { // Lets start with one window with one tab.
diff --git a/chrome/browser/renderer_context_menu/accessibility_labels_bubble_model_browsertest.cc b/chrome/browser/renderer_context_menu/accessibility_labels_bubble_model_browsertest.cc index 55891a8..ce55a1b 100644 --- a/chrome/browser/renderer_context_menu/accessibility_labels_bubble_model_browsertest.cc +++ b/chrome/browser/renderer_context_menu/accessibility_labels_bubble_model_browsertest.cc
@@ -67,7 +67,7 @@ model->OpenHelpPage(); content::WebContents* web_contents = waiter.Wait(); EXPECT_EQ(web_contents->GetBrowserContext(), browser()->profile()); - EXPECT_EQ(web_contents->GetURL(), model->GetHelpPageURL()); + EXPECT_EQ(web_contents->GetVisibleURL(), model->GetHelpPageURL()); } // Tests that closing the tab with WebContents that was used to construct @@ -89,5 +89,5 @@ model->OpenHelpPage(); content::WebContents* web_contents = waiter.Wait(); EXPECT_EQ(web_contents->GetBrowserContext(), browser()->profile()); - EXPECT_EQ(web_contents->GetURL(), model->GetHelpPageURL()); + EXPECT_EQ(web_contents->GetVisibleURL(), model->GetHelpPageURL()); }
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc index 509cfef..29479181 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc
@@ -36,8 +36,8 @@ namespace { -using ash::quick_answers::Context; -using ash::quick_answers::QuickAnswersExitPoint; +using quick_answers::Context; +using quick_answers::QuickAnswersExitPoint; constexpr int kMaxSurroundingTextLength = 300; @@ -62,10 +62,10 @@ void QuickAnswersMenuObserver::OnContextMenuShown( const content::ContextMenuParams& params, const gfx::Rect& bounds_in_screen) { - DCHECK(ash::QuickAnswersController::Get()); + DCHECK(QuickAnswersController::Get()); menu_shown_time_ = base::TimeTicks::Now(); - if (!ash::QuickAnswersState::Get()->is_eligible()) + if (!QuickAnswersState::Get()->is_eligible()) return; // Skip password input field. @@ -84,7 +84,7 @@ content::RenderFrameHost* focused_frame = proxy_->GetWebContents()->GetFocusedFrame(); if (focused_frame) { - ash::QuickAnswersController::Get()->SetPendingShowQuickAnswers(); + QuickAnswersController::Get()->SetPendingShowQuickAnswers(); focused_frame->RequestTextSurroundingSelection( base::BindOnce( &QuickAnswersMenuObserver::OnTextSurroundingSelectionAvailable, @@ -96,7 +96,7 @@ void QuickAnswersMenuObserver::OnContextMenuViewBoundsChanged( const gfx::Rect& bounds_in_screen) { bounds_in_screen_ = bounds_in_screen; - ash::QuickAnswersController::Get()->UpdateQuickAnswersAnchorBounds( + QuickAnswersController::Get()->UpdateQuickAnswersAnchorBounds( bounds_in_screen); } @@ -115,7 +115,7 @@ base::UmaHistogramBoolean("QuickAnswers.ContextMenu.Close", is_other_command_executed_); - ash::QuickAnswersController::Get()->DismissQuickAnswers( + QuickAnswersController::Get()->DismissQuickAnswers( is_other_command_executed_ ? QuickAnswersExitPoint::kContextMenuClick : QuickAnswersExitPoint::KContextMenuDismiss); } @@ -139,6 +139,6 @@ context.device_properties.preferred_languages = prefs->GetString(language::prefs::kPreferredLanguages); context.device_properties.is_internal = IsInternalUser(profile); - ash::QuickAnswersController::Get()->MaybeShowQuickAnswers( - bounds_in_screen_, selected_text, context); + QuickAnswersController::Get()->MaybeShowQuickAnswers(bounds_in_screen_, + selected_text, context); }
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc index 2110b82..12432a56 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc
@@ -30,7 +30,7 @@ // InProcessBrowserTest overrides: void SetUpOnMainThread() override { Reset(false); - ash::QuickAnswersState::Get()->set_eligibility_for_testing(true); + QuickAnswersState::Get()->set_eligibility_for_testing(true); } void TearDownOnMainThread() override { @@ -55,9 +55,7 @@ } MockRenderViewContextMenu* menu() { return menu_.get(); } - ash::QuickAnswersController* controller() { - return ash::QuickAnswersController::Get(); - } + QuickAnswersController* controller() { return QuickAnswersController::Get(); } QuickAnswersMenuObserver* observer() { return observer_.get(); } protected: @@ -68,7 +66,7 @@ } // namespace IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, FeatureIneligible) { - ash::QuickAnswersState::Get()->set_eligibility_for_testing(false); + QuickAnswersState::Get()->set_eligibility_for_testing(false); content::ContextMenuParams params; params.selection_text = u"test"; @@ -76,12 +74,12 @@ ShowMenu(params); // Quick Answers UI should stay hidden since the feature is not eligible. - ASSERT_EQ(ash::QuickAnswersVisibility::kClosed, + ASSERT_EQ(QuickAnswersVisibility::kClosed, controller()->GetVisibilityForTesting()); } IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, PasswordField) { - ash::QuickAnswersState::Get()->set_eligibility_for_testing(true); + QuickAnswersState::Get()->set_eligibility_for_testing(true); content::ContextMenuParams params; params.input_field_type = @@ -92,29 +90,29 @@ // Quick Answers UI should stay hidden since the input field is password // field. - ASSERT_EQ(ash::QuickAnswersVisibility::kClosed, + ASSERT_EQ(QuickAnswersVisibility::kClosed, controller()->GetVisibilityForTesting()); } IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, NoSelectedText) { - ash::QuickAnswersState::Get()->set_eligibility_for_testing(true); + QuickAnswersState::Get()->set_eligibility_for_testing(true); content::ContextMenuParams params; ShowMenu(params); // Quick Answers UI should stay hidden since no text is selected. - ASSERT_EQ(ash::QuickAnswersVisibility::kClosed, + ASSERT_EQ(QuickAnswersVisibility::kClosed, controller()->GetVisibilityForTesting()); } IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, QuickAnswersPending) { - ash::QuickAnswersState::Get()->set_eligibility_for_testing(true); + QuickAnswersState::Get()->set_eligibility_for_testing(true); content::ContextMenuParams params; params.selection_text = u"test"; ShowMenu(params); // Quick Answers UI should be pending. - ASSERT_EQ(ash::QuickAnswersVisibility::kPending, + ASSERT_EQ(QuickAnswersVisibility::kPending, controller()->GetVisibilityForTesting()); }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 4e74363..48c1aee 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -3025,8 +3025,9 @@ ProfileIOData::IsHandledProtocol(url.scheme()); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // Do not save the preview PDF on the print preview page. - can_save = can_save && - !(printing::PrintPreviewDialogController::IsPrintPreviewURL(url)); + can_save = + can_save && + !printing::PrintPreviewDialogController::IsPrintPreviewContentURL(url); #endif return can_save; }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 8555a10..b3fd3b8e 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -872,7 +872,7 @@ EXPECT_TRUE(content::WaitForLoadStop(tab)); // Verify that it's the correct tab. - EXPECT_EQ(GURL("about:blank"), tab->GetURL()); + EXPECT_EQ(GURL("about:blank"), tab->GetLastCommittedURL()); } // Verify that "Open Link in New Tab" doesn't crash for about:blank. @@ -901,7 +901,7 @@ EXPECT_TRUE(content::WaitForLoadStop(tab)); // Verify that it's the correct tab. - EXPECT_EQ(GURL("about:blank"), tab->GetURL()); + EXPECT_EQ(GURL("about:blank"), tab->GetLastCommittedURL()); } // Verify that "Open Link in New Tab" doesn't crash for data: URLs. @@ -964,7 +964,7 @@ EXPECT_TRUE(content::WaitForLoadStop(tab)); // Verify that it's the correct tab. - ASSERT_EQ(echoheader, tab->GetURL()); + ASSERT_EQ(echoheader, tab->GetLastCommittedURL()); // Verify that the text on the page matches |kCorrectReferrer|. std::string actual_referrer; ASSERT_TRUE(content::ExecuteScriptAndExtractString( @@ -1013,7 +1013,7 @@ EXPECT_TRUE(content::WaitForLoadStop(tab)); // Verify that it's the correct tab. - ASSERT_EQ(echoheader, tab->GetURL()); + ASSERT_EQ(echoheader, tab->GetLastCommittedURL()); // Verify that the text on the page matches |kNoneReferrer|. std::string actual_referrer; ASSERT_TRUE(content::ExecuteScriptAndExtractString( @@ -1486,7 +1486,7 @@ content::WaitForLoadStop(tab); // Verify that it's the correct tab and profile. - EXPECT_EQ(url, tab->GetURL()); + EXPECT_EQ(url, tab->GetLastCommittedURL()); EXPECT_EQ(profile, Profile::FromBrowserContext(tab->GetBrowserContext())); } } @@ -1603,7 +1603,7 @@ content::WaitForLoadStop(new_tab); std::string expected_content = GetLensRegionSearchURL().GetContent(); - std::string new_tab_content = new_tab->GetURL().GetContent(); + std::string new_tab_content = new_tab->GetLastCommittedURL().GetContent(); // Match strings up to the query. std::size_t query_start_pos = new_tab_content.find("?"); // Match the query parameters, without the value of start_time. @@ -1624,7 +1624,7 @@ content::WaitForLoadStop(new_tab); std::string expected_content = GetNonGoogleRegionSearchURL().GetContent(); - std::string new_tab_content = new_tab->GetURL().GetContent(); + std::string new_tab_content = new_tab->GetLastCommittedURL().GetContent(); EXPECT_EQ(expected_content, new_tab_content); } #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -1721,7 +1721,7 @@ // The browser should open a new tab for an image search. content::WebContents* new_tab = add_tab.Wait(); content::WaitForLoadStop(new_tab); - EXPECT_EQ(GetImageSearchURL(), new_tab->GetURL()); + EXPECT_EQ(GetImageSearchURL(), new_tab->GetLastCommittedURL()); } IN_PROC_BROWSER_TEST_F(SearchByImageBrowserTest, ImageSearchWithCorruptImage) { @@ -1781,7 +1781,7 @@ content::WaitForLoadStop(new_tab); std::string expected_content = GetLensImageSearchURL().GetContent(); - std::string new_tab_content = new_tab->GetURL().GetContent(); + std::string new_tab_content = new_tab->GetLastCommittedURL().GetContent(); // Match strings up to the query. std::size_t query_start_pos = new_tab_content.find("?"); EXPECT_EQ(expected_content.substr(0, query_start_pos),
diff --git a/chrome/browser/renderer_context_menu/spelling_bubble_model_browsertest.cc b/chrome/browser/renderer_context_menu/spelling_bubble_model_browsertest.cc index 50dbe0b..57543bf2 100644 --- a/chrome/browser/renderer_context_menu/spelling_bubble_model_browsertest.cc +++ b/chrome/browser/renderer_context_menu/spelling_bubble_model_browsertest.cc
@@ -68,7 +68,7 @@ model->OpenHelpPage(); content::WebContents* web_contents = waiter.Wait(); EXPECT_EQ(web_contents->GetBrowserContext(), browser()->profile()); - EXPECT_EQ(web_contents->GetURL(), model->GetHelpPageURL()); + EXPECT_EQ(web_contents->GetVisibleURL(), model->GetHelpPageURL()); } // Tests that closing the tab with WebContents that was used to construct the @@ -89,5 +89,5 @@ model->OpenHelpPage(); content::WebContents* web_contents = waiter.Wait(); EXPECT_EQ(web_contents->GetBrowserContext(), browser()->profile()); - EXPECT_EQ(web_contents->GetURL(), model->GetHelpPageURL()); + EXPECT_EQ(web_contents->GetVisibleURL(), model->GetHelpPageURL()); }
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js index ce58c0d..dfd16a5 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
@@ -57,7 +57,6 @@ #include "chrome/common/extensions/extension_constants.h" #include "content/public/test/browser_test.h" #include "ui/accessibility/accessibility_features.h" -#include "ui/accessibility/accessibility_switches.h" `); } @@ -65,8 +64,6 @@ testGenPreamble() { super.testGenPreamble(); GEN(` - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityDictationExtension); base::OnceClosure load_cb = base::BindOnce(&ash::AccessibilityManager::SetDictationEnabled, base::Unretained(ash::AccessibilityManager::Get()), @@ -77,7 +74,12 @@ /** @override */ get featureList() { - return {enabled: ['features::kExperimentalAccessibilityDictationCommands']}; + return { + enabled: [ + 'features::kExperimentalAccessibilityDictationCommands', + 'features::kExperimentalAccessibilityDictationExtension' + ] + }; } /**
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier_test.js index e6d7ee6..cbce6be 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier_test.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier_test.js
@@ -188,9 +188,16 @@ magnifier.setIsInitializingForTest(false); const moveMenuSelectionAssertBounds = async (targetBounds) => { - return new Promise(resolve => { + // Send arrow up key. + chrome.accessibilityPrivate.sendSyntheticKeyEvent({ + type: + chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN, + keyCode: KeyCode.UP + }); + + // Verify new magnifier bounds include |targetBounds|. + await new Promise(resolve => { const boundsChangedListener = newBounds => { - // Verify new magnifier bounds include |targetBounds|. if (RectUtil.contains(newBounds, targetBounds)) { chrome.accessibilityPrivate.onMagnifierBoundsChanged .removeListener(boundsChangedListener); @@ -199,29 +206,21 @@ }; chrome.accessibilityPrivate.onMagnifierBoundsChanged.addListener( boundsChangedListener); - - // Arrow up - chrome.accessibilityPrivate.sendSyntheticKeyEvent({ - type: chrome.accessibilityPrivate.SyntheticKeyboardEventType - .KEYDOWN, - keyCode: KeyCode.UP - }); }); }; - // Trigger Chrome menu, and wait for it to open. - await new Promise(resolve => { - desktop.addEventListener( - chrome.automation.EventType.MENU_START, resolve, false); - - chrome.accessibilityPrivate.sendSyntheticKeyEvent({ - type: - chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN, - keyCode: KeyCode.E, - modifiers: {alt: true} - }); + // Trigger Chrome menu. + chrome.accessibilityPrivate.sendSyntheticKeyEvent({ + type: chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN, + keyCode: KeyCode.E, + modifiers: {alt: true} }); + // Wait for Chrome menu to open. + await new Promise( + resolve => desktop.addEventListener( + chrome.automation.EventType.MENU_START, resolve, false)); + // Move menu selection to end of menu, and await new magnifier bounds. await moveMenuSelectionAssertBounds( {left: 650, top: 450, width: 0, height: 0}); @@ -252,9 +251,14 @@ magnifier.setIsInitializingForTest(false); const movePointAssertBounds = async (targetPoint, targetBounds) => { - return new Promise(resolve => { + // Repeatedly center magnifier on |targetPoint|. + const id = setInterval(() => { + chrome.accessibilityPrivate.magnifierCenterOnPoint(targetPoint); + }, 500); + + // Verify new magnifier bounds include |targetBounds|. + await new Promise(resolve => { const boundsChangedListener = newBounds => { - // Verify new magnifier bounds include |targetBounds|. if (RectUtil.contains(newBounds, targetBounds)) { chrome.accessibilityPrivate.onMagnifierBoundsChanged.removeListener( boundsChangedListener); @@ -264,10 +268,6 @@ }; chrome.accessibilityPrivate.onMagnifierBoundsChanged.addListener( boundsChangedListener); - const id = setInterval(() => { - // Center magnifier on |targetPoint|. - chrome.accessibilityPrivate.magnifierCenterOnPoint(targetPoint); - }, 500); }); }; @@ -302,9 +302,14 @@ input.doDefault(); const typeWordsAssertBounds = async targetBounds => { - return new Promise(resolve => { + // Type words in the input field to move the text caret forward. + const id = setInterval(() => { + button.doDefault(); + }, 500); + + // Verify new magnifier bounds include |targetBounds|. + await new Promise(resolve => { const boundsChangedListener = newBounds => { - // Verify new magnifier bounds include |targetBounds|. if (RectUtil.contains(newBounds, targetBounds)) { chrome.accessibilityPrivate.onMagnifierBoundsChanged.removeListener( boundsChangedListener); @@ -314,11 +319,6 @@ }; chrome.accessibilityPrivate.onMagnifierBoundsChanged.addListener( boundsChangedListener); - - const id = setInterval(() => { - // Type words in the input field to move the text caret forward. - button.doDefault(); - }, 500); }); };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js index 335a2e2..9b0b091 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js
@@ -516,11 +516,6 @@ } if (this.multiline) { - // Fall back to announce deleted but omit the text that was deleted. - if (evt.value.length < prev.value.length) { - this.speak( - Msgs.getMsg('text_deleted'), evt.triggeredByUser, personality); - } // The below is a somewhat loose way to deal with non-standard // insertions/deletions. Intentionally skip for multiline since deletion // announcements are covered above and insertions are non-standard
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js index 0a37756..1bbac53 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js
@@ -460,3 +460,13 @@ obj.changed(new TextChangeEvent('hi t', 4, 4)); assertEqualStringArrays(['h', 'i', 'hi ', 't'], tts.get()); }); +TEST_F('ChromeVoxEditableTextUnitTest', 'DoesNotSpeakDeleted', function() { + var tts = new TestTts(); + var obj = new ChromeVoxEditableTextBase('Hello', 0, 0, false, tts); + obj.multiline = true; + + obj.changed(new TextChangeEvent('wor', 0, 0)); + + // This was once ['text_deleted'], but that is undesirable and mostly noise. + assertEqualStringArrays([], tts.get()); +});
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html index 2e6979f..afd460b 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html
@@ -166,10 +166,9 @@ grid-gap: unset; } - /* TODO(b/212459278): Reset bar visibility again after finishing - the subcategory bar layout implementation.*/ :host([text-subcategory-bar-enabled]) #bar { - visibility: hidden; + margin-inline: 9px; + padding-inline: 0; } </style> @@ -240,8 +239,8 @@ </emoji-group-button> <!-- Render non history tab. --> <template is="dom-repeat" - items="[[getGroupTabsByPagination(emojiGroupTabs, 1)]]" - filter="isNonHistoryTab"> + items="[[emojiGroupTabs]]" + filter="[[filterGroupTabByPagination(1)]]"> <text-group-button data-group$="[[item.groupId]]" group-id="[[item.groupId]]" active="[[item.active]]" @@ -254,8 +253,9 @@ <template is="dom-repeat" as="pageNumber" filter="isNotFirstPage" items="[[getPaginationArray(emojiGroupTabs)]]"> <div class="pagination"> - <template is="dom-repeat" - items="[[getGroupTabsByPagination(emojiGroupTabs, pageNumber)]]"> + <template is="dom-repeat" + items="[[emojiGroupTabs]]" + filter="[[filterGroupTabByPagination(pageNumber)]]"> <text-group-button data-group$="[[item.groupId]]" group-id="[[item.groupId]]" active="[[item.active]]"
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js index 7581a62..b4a895d 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
@@ -12,12 +12,12 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {afterNextRender, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {EMOJI_GROUP_SIZE_PX, EMOJI_ICON_SIZE, EMOJI_PER_ROW, EMOJI_PICKER_HEIGHT_PX, EMOJI_PICKER_SIDE_PADDING_PX, EMOJI_PICKER_TOP_PADDING_PX, EMOJI_PICKER_TOTAL_EMOJI_WIDTH, EMOJI_PICKER_TOTAL_EMOJI_WIDTH_PX, EMOJI_PICKER_WIDTH, EMOJI_PICKER_WIDTH_PX, EMOJI_SIZE_PX, EMOJI_SPACING_PX, GROUP_ICON_SIZE, GROUP_PER_ROW} from './constants.js'; +import {EMOJI_GROUP_SIZE_PX, EMOJI_ICON_SIZE, EMOJI_PER_ROW, EMOJI_PICKER_HEIGHT_PX, EMOJI_PICKER_SIDE_PADDING, EMOJI_PICKER_SIDE_PADDING_PX, EMOJI_PICKER_TOP_PADDING_PX, EMOJI_PICKER_TOTAL_EMOJI_WIDTH, EMOJI_PICKER_TOTAL_EMOJI_WIDTH_PX, EMOJI_PICKER_WIDTH, EMOJI_PICKER_WIDTH_PX, EMOJI_SIZE_PX, EMOJI_SPACING_PX, GROUP_ICON_SIZE, GROUP_PER_ROW} from './constants.js'; import {EmojiButton} from './emoji_button.js'; import {Feature} from './emoji_picker.mojom-webui.js'; import {EmojiPickerApiProxy, EmojiPickerApiProxyImpl} from './emoji_picker_api_proxy.js'; import {CATEGORY_BUTTON_CLICK, createCustomEvent, EMOJI_BUTTON_CLICK, EMOJI_CLEAR_RECENTS_CLICK, EMOJI_DATA_LOADED, EMOJI_VARIANTS_SHOWN, EmojiVariantsShownEvent, GROUP_BUTTON_CLICK} from './events.js'; -import {V2_SUBCATEGORY_TABS} from './metadata_extension.js'; +import {EMPTY_EMOTICON_DATA, V2_SUBCATEGORY_TABS} from './metadata_extension.js'; import {RecentEmojiStore} from './store.js'; import {Emoji, EmojiGroup, EmojiGroupData, EmojiVariants, StoredEmoji, SubcategoryData} from './types.js'; @@ -211,6 +211,16 @@ this.getHistory(); } + /** + * @private + * @param {number} pageNumber + */ + filterGroupTabByPagination(pageNumber) { + return function(tab) { + return tab.pagination === pageNumber && tab.groupId !== 'history'; + }; + } + async getHistory() { const incognito = (await this.apiProxy_.isIncognitoTextField()).incognito; if (incognito) { @@ -241,8 +251,19 @@ this.fetchEmojiData(), ]); - initializationPromise.then( - () => afterNextRender(this, () => this.apiProxy_.showUI())); + initializationPromise.then(() => { + afterNextRender(this, () => { + this.apiProxy_.showUI(); + if (this.v2Enabled) { + this.addEventListener( + CATEGORY_BUTTON_CLICK, + ev => this.set('category', ev.detail.categoryName)); + // TODO(b/211520561): remove below line after the emoticon loading + // logic is finished. + this.emojiData = this.emojiData.concat(EMPTY_EMOTICON_DATA); + } + }); + }); this.updateStyles({ '--emoji-group-button-size': EMOJI_GROUP_SIZE_PX, @@ -254,15 +275,6 @@ '--emoji-picker-top-padding': EMOJI_PICKER_TOP_PADDING_PX, '--emoji-spacing': EMOJI_SPACING_PX, }); - - // only after the next render is this.v2Enabled updated. - afterNextRender(this, () => { - if (this.v2Enabled) { - this.addEventListener( - CATEGORY_BUTTON_CLICK, - ev => this.set('category', ev.detail.categoryName)); - } - }); } /** @@ -501,30 +513,59 @@ if (!this.highlightBarMoving && !this.groupTabsMoving) { // Update the scroll position of the emoji groups so that active group is // visible. - let tabscrollLeft = this.$.tabs.scrollLeft; - if (tabscrollLeft > EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (index - 0.5)) { - tabscrollLeft = 0; - } - if (tabscrollLeft + EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (GROUP_PER_ROW - 2) < - GROUP_ICON_SIZE * index) { - // 5 = We want the seventh icon to be first. Then -1 for chevron, -1 for - // 1 based indexing. - tabscrollLeft = EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (7); - } + if (!this.textSubcategoryBarEnabled) { + // for emoji group buttons, their highlighter always has a fixed width. + const emojiHighlighterWidth = 24; + this.$.bar.style.width = `${emojiHighlighterWidth}px`; - if (updateTabsScroll) { - this.$.tabs.scrollLeft = tabscrollLeft; - this.$.bar.style.left = - ((index * EMOJI_PICKER_TOTAL_EMOJI_WIDTH - tabscrollLeft)) + 'px'; + // TODO(b/213120632): Convert the following number literals into + // contextualized constants. + let tabscrollLeft = this.$.tabs.scrollLeft; + if (tabscrollLeft > EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (index - 0.5)) { + tabscrollLeft = 0; + } + if (tabscrollLeft + + EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (GROUP_PER_ROW - 2) < + GROUP_ICON_SIZE * index) { + // 5 = We want the seventh icon to be first. Then -1 for chevron, -1 + // for 1 based indexing. + tabscrollLeft = EMOJI_PICKER_TOTAL_EMOJI_WIDTH * (7); + } + + if (updateTabsScroll) { + this.$.bar.style.left = + ((index * EMOJI_PICKER_TOTAL_EMOJI_WIDTH - tabscrollLeft)) + 'px'; + } else { + this.$.bar.style.left = ((index * EMOJI_PICKER_TOTAL_EMOJI_WIDTH - + this.$.tabs.scrollLeft)) + + 'px'; + } + + // only update tab scroll when using emoji-based subcategory, because + // the scroll position of the text-based subcategory bar is controlled + // differently. + if (updateTabsScroll && !this.textSubcategoryBarEnabled) { + this.$.tabs.scrollLeft = tabscrollLeft; + } } else { - this.$.bar.style.left = ((index * EMOJI_PICKER_TOTAL_EMOJI_WIDTH - - this.$.tabs.scrollLeft)) + - 'px'; + const subcategoryTabs = + Array.from(this.$.tabs.getElementsByClassName('tab')); + + // for text group button, the highlight bar only spans its inner width, + // which excludes both padding and margin. + const barInlineGap = 9; + this.$.bar.style.left = `${ + subcategoryTabs[index].offsetLeft - EMOJI_PICKER_SIDE_PADDING - + this.$.tabs.scrollLeft}px`; + this.$.bar.style.width = + `${subcategoryTabs[index].clientWidth - barInlineGap * 2}px`; + + // TODO(b/213230435): fix the bar width and left position when the + // history tab is active } } } - hideDialogs() { this.hideEmojiVariants(); if (this.history.emoji.length > 0) { @@ -634,6 +675,11 @@ this.set('emojiGroupTabs', [historyTab, ...categoryTabs]); this.set('pagination', 1); this.updateChevrons(); + this.scrollToGroup(this.emojiGroupTabs[0].groupId); + afterNextRender(this, () => { + this.updateActiveGroup(true); + this.$.tabs.scrollLeft = 0; + }); } } @@ -659,16 +705,6 @@ } /** - * Returns an array of tabs that have the matched page number. - * @private - * @param {Array<SubcategoryData>} tabs - * @param {number} pageNumber - */ - getGroupTabsByPagination(tabs, pageNumber) { - return tabs.filter((tab) => tab.pagination === pageNumber); - } - - /** * Returns the array of page numbers which starts at 1 and finishes at the * last pagination. * @private
diff --git a/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.js b/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.js index 668e7c7..2ba8df6 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.js +++ b/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.js
@@ -213,4 +213,9 @@ disabled: false, pagination: 4 }, -]; \ No newline at end of file +]; + +// TODO(b/211520561): remove this after the emoticon loading logic is finished. +export const EMPTY_EMOTICON_DATA = + V2_SUBCATEGORY_TABS.filter((tab) => tab.category === 'emoticon') + .map(tab => ({group: tab.name, emoji: []})); \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/text_group_button.html b/chrome/browser/resources/chromeos/emoji_picker/text_group_button.html index d037a6f..57efc8dd 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/text_group_button.html +++ b/chrome/browser/resources/chromeos/emoji_picker/text_group_button.html
@@ -6,8 +6,9 @@ color: var(--cros-text-color-primary); font-size: 12px; margin: 0; + margin-inline: 5px; min-width: unset; - padding-inline: 8px; + padding-inline: 4px; width: max-content; }
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html index bbfd5878..5b1571f 100644 --- a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html +++ b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html
@@ -37,9 +37,7 @@ --disabled-border-color: var(--cros-button-stroke-color-secondary-disabled); --disabled-text-color: var(--cros-button-label-color-secondary-disabled); - /* TODO(crbug.com/1275388): use blend() instead */ - --hover-bg-action: linear-gradient(rgba(0 0 0 / 8%), rgba(0 0 0 / 8%)), - var(--cros-button-background-color-primary); + --hover-bg-action: var(--cros-button-background-color-primary-hover-preblended); --hover-bg-color: var(--cros-button-background-color-secondary-hover); --hover-border-color: var(--cros-button-stroke-color-secondary-hover); --ink-color: var(--cros-button-ripple-color-secondary);
diff --git a/chrome/browser/resources/extensions/detail_view.html b/chrome/browser/resources/extensions/detail_view.html index 65f5b04..a582018 100644 --- a/chrome/browser/resources/extensions/detail_view.html +++ b/chrome/browser/resources/extensions/detail_view.html
@@ -327,6 +327,7 @@ if="[[showFreeformRuntimeHostPermissions_(data.*)]]"> <extensions-runtime-host-permissions permissions="[[data.permissions.runtimeHostPermissions]]" + enable-enhanced-site-controls="[[enableEnhancedSiteControls]]" delegate="[[delegate]]" item-id="[[data.id]]"> </extensions-runtime-host-permissions>
diff --git a/chrome/browser/resources/extensions/detail_view.ts b/chrome/browser/resources/extensions/detail_view.ts index 949349a..2614377 100644 --- a/chrome/browser/resources/extensions/detail_view.ts +++ b/chrome/browser/resources/extensions/detail_view.ts
@@ -78,6 +78,13 @@ /** Whether the user has enabled the UI's developer mode. */ inDevMode: Boolean, + /** + * Whether enhanced site controls have been enabled (through a feature + * flag). For this page, there are some changes to the site permissions + * section. + */ + enableEnhancedSiteControls: Boolean, + /** Whether "allow in incognito" option should be shown. */ incognitoAvailable: Boolean, @@ -96,6 +103,7 @@ data: chrome.developerPrivate.ExtensionInfo; delegate: ItemDelegate; inDevMode: boolean; + enableEnhancedSiteControls: boolean; incognitoAvailable: boolean; showActivityLog: boolean; fromActivityLog: boolean;
diff --git a/chrome/browser/resources/extensions/extensions.gni b/chrome/browser/resources/extensions/extensions.gni index 07319d1..1606dad 100644 --- a/chrome/browser/resources/extensions/extensions.gni +++ b/chrome/browser/resources/extensions/extensions.gni
@@ -48,6 +48,7 @@ "shared_vars.ts", "shortcut_input.ts", "sidebar.ts", + "site_permissions.ts", "toggle_row.ts", "toolbar.ts", ]
diff --git a/chrome/browser/resources/extensions/manager.html b/chrome/browser/resources/extensions/manager.html index d8f993e..7d9a5bd7 100644 --- a/chrome/browser/resources/extensions/manager.html +++ b/chrome/browser/resources/extensions/manager.html
@@ -40,6 +40,7 @@ align="$i18n{textdirection}" on-close="onDrawerClose_"> <div slot="body"> <extensions-sidebar id="sidebar" + enable-enhanced-site-controls="[[enableEnhancedSiteControls]]" on-close-drawer="onCloseDrawer_"> </extensions-sidebar> </div> @@ -56,6 +57,7 @@ <template> <extensions-detail-view delegate="[[delegate]]" slot="view" in-dev-mode="[[inDevMode]]" + enable-enhanced-site-controls="[[enableEnhancedSiteControls]]" from-activity-log="[[fromActivityLog_]]" show-activity-log="[[showActivityLog]]" incognito-available="[[incognitoAvailable_]]" @@ -70,6 +72,11 @@ </extensions-activity-log> </template> </cr-lazy-render> + <cr-lazy-render id="site-permissions"> + <template> + <extensions-site-permissions slot="view"></extensions-site-permissions> + </template> + </cr-lazy-render> <cr-lazy-render id="keyboard-shortcuts"> <template> <extensions-keyboard-shortcuts delegate="[[delegate]]" slot="view"
diff --git a/chrome/browser/resources/extensions/manager.ts b/chrome/browser/resources/extensions/manager.ts index ed24e15..59be9b8 100644 --- a/chrome/browser/resources/extensions/manager.ts +++ b/chrome/browser/resources/extensions/manager.ts
@@ -20,15 +20,16 @@ import './load_error.js'; import './options_dialog.js'; import './sidebar.js'; +import './site_permissions.js'; import './toolbar.js'; // <if expr="chromeos"> import './kiosk_dialog.js'; // </if> +import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; import {ActivityLogExtensionPlaceholder} from './activity_log/activity_log.js'; import {ExtensionsDetailViewElement} from './detail_view.js'; @@ -107,6 +108,11 @@ value: () => loadTimeData.getBoolean('showActivityLog'), }, + enableEnhancedSiteControls: { + type: Boolean, + value: () => loadTimeData.getBoolean('enableEnhancedSiteControls'), + }, + devModeControlledByPolicy: { type: Boolean, value: false, @@ -194,6 +200,7 @@ delegate: Service; inDevMode: boolean; showActivityLog: boolean; + enableEnhancedSiteControls: boolean; devModeControlledByPolicy: boolean; private isChildAccount_: boolean; private incognitoAvailable_: boolean; @@ -552,6 +559,12 @@ } this.activityLogItem_ = data ? assert(data) : activityLogPlaceholder; + } else if ( + toPage === Page.SITE_PERMISSIONS && !this.enableEnhancedSiteControls) { + // Redirect back to the main page if we try to view the new site + // permissions page but the flag is not set. + navigation.replaceWith({page: Page.LIST}); + return; } if (fromPage !== toPage) { @@ -615,7 +628,8 @@ const viewType = (e.composedPath()[0] as HTMLElement).tagName; if (viewType === 'EXTENSIONS-ITEM-LIST' || viewType === 'EXTENSIONS-KEYBOARD-SHORTCUTS' || - viewType === 'EXTENSIONS-ACTIVITY-LOG') { + viewType === 'EXTENSIONS-ACTIVITY-LOG' || + viewType === 'EXTENSIONS-SITE-PERMISSIONS') { return; }
diff --git a/chrome/browser/resources/extensions/navigation_helper.ts b/chrome/browser/resources/extensions/navigation_helper.ts index 9ed4800..8c61e4e 100644 --- a/chrome/browser/resources/extensions/navigation_helper.ts +++ b/chrome/browser/resources/extensions/navigation_helper.ts
@@ -13,6 +13,7 @@ LIST = 'items-list', DETAILS = 'details-view', ACTIVITY_LOG = 'activity-log', + SITE_PERMISSIONS = 'site-permissions', SHORTCUTS = 'keyboard-shortcuts', ERRORS = 'error-page', } @@ -103,6 +104,9 @@ if (this.currentPath_ === '/shortcuts') { return {page: Page.SHORTCUTS}; } + if (this.currentPath_ === '/sitePermissions') { + return {page: Page.SITE_PERMISSIONS}; + } return {page: Page.LIST}; } @@ -182,6 +186,9 @@ path = '/?id=' + entry.extensionId; } break; + case Page.SITE_PERMISSIONS: + path = '/sitePermissions'; + break; case Page.SHORTCUTS: path = '/shortcuts'; break;
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.html b/chrome/browser/resources/extensions/runtime_host_permissions.html index c972ce0..d0de954 100644 --- a/chrome/browser/resources/extensions/runtime_host_permissions.html +++ b/chrome/browser/resources/extensions/runtime_host_permissions.html
@@ -64,7 +64,7 @@ <div id="section-heading"> <div id="section-heading-heading"> <span id="section-heading-text"> - [[getHostPermissionsHeading_(extensionsMenuAccessControlEnabled_)]] + [[getHostPermissionsHeading_(enableEnhancedSiteControls)]] </span> <a class="link-icon-button" aria-label="$i18n{learnMore}" href="$i18n{hostPermissionsLearnMoreLink}" target="_blank" @@ -77,7 +77,7 @@ <select id="host-access" class="md-select" on-change="onHostAccessChange_" value="[[permissions.hostAccess]]" aria-labelledby="section-heading-text"> - <template is="dom-if" if="[[!extensionsMenuAccessControlEnabled_]]"> + <template is="dom-if" if="[[!enableEnhancedSiteControls]]"> <option value="[[HostAccess_.ON_CLICK]]"> $i18n{hostAccessOnClick} </option> @@ -88,7 +88,7 @@ $i18n{hostAccessOnAllSites} </option> </template> - <template is="dom-if" if="[[extensionsMenuAccessControlEnabled_]]"> + <template is="dom-if" if="[[enableEnhancedSiteControls]]"> <option value="[[HostAccess_.ON_CLICK]]"> $i18n{newHostAccessOnClick} </option>
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.ts b/chrome/browser/resources/extensions/runtime_host_permissions.ts index 4710acb1..c6572a6 100644 --- a/chrome/browser/resources/extensions/runtime_host_permissions.ts +++ b/chrome/browser/resources/extensions/runtime_host_permissions.ts
@@ -59,6 +59,8 @@ delegate: Object, + enableEnhancedSiteControls: Boolean, + /** * Whether the dialog to add a new host permission is shown. */ @@ -125,21 +127,13 @@ type: Object, value: chrome.developerPrivate.HostAccess, }, - - /** - * Whether the new site access menu should be shown. - */ - extensionsMenuAccessControlEnabled_: { - type: Boolean, - value: () => - loadTimeData.getBoolean('extensionsMenuAccessControlEnabled'), - }, }; } permissions: chrome.developerPrivate.RuntimeHostPermissions; itemId: string; delegate: ItemDelegate; + enableEnhancedSiteControls: boolean; private showHostDialog_: boolean; private hostDialogModel_: string|null; private hostDialogAnchorElement_: HTMLElement|null; @@ -147,7 +141,6 @@ private actionMenuAnchorElement_: HTMLElement|null; private oldHostAccess_: string|null; private revertingHostAccess_: boolean; - private extensionsMenuAccessControlEnabled_: boolean; private onHostAccessChange_() { const selectMenu = this.$['host-access']; @@ -192,14 +185,14 @@ private getHostPermissionsHeading_(): string { return loadTimeData.getString( - this.extensionsMenuAccessControlEnabled_ ? 'newHostPermissionsHeading' : - 'hostPermissionsHeading'); + this.enableEnhancedSiteControls ? 'newHostPermissionsHeading' : + 'hostPermissionsHeading'); } private showSpecificSites_(): boolean { // TODO(crbug.com/1253673): Show a different "customize for each site" menu // for the new site access menu. - return !this.extensionsMenuAccessControlEnabled_ && + return !this.enableEnhancedSiteControls && this.permissions.hostAccess === chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES; }
diff --git a/chrome/browser/resources/extensions/sidebar.html b/chrome/browser/resources/extensions/sidebar.html index e0f78db..486e3c69 100644 --- a/chrome/browser/resources/extensions/sidebar.html +++ b/chrome/browser/resources/extensions/sidebar.html
@@ -1,4 +1,4 @@ -<style include="cr-icons"> +<style include="cr-icons cr-hidden-style"> :host { --sidebar-inactive-color: #5a5a5a; color: var(--sidebar-inactive-color); @@ -63,6 +63,13 @@ $i18n{sidebarExtensions} <paper-ripple></paper-ripple> </a> + <a class="section-item" id="sections-site-permissions" + hidden="[[!enableEnhancedSiteControls]]" + href="/sitePermissions" on-click="onLinkTap_" + data-path="site-permissions"> + $i18n{sitePermissions} + <paper-ripple></paper-ripple> + </a> <a class="section-item" id="sections-shortcuts" href="/shortcuts" on-click="onLinkTap_" data-path="keyboard-shortcuts"> $i18n{keyboardShortcuts}
diff --git a/chrome/browser/resources/extensions/sidebar.ts b/chrome/browser/resources/extensions/sidebar.ts index 88075c5e..daacfd3 100644 --- a/chrome/browser/resources/extensions/sidebar.ts +++ b/chrome/browser/resources/extensions/sidebar.ts
@@ -2,6 +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_elements/cr_icons_css.m.js'; +import 'chrome://resources/cr_elements/hidden_style_css.m.js'; import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import 'chrome://resources/polymer/v3_0/paper-ripple/paper-ripple.js'; import 'chrome://resources/polymer/v3_0/paper-styles/color.js'; @@ -26,6 +27,14 @@ return html`{__html_template__}`; } + static get properties() { + return { + enableEnhancedSiteControls: Boolean, + }; + } + + enableEnhancedSiteControls: boolean; + ready() { super.ready(); this.setAttribute('role', 'navigation'); @@ -34,8 +43,14 @@ connectedCallback() { super.connectedCallback(); - this.$.sectionMenu.select( - navigation.getCurrentPage().page === Page.SHORTCUTS ? 1 : 0); + const page = navigation.getCurrentPage().page; + let selectIndex = 0; + if (page === Page.SITE_PERMISSIONS) { + selectIndex = 1; + } else if (page === Page.SHORTCUTS) { + selectIndex = 2; + } + this.$.sectionMenu.select(selectIndex); } private onLinkTap_(e: Event) {
diff --git a/chrome/browser/resources/extensions/site_permissions.html b/chrome/browser/resources/extensions/site_permissions.html new file mode 100644 index 0000000..ab51279 --- /dev/null +++ b/chrome/browser/resources/extensions/site_permissions.html
@@ -0,0 +1,14 @@ +<style include="shared-style"> + #container { + box-sizing: border-box; + } + + #header { + font-size: 0.88rem; /* Should be 14px */ + margin: 31px auto 16px auto; + width: var(--cr-toolbar-field-width); + } +</style> +<div class="page-container" id="container"> + <div id="header">$i18n{sitePermissionsPageTitle}</div> +</div>
diff --git a/chrome/browser/resources/extensions/site_permissions.ts b/chrome/browser/resources/extensions/site_permissions.ts new file mode 100644 index 0000000..5a690c7 --- /dev/null +++ b/chrome/browser/resources/extensions/site_permissions.ts
@@ -0,0 +1,24 @@ +// 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/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import './strings.m.js'; +import './shared_style.js'; +import './shared_vars.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +class ExtensionsSitePermissionsElement extends PolymerElement { + static get is() { + return 'extensions-site-permissions'; + } + + static get template() { + return html`{__html_template__}`; + } +} + +customElements.define( + ExtensionsSitePermissionsElement.is, ExtensionsSitePermissionsElement);
diff --git a/chrome/browser/resources/feedback_webui/css/feedback_shared_styles.css b/chrome/browser/resources/feedback_webui/css/feedback_shared_styles.css new file mode 100644 index 0000000..885d6d9b --- /dev/null +++ b/chrome/browser/resources/feedback_webui/css/feedback_shared_styles.css
@@ -0,0 +1,15 @@ +/* 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 url(./feedback_shared_vars.css); + +html, +body { + background-color: var(--feedback-bg-color); + color: var(--feedback-primary-color); +} + +a[href] { + color: var(--feedback-link-color); +}
diff --git a/chrome/browser/resources/feedback_webui/css/feedback_shared_vars.css b/chrome/browser/resources/feedback_webui/css/feedback_shared_vars.css new file mode 100644 index 0000000..195bb77 --- /dev/null +++ b/chrome/browser/resources/feedback_webui/css/feedback_shared_vars.css
@@ -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. */ + +html:not(body) { + /* Google colors used in UI. */ + --google-blue-300: rgb(138, 180, 248); + --google-blue-600: rgb(26, 115, 232); + + --google-grey-200: rgb(232, 234, 237); + --google-grey-900: rgb(32, 33, 36); + + --google-red-300: rgb(242, 139, 130); + --google-red-600: rgb(217, 48, 37); + + /* Feedback specific variables. */ + --feedback-bg-color: #fff; + --feedback-link-color: var(--google-blue-600); + --feedback-primary-color: var(--google-grey-900); +} + +@media (prefers-color-scheme: dark) { + html:not(body) { + --feedback-bg-color: var(--google-grey-900); + --feedback-link-color: var(--google-blue-300); + --feedback-primary-color: var(--google-grey-200); + } +}
diff --git a/chrome/browser/resources/feedback_webui/feedback_resources.grd b/chrome/browser/resources/feedback_webui/feedback_resources.grd index de95245..860383c 100644 --- a/chrome/browser/resources/feedback_webui/feedback_resources.grd +++ b/chrome/browser/resources/feedback_webui/feedback_resources.grd
@@ -18,6 +18,8 @@ <include name="IDR_FEEDBACK_TAKE_SCREENSHOT_JS" file="js/take_screenshot.js" type="BINDATA" /> <include name="IDR_FEEDBACK_QUESTIONNAIRE_JS" file="js/questionnaire.js" type="BINDATA" /> <include name="IDR_FEEDBACK_FEEDBACK_CSS" file="css/feedback.css" type="BINDATA" /> + <include name="IDR_FEEDBACK_FEEDBACK_SHARED_STYLES_CSS" file="css/feedback_shared_styles.css" type="BINDATA" /> + <include name="IDR_FEEDBACK_FEEDBACK_SHARED_VARS_CSS" file="css/feedback_shared_vars.css" type="BINDATA" /> <include name="IDR_FEEDBACK_BUTTON_BUTTER_BAR_CLOSE_PNG" file="images/button_butter_bar_close.png" type="BINDATA" /> <include name="IDR_FEEDBACK_BUTTON_BUTTER_BAR_CLOSE_HOVER_PNG"
diff --git a/chrome/browser/resources/feedback_webui/html/assistant_logs_info.html b/chrome/browser/resources/feedback_webui/html/assistant_logs_info.html index 6af1861..bee2a06 100644 --- a/chrome/browser/resources/feedback_webui/html/assistant_logs_info.html +++ b/chrome/browser/resources/feedback_webui/html/assistant_logs_info.html
@@ -2,8 +2,10 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> +<meta name="color-scheme" content="light dark"> <link rel="stylesheet" href="chrome://resources/css/apps/topbutton_bar.css"></link> <link rel="stylesheet" href="../css/assistant_logs_info.css"></link> +<link rel="stylesheet" href="../css/feedback_shared_styles.css"></link> <script type="module" src="../js/assistant_logs_info.js"></script> </head> <body>
diff --git a/chrome/browser/resources/feedback_webui/html/bluetooth_logs_info.html b/chrome/browser/resources/feedback_webui/html/bluetooth_logs_info.html index 4053a83..feceb495 100644 --- a/chrome/browser/resources/feedback_webui/html/bluetooth_logs_info.html +++ b/chrome/browser/resources/feedback_webui/html/bluetooth_logs_info.html
@@ -1,6 +1,8 @@ <!doctype html> <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> + <meta name="color-scheme" content="light dark"> + <link rel="stylesheet" href="../css/feedback_shared_styles.css"> </head> <body> <div id="bluetooth-logs-info-container"> @@ -8,4 +10,3 @@ </div> </body> <html> -
diff --git a/chrome/browser/resources/feedback_webui/html/default.html b/chrome/browser/resources/feedback_webui/html/default.html index a5b1224..b1abef2 100644 --- a/chrome/browser/resources/feedback_webui/html/default.html +++ b/chrome/browser/resources/feedback_webui/html/default.html
@@ -3,10 +3,12 @@ <head> <title>$i18n{appTitle} </title> <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/apps/common.css"></link> </link> <link rel="stylesheet" href="../css/feedback.css"> + <link rel="stylesheet" href="../css/feedback_shared_styles.css"> <script type="module" src="../js/feedback.js"></script> </head>
diff --git a/chrome/browser/resources/feedback_webui/html/sys_info.html b/chrome/browser/resources/feedback_webui/html/sys_info.html index 43bbcf4..1517e3ce 100644 --- a/chrome/browser/resources/feedback_webui/html/sys_info.html +++ b/chrome/browser/resources/feedback_webui/html/sys_info.html
@@ -2,11 +2,13 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta name="color-scheme" content="light dark"> <title>$i18n{sysinfoPageTitle}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/spinner.css"> <link rel="stylesheet" href="../../about_sys/about_sys.css"> <link rel="stylesheet" href="../css/sys_info.css"> + <link rel="stylesheet" href="../css/feedback_shared_styles.css"> <script type="module" src="../js/sys_info.js"></script> </head>
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 0dd3939..18457c0 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -59,6 +59,7 @@ /** * Credentials passed with 'authCompleted' message. + * `isAvailableInArc` field is optional and is used only on Chrome OS. * @typedef {{ * email: string, * gaiaId: string, @@ -71,7 +72,8 @@ * trusted: boolean, * services: Array, * passwordAttributes: !PasswordAttributes, - * syncTrustedVaultKeys: !SyncTrustedVaultKeys + * syncTrustedVaultKeys: !SyncTrustedVaultKeys, + * isAvailableInArc: (boolean|undefined), * }} */ /* #export */ let AuthCompletedCredentials;
diff --git a/chrome/browser/resources/inline_login/inline_login_app.js b/chrome/browser/resources/inline_login/inline_login_app.js index bd3405f..2e793a8 100644 --- a/chrome/browser/resources/inline_login/inline_login_app.js +++ b/chrome/browser/resources/inline_login/inline_login_app.js
@@ -80,6 +80,18 @@ }, /* + * True if `kArcAccountRestrictions` feature is enabled. + * @private + */ + isArcAccountRestrictionsEnabled_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('isArcAccountRestrictionsEnabled'); + }, + readOnly: true, + }, + + /* * True if the dialog is open for reauthentication. * @private */ @@ -87,6 +99,15 @@ type: Boolean, value: false, }, + + /* + * True if the account should be available in ARC++ after addition. + * @private + */ + isAvailableInArc_: { + type: Boolean, + value: false, + }, // </if> /** @@ -207,7 +228,16 @@ */ onAuthCompleted_(e) { this.loading_ = true; - this.browserProxy_.completeLogin(e.detail); + /** @type {!AuthCompletedCredentials} */ + const credentials = e.detail; + + // <if expr="chromeos_ash"> + if (this.isArcAccountRestrictionsEnabled_ && !this.isReauthentication_) { + credentials.isAvailableInArc = this.isAvailableInArc_; + } + // </if> + + this.browserProxy_.completeLogin(credentials); }, /** @private */
diff --git a/chrome/browser/resources/pdf/BUILD.gn b/chrome/browser/resources/pdf/BUILD.gn index 99aecf0e8..f20f682 100644 --- a/chrome/browser/resources/pdf/BUILD.gn +++ b/chrome/browser/resources/pdf/BUILD.gn
@@ -10,6 +10,7 @@ import("//tools/polymer/html_to_js.gni") import("//ui/webui/resources/tools/generate_grd.gni") import("../tools/optimize_webui.gni") +import("./pdf.gni") preprocess_folder = "preprocessed" preprocess_manifest = "preprocessed_manifest.json" @@ -22,28 +23,7 @@ out_folder = "$target_gen_dir/$preprocess_folder" out_manifest = "$target_gen_dir/$preprocess_manifest" defines = [ "enable_ink=$enable_ink" ] - in_files = [ - "bookmark_type.js", - "constants.js", - "controller.js", - "gesture_detector.js", - "internal_plugin.js", - "local_storage_proxy.js", - "metrics.js", - "navigator.js", - "open_pdf_params_parser.js", - "pdf_scripting_api.js", - "pdf_viewer_base.js", - "pdf_viewer_utils.js", - "pdf_viewer_wrapper.js", - "viewport.js", - "viewport_scroller.js", - "zoom_manager.js", - ] - - if (enable_ink) { - in_files += [ "ink_controller.js" ] - } + in_files = pdf_non_webcomponents_files + shared_non_webcomponents_files } preprocess_if_expr("preprocess_generated") { @@ -52,33 +32,46 @@ out_folder = "$target_gen_dir/$preprocess_folder" out_manifest = "$target_gen_dir/$preprocess_gen_manifest" defines = [ "enable_ink=$enable_ink" ] - in_files = [ - "elements/icons.js", - "elements/shared-css.js", - "elements/shared-vars.js", - "elements/viewer-bookmark.js", - "elements/viewer-document-outline.js", - "elements/viewer-download-controls.js", - "elements/viewer-error-dialog.js", - "elements/viewer-page-selector.js", - "elements/viewer-password-dialog.js", - "elements/viewer-pdf-sidenav.js", - "elements/viewer-properties-dialog.js", - "elements/viewer-thumbnail-bar.js", - "elements/viewer-thumbnail.js", - "elements/viewer-toolbar.js", - "pdf_viewer.js", - "pdf_viewer_shared_style.js", + in_files = pdf_webcomponents_files + shared_webcomponents_files +} + +# Extra files that are needed by Print Preview. +preprocess_if_expr("preprocess_print_preview") { + in_folder = "./" + out_folder = "$target_gen_dir/$preprocess_folder" + in_files = print_preview_non_webcomponents_files +} + +preprocess_if_expr("preprocess_print_preview_generated") { + deps = [ ":web_components" ] + in_folder = target_gen_dir + out_folder = "$target_gen_dir/$preprocess_folder" + in_files = print_preview_webcomponents_files +} + +generate_grd("build_print_preview_grdp") { + input_files = + print_preview_non_webcomponents_files + shared_non_webcomponents_files + + print_preview_webcomponents_files + shared_webcomponents_files + input_files_base_dir = rebase_path("$target_gen_dir/$preprocess_folder", "//") + deps = [ + ":preprocess", + ":preprocess_generated", + ":preprocess_print_preview", + ":preprocess_print_preview_generated", ] - if (enable_ink) { - in_files += [ - "elements/viewer-annotations-bar.js", - "elements/viewer-annotations-mode-dialog.js", - "elements/viewer-ink-host.js", - "elements/viewer-pen-options.js", - "elements/viewer-toolbar-dropdown.js", - ] - } + resource_path_rewrites = [ + "index_pp.html|index.html", + + # Expose pdf_viewer_pp.js as pdf_viewer_wrapper.js so that the PDF viewer + # and Print Preview viewer can use the same main.js source. + "pdf_viewer_pp.js|pdf_viewer_wrapper.js", + ] + grd_prefix = "print_preview_pdf" + + # Print Preview expects to import from "pdf/" relative path + resource_path_prefix = "pdf" + out_grd = "$target_gen_dir/${grd_prefix}_resources.grdp" } # Just copy to $preprocess_folder. @@ -187,19 +180,9 @@ assert(enable_pdf, "enable_pdf check failed") -group("web_components") { - public_deps = [ - ":web_components_local", - "elements:web_components", - ] -} - -html_to_js("web_components_local") { - js_files = [ - "pdf_viewer.js", - "pdf_viewer_pp.js", - "pdf_viewer_shared_style.js", - ] +html_to_js("web_components") { + js_files = pdf_webcomponents_files + print_preview_webcomponents_files + + shared_webcomponents_files } group("closure_compile") {
diff --git a/chrome/browser/resources/pdf/elements/BUILD.gn b/chrome/browser/resources/pdf/elements/BUILD.gn index 8c63a4e..66fb3d3 100644 --- a/chrome/browser/resources/pdf/elements/BUILD.gn +++ b/chrome/browser/resources/pdf/elements/BUILD.gn
@@ -4,7 +4,6 @@ import("//pdf/features.gni") import("//third_party/closure_compiler/compile_js.gni") -import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true @@ -173,34 +172,3 @@ js_library("viewer-zoom-button") { deps = [] } - -html_to_js("web_components") { - js_files = [ - "icons.js", - "shared-vars.js", - "shared-css.js", - "viewer-bookmark.js", - "viewer-document-outline.js", - "viewer-download-controls.js", - "viewer-error-dialog.js", - "viewer-page-indicator.js", - "viewer-page-selector.js", - "viewer-password-dialog.js", - "viewer-pdf-sidenav.js", - "viewer-properties-dialog.js", - "viewer-thumbnail.js", - "viewer-thumbnail-bar.js", - "viewer-toolbar.js", - "viewer-zoom-button.js", - "viewer-zoom-toolbar.js", - ] - if (enable_ink) { - js_files += [ - "viewer-annotations-bar.js", - "viewer-annotations-mode-dialog.js", - "viewer-ink-host.js", - "viewer-pen-options.js", - "viewer-toolbar-dropdown.js", - ] - } -}
diff --git a/chrome/browser/resources/pdf/pdf.gni b/chrome/browser/resources/pdf/pdf.gni new file mode 100644 index 0000000..997158b --- /dev/null +++ b/chrome/browser/resources/pdf/pdf.gni
@@ -0,0 +1,90 @@ +# Copyright 2022 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("//pdf/features.gni") + +# Files to pass directly to preprocess_if_expr() that are used only in PDF +# Viewer. +pdf_non_webcomponents_files = [ + "bookmark_type.js", + "local_storage_proxy.js", + "navigator.js", + "pdf_viewer_wrapper.js", +] + +if (enable_ink) { + pdf_non_webcomponents_files += [ "ink_controller.js" ] +} + +# Files that need to be passed to html_to_js() that are used only in PDF Viewer. +pdf_webcomponents_files = [ + "elements/shared-css.js", + "elements/viewer-bookmark.js", + "elements/viewer-document-outline.js", + "elements/viewer-download-controls.js", + "elements/viewer-page-selector.js", + "elements/viewer-password-dialog.js", + "elements/viewer-pdf-sidenav.js", + "elements/viewer-properties-dialog.js", + "elements/viewer-thumbnail-bar.js", + "elements/viewer-thumbnail.js", + "elements/viewer-toolbar.js", + "pdf_viewer.js", +] + +if (enable_ink) { + pdf_webcomponents_files += [ + "elements/viewer-annotations-bar.js", + "elements/viewer-annotations-mode-dialog.js", + "elements/viewer-ink-host.js", + "elements/viewer-pen-options.js", + "elements/viewer-toolbar-dropdown.js", + ] +} + +# Files to pass directly to preprocess_if_expr() that are used only in Print +# Preview. Note: browser_api.js, main.js and index.css are also used by the PDF +# viewer, but the current PDF viewer build does not preprocess these files. +print_preview_non_webcomponents_files = [ + "browser_api.js", + "index.css", + "index_pp.html", + "main.js", + "toolbar_manager.js", +] + +# Files that need to be passed to html_to_js() that are used only in Print +# Preview. +print_preview_webcomponents_files = [ + "elements/viewer-page-indicator.js", + "elements/viewer-zoom-button.js", + "elements/viewer-zoom-toolbar.js", + "pdf_viewer_pp.js", +] + +# Files to pass directly to preprocess_if_expr() that are shared by PDF Viewer +# and Print Preview. +shared_non_webcomponents_files = [ + "constants.js", + "controller.js", + "gesture_detector.js", + "internal_plugin.js", + "metrics.js", + "open_pdf_params_parser.js", + "pdf_scripting_api.js", + "pdf_viewer_base.js", + "pdf_viewer_utils.js", + "viewport.js", + "viewport_scroller.js", + "zoom_manager.js", +] + +# Files that need to be passed to html_to_js() that are shared by PDF Viewer +# and Print Preview. +shared_webcomponents_files = [ + "elements/icons.js", + "elements/shared-vars.js", + "elements/viewer-error-dialog.js", + "pdf_viewer_shared_style.js", +]
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn index e13962e..5a16fe7 100644 --- a/chrome/browser/resources/print_preview/BUILD.gn +++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -16,8 +16,6 @@ assert(enable_print_preview, "enable_print_preview check failed") preprocess_folder = "preprocessed" -preprocess_pdf_manifest = "preprocessed_pdf_manifest.json" -preprocess_pdf_gen_manifest = "preprocessed_pdf_gen_manifest.json" if (optimize_webui) { build_manifest = "build_manifest.json" @@ -43,28 +41,15 @@ generate_grd("build_grd") { input_files = [ "print_preview.html" ] input_files_base_dir = rebase_path(".", "//") - deps = [ - ":preprocess_pdf", - ":preprocess_pdf_generated", - ] - manifest_files = [ - "$target_gen_dir/$preprocess_pdf_manifest", - "$target_gen_dir/$preprocess_pdf_gen_manifest", - ] - resource_path_rewrites = [ - "pdf/index_pp.html|pdf/index.html", - - # Expose pdf_viewer_pp.js as pdf_viewer_wrapper.js so that the PDF viewer - # and Print Preview viewer can use the same main.js source. - "pdf/pdf_viewer_pp.js|pdf/pdf_viewer_wrapper.js", - ] + deps = [ "../pdf:build_print_preview_grdp" ] + grdp_files = [ "$root_gen_dir/chrome/browser/resources/pdf/print_preview_pdf_resources.grdp" ] if (optimize_webui) { deps += [ ":build" ] - resource_path_rewrites += [ "print_preview.rollup.js|print_preview.js" ] - manifest_files += [ "$target_gen_dir/$build_manifest" ] + resource_path_rewrites = [ "print_preview.rollup.js|print_preview.js" ] + manifest_files = [ "$target_gen_dir/$build_manifest" ] } else { deps += [ ":build_ts" ] - manifest_files += [ "$target_gen_dir/tsconfig.manifest" ] + manifest_files = [ "$target_gen_dir/tsconfig.manifest" ] } grd_prefix = "print_preview" out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" @@ -87,48 +72,6 @@ in_files = web_component_files } -preprocess_if_expr("preprocess_pdf") { - in_folder = "../" - out_folder = "$target_gen_dir/$preprocess_folder" - out_manifest = "$target_gen_dir/$preprocess_pdf_manifest" - in_files = [ - "pdf/browser_api.js", - "pdf/constants.js", - "pdf/controller.js", - "pdf/gesture_detector.js", - "pdf/index.css", - "pdf/index_pp.html", - "pdf/internal_plugin.js", - "pdf/main.js", - "pdf/metrics.js", - "pdf/open_pdf_params_parser.js", - "pdf/pdf_scripting_api.js", - "pdf/pdf_viewer_utils.js", - "pdf/pdf_viewer_base.js", - "pdf/toolbar_manager.js", - "pdf/viewport.js", - "pdf/viewport_scroller.js", - "pdf/zoom_manager.js", - ] -} - -preprocess_if_expr("preprocess_pdf_generated") { - deps = [ "../pdf:web_components" ] - in_folder = get_path_info("..", "gen_dir") - out_folder = "$target_gen_dir/$preprocess_folder" - out_manifest = "$target_gen_dir/$preprocess_pdf_gen_manifest" - in_files = [ - "pdf/elements/icons.js", - "pdf/elements/shared-vars.js", - "pdf/elements/viewer-error-dialog.js", - "pdf/elements/viewer-page-indicator.js", - "pdf/elements/viewer-zoom-button.js", - "pdf/elements/viewer-zoom-toolbar.js", - "pdf/pdf_viewer_pp.js", - "pdf/pdf_viewer_shared_style.js", - ] -} - grit("resources") { defines = chrome_grit_defines @@ -172,6 +115,5 @@ ":copy_pdf_definitions", ":preprocess", ":preprocess_generated", - ":preprocess_pdf", ] }
diff --git a/chrome/browser/resources/read_later/app.ts b/chrome/browser/resources/read_later/app.ts index 6ec0268e..b25bd0dc8a 100644 --- a/chrome/browser/resources/read_later/app.ts +++ b/chrome/browser/resources/read_later/app.ts
@@ -80,6 +80,7 @@ private currentPageActionButtonState_: CurrentPageActionButtonState; buttonRipples: boolean; private loadingContent_: boolean; + private unifiedSidePanel_: boolean; private apiProxy_: ReadLaterApiProxy = ReadLaterApiProxyImpl.getInstance(); private listenerIds_: number[] = []; private visibilityChangedListener_: () => void; @@ -109,6 +110,10 @@ (state: CurrentPageActionButtonState) => this.updateCurrentPageActionButton_(state))); + if (this.unifiedSidePanel_) { + this.apiProxy_.showUI(); + } + // If added in a visible state update current read later items. if (document.visibilityState === 'visible') { this.updateReadLaterEntries_();
diff --git a/chrome/browser/resources/read_later/side_panel/bookmarks_api_proxy.ts b/chrome/browser/resources/read_later/side_panel/bookmarks_api_proxy.ts index 4b3704e..1e3c8fd4 100644 --- a/chrome/browser/resources/read_later/side_panel/bookmarks_api_proxy.ts +++ b/chrome/browser/resources/read_later/side_panel/bookmarks_api_proxy.ts
@@ -2,9 +2,6 @@ // 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 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'; - import {ChromeEvent} from '/tools/typescript/definitions/chrome_event.js'; import {ClickModifiers} from 'chrome://resources/mojo/ui/base/mojom/window_open_disposition.mojom-webui.js';
diff --git a/chrome/browser/resources/read_later/side_panel/reader_mode/reader_mode_api_proxy.ts b/chrome/browser/resources/read_later/side_panel/reader_mode/reader_mode_api_proxy.ts index 3cfe819..1ba9cec 100644 --- a/chrome/browser/resources/read_later/side_panel/reader_mode/reader_mode_api_proxy.ts +++ b/chrome/browser/resources/read_later/side_panel/reader_mode/reader_mode_api_proxy.ts
@@ -2,9 +2,6 @@ // 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 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'; - import {PageHandlerFactory, PageHandlerRemote} from './reader_mode.mojom-webui.js'; let instance: ReaderModeApiProxy|null = null;
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 336dd90..dc75f495 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -46,6 +46,7 @@ ":preprocess_v3", "../../../../../ui/webui/resources:preprocess", "../../nearby_share/shared:preprocess_v3", + "//ui/webui/resources/cr_components/app_management:build_ts", ] excludes = [ "chrome://resources/mojo/chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom-lite.js", @@ -61,10 +62,8 @@ "chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js", "chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js", "chrome://resources/cr_components/app_management/app_management.mojom-lite.js", - "chrome://resources/cr_components/app_management/file_path.mojom-lite.js", - "chrome://resources/cr_components/app_management/image.mojom-lite.js", - "chrome://resources/cr_components/app_management/safe_base_name.mojom-lite.js", - "chrome://resources/cr_components/app_management/types.mojom-lite.js", + "chrome://resources/cr_components/app_management/app_management.mojom-webui.js", + "chrome://resources/cr_components/app_management/types.mojom-webui.js", "chrome://resources/js/cr.m.js", "chrome://resources/chromeos/colors/cros_styles.css", "chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js", @@ -220,6 +219,7 @@ ":preprocess_mojo_v3", ":preprocess_v3", "../../nearby_share/shared:build_v3_grdp", + "//ui/webui/resources/cr_components/app_management:build_ts", ] grdp_files += [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_share_resources_v3.grdp" ] manifest_files += [ @@ -267,6 +267,7 @@ "chromeos/os_apps_page/app_management_page/store.js", "chromeos/os_apps_page/app_management_page/store_client.js", "chromeos/os_apps_page/app_management_page/util.js", + "chromeos/os_apps_page/app_management_page/types.js", "chromeos/os_apps_page/app_notifications_page/mojo_interface_provider.js", "chromeos/os_languages_page/input_method_settings.js", "chromeos/os_languages_page/languages_browser_proxy.js", @@ -493,7 +494,6 @@ "chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js", "chromeos/os_apps_page/app_management_page/chrome_app_detail_view.js", "chromeos/os_apps_page/app_management_page/dom_switch.js", - "chromeos/os_apps_page/app_management_page/icons.js", "chromeos/os_apps_page/app_management_page/main_view.js", "chromeos/os_apps_page/app_management_page/more_permissions_item.js", "chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js",
diff --git a/chrome/browser/resources/settings/chromeos/OWNERS b/chrome/browser/resources/settings/chromeos/OWNERS index 6564996..aa9bd85 100644 --- a/chrome/browser/resources/settings/chromeos/OWNERS +++ b/chrome/browser/resources/settings/chromeos/OWNERS
@@ -4,6 +4,7 @@ jonmann@chromium.org khorimoto@chromium.org michaelpg@chromium.org +xiaohuic@chromium.org zentaro@chromium.org # For APAC timezone build file related changes only.
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js index e14da02..a3dd04f 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js
@@ -84,6 +84,16 @@ * Cancels the phone hub notification access setup flow. */ cancelNotificationSetup() {} + + /** + * Attempts the phone hub apps access setup flow. + */ + attemptAppsSetup() {} + + /** + * Cancels the phone hub apps access setup flow. + */ + cancelAppsSetup() {} } /** @@ -150,6 +160,16 @@ cancelNotificationSetup() { chrome.send('cancelNotificationSetup'); } + + /** @override */ + attemptAppsSetup() { + chrome.send('attemptAppsSetup'); + } + + /** @override */ + cancelAppsSetup() { + chrome.send('cancelAppsSetup'); + } } cr.addSingletonGetter(MultiDeviceBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js index 1103e5f..c3bf886 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js
@@ -80,6 +80,22 @@ }; /** + * Possible of Phone Hub's permissions setup mode.The value will be assigned + * when the user clicks on the settings UI. Basically, INIT_MODE will be + * default value, which means it has not been set yet. + * ALL_PERMISSIONS_SETUP_MODE means that we will process notifications and + * apps streaming onboarding flow in order. + * + * @enum {number} + */ + /* #export */ const PhoneHubPermissionsSetupMode = { + INIT_MODE: 0, + NOTIFICATION_SETUP_MODE: 1, + APPS_SETUP_MODE: 2, + ALL_PERMISSIONS_SETUP_MODE: 3, + }; + + /** * Container for the initial data that the page requires in order to display * the correct content. It is also used for receiving status updates during * use. Note that the host device may be verified (enabled or disabled), @@ -122,6 +138,7 @@ MultiDeviceFeatureState, MultiDevicePageContentData, PhoneHubNotificationAccessStatus, + PhoneHubPermissionsSetupMode, SmartLockSignInEnabledState }; });
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html index bdbb5b7..2721e3a 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html
@@ -238,6 +238,7 @@ restamp> <settings-multidevice-permissions-setup-dialog is-password-dialog-showing="{{isPasswordDialogShowing_}}" + phone-permission-setup-mode="{{phonePermissionSetupMode_}}"_ on-close="onHidePhonePermissionsSetupDialog_"> </settings-multidevice-permissions-setup-dialog> </template>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js index 6831dea..de9450b3 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
@@ -68,6 +68,14 @@ }, /** + * @private {?settings.PhoneHubPermissionsSetupMode} + */ + phonePermissionSetupMode_: { + type: Number, + value: null, + }, + + /** * Whether or not Nearby Share is supported which controls if the Nearby * Share settings and subpage are accessible. * @private {boolean} @@ -120,6 +128,7 @@ 'close': 'onDialogClose_', 'feature-toggle-clicked': 'onFeatureToggleClicked_', 'forget-device-requested': 'onForgetDeviceRequested_', + 'permission-setup-requested': 'onPermissionSetupRequested_', }, /** @private {?settings.MultiDeviceBrowserProxy} */ @@ -374,6 +383,8 @@ return; case settings.PhoneHubNotificationAccessStatus .AVAILABLE_BUT_NOT_GRANTED: + this.phonePermissionSetupMode_ = + settings.PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; this.showPhonePermissionSetupDialog_ = true; return; default: @@ -427,6 +438,16 @@ }, /** + * @param {!CustomEvent<!{mode: !settings.PhoneHubPermissionsSetupMode}>} + * event + * @private + */ + onPermissionSetupRequested_(event) { + this.showPhonePermissionSetupDialog_ = true; + this.phonePermissionSetupMode_ = event.detail.mode; + }, + + /** * Checks if the user is in a nested page without a host set and, if so, * navigates them back to the main page. * @private @@ -475,6 +496,8 @@ // param. const urlParams = settings.Router.getInstance().getQueryParameters(); if (urlParams.get('showNotificationAccessSetupDialog') !== null) { + this.phonePermissionSetupMode_ = + settings.PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; this.showPhonePermissionSetupDialog_ = true; } }, @@ -627,6 +650,7 @@ return; } this.showPhonePermissionSetupDialog_ = false; + this.phonePermissionSetupMode_ = null; }, /** @private */
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js index 985d34a5..e123508 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js
@@ -11,11 +11,11 @@ /** * Numerical values should not be changed because they must stay in sync with - * notification_access_setup_operation.h, with the exception of - * CONNECTION_REQUESTED. + * notification_access_setup_operation.h and apps_access_setup_operation.h, + * with the exception of CONNECTION_REQUESTED. * @enum {number} */ -/* #export */ const NotificationAccessSetupOperationStatus = { +/* #export */ const PermissionsSetupStatus = { CONNECTION_REQUESTED: 0, CONNECTING: 1, TIMED_OUT_CONNECTING: 2, @@ -32,7 +32,8 @@ /* #export */ const SetupFlowStatus = { INTRO: 0, SET_LOCKSCREEN: 1, - WAIT_FOR_PHONE: 2, + WAIT_FOR_PHONE_NOTIFICATION: 2, + WAIT_FOR_PHONE_APPS: 3, }; Polymer({ @@ -46,7 +47,7 @@ properties: { /** * A null |setupState_| indicates that the operation has not yet started. - * @private {?NotificationAccessSetupOperationStatus} + * @private {?PermissionsSetupStatus} */ setupState_: { type: Number, @@ -68,7 +69,7 @@ /** @private */ hasStartedSetupAttempt_: { type: Boolean, - computed: 'computeHasStartedSetupAttempt_(setupState_)', + computed: 'computeHasStartedSetupAttempt_(flowState_)', reflectToAttribute: true, }, @@ -127,6 +128,15 @@ value: false, notify: true, }, + + /** + * @private {?settings.PhoneHubPermissionsSetupMode} + */ + phonePermissionSetupMode: { + type: Number, + value: settings.PhoneHubPermissionsSetupMode.INIT_MODE, + notify: true, + }, }, /** @private {?settings.MultiDeviceBrowserProxy} */ @@ -141,20 +151,52 @@ attached() { this.addWebUIListener( 'settings.onNotificationAccessSetupStatusChanged', - this.onSetupStateChanged_.bind(this)); + this.onNotificationSetupStateChanged_.bind(this)); + this.addWebUIListener( + 'settings.onAppsAccessSetupStatusChanged', + this.onAppsSetupStateChanged_.bind(this)); this.$.dialog.showModal(); }, /** - * @param {!NotificationAccessSetupOperationStatus} setupState + * @param {!PermissionsSetupStatus} setupState * @private */ - onSetupStateChanged_(setupState) { + onNotificationSetupStateChanged_(setupState) { + if (this.flowState_ !== SetupFlowStatus.WAIT_FOR_PHONE_NOTIFICATION) { + return; + } + this.setupState_ = setupState; - if (this.setupState_ === - NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY) { + if (this.setupState_ !== PermissionsSetupStatus.COMPLETED_SUCCESSFULLY) { + return; + } + + this.browserProxy_.setFeatureEnabledState( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); + + if (this.phonePermissionSetupMode === + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE) { + this.browserProxy_.attemptAppsSetup(); + this.flowState_ = SetupFlowStatus.WAIT_FOR_PHONE_APPS; + this.setupState_ = PermissionsSetupStatus.CONNECTION_REQUESTED; + } + }, + + /** + * @param {!PermissionsSetupStatus} setupState + * @private + */ + onAppsSetupStateChanged_(setupState) { + if (this.flowState_ !== SetupFlowStatus.WAIT_FOR_PHONE_APPS) { + return; + } + + this.setupState_ = setupState; + + if (this.setupState_ === PermissionsSetupStatus.COMPLETED_SUCCESSFULLY) { this.browserProxy_.setFeatureEnabledState( - settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); + settings.MultiDeviceFeature.ECHE, true); } }, @@ -163,7 +205,7 @@ * @private */ computeHasStartedSetupAttempt_() { - return this.setupState_ !== null; + return this.flowState_ !== SetupFlowStatus.INTRO; }, /** @@ -172,12 +214,9 @@ */ computeIsSetupAttemptInProgress_() { return this.setupState_ === - NotificationAccessSetupOperationStatus - .SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE || - this.setupState_ === - NotificationAccessSetupOperationStatus.CONNECTING || - this.setupState_ === - NotificationAccessSetupOperationStatus.CONNECTION_REQUESTED; + PermissionsSetupStatus.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE || + this.setupState_ === PermissionsSetupStatus.CONNECTING || + this.setupState_ === PermissionsSetupStatus.CONNECTION_REQUESTED; }, /** @@ -185,8 +224,7 @@ * @private */ computeHasCompletedSetupSuccessfully_() { - return this.setupState_ === - NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY; + return this.setupState_ === PermissionsSetupStatus.COMPLETED_SUCCESSFULLY; }, /** @@ -195,7 +233,7 @@ */ computeIsNotificationAccessProhibited_() { return this.setupState_ === - NotificationAccessSetupOperationStatus.NOTIFICATION_ACCESS_PROHIBITED; + PermissionsSetupStatus.NOTIFICATION_ACCESS_PROHIBITED; }, /** @@ -203,12 +241,10 @@ * @private * */ computeDidSetupAttemptFail_() { - return this.setupState_ === - NotificationAccessSetupOperationStatus.TIMED_OUT_CONNECTING || + return this.setupState_ === PermissionsSetupStatus.TIMED_OUT_CONNECTING || + this.setupState_ === PermissionsSetupStatus.CONNECTION_DISCONNECTED || this.setupState_ === - NotificationAccessSetupOperationStatus.CONNECTION_DISCONNECTED || - this.setupState_ === - NotificationAccessSetupOperationStatus.NOTIFICATION_ACCESS_PROHIBITED; + PermissionsSetupStatus.NOTIFICATION_ACCESS_PROHIBITED; }, /** @@ -217,12 +253,10 @@ */ computeShouldShowSetupInstructionsSeparately_() { return this.setupState_ === null || + this.setupState_ === PermissionsSetupStatus.CONNECTION_REQUESTED || this.setupState_ === - NotificationAccessSetupOperationStatus.CONNECTION_REQUESTED || - this.setupState_ === - NotificationAccessSetupOperationStatus - .SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE || - this.setupState_ === NotificationAccessSetupOperationStatus.CONNECTING; + PermissionsSetupStatus.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE || + this.setupState_ === PermissionsSetupStatus.CONNECTING; }, /** @private */ @@ -244,15 +278,29 @@ this.isPasswordDialogShowing = false; break; } - this.flowState_ = SetupFlowStatus.WAIT_FOR_PHONE; - this.browserProxy_.attemptNotificationSetup(); - this.setupState_ = - NotificationAccessSetupOperationStatus.CONNECTION_REQUESTED; + + switch (this.phonePermissionSetupMode) { + case settings.PhoneHubPermissionsSetupMode.APPS_SETUP_MODE: + this.browserProxy_.attemptAppsSetup(); + this.flowState_ = SetupFlowStatus.WAIT_FOR_PHONE_APPS; + this.setupState_ = PermissionsSetupStatus.CONNECTION_REQUESTED; + break; + case settings.PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE: + case settings.PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE: + this.browserProxy_.attemptNotificationSetup(); + this.flowState_ = SetupFlowStatus.WAIT_FOR_PHONE_NOTIFICATION; + this.setupState_ = PermissionsSetupStatus.CONNECTION_REQUESTED; + break; + } }, /** @private */ onCancelClicked_() { - this.browserProxy_.cancelNotificationSetup(); + if (this.flowState_ === SetupFlowStatus.WAIT_FOR_PHONE_NOTIFICATION) { + this.browserProxy_.cancelNotificationSetup(); + } else if (this.flowState_ === SetupFlowStatus.WAIT_FOR_PHONE_APPS) { + this.browserProxy_.cancelAppsSetup(); + } this.$.dialog.close(); }, @@ -271,14 +319,14 @@ * @private */ getTitle_() { + if (this.flowState_ === SetupFlowStatus.INTRO) { + return this.i18n('multideviceNotificationAccessSetupAckTitle'); + } if (this.flowState_ === SetupFlowStatus.SET_LOCKSCREEN) { return this.i18n('multideviceNotificationAccessSetupScreenLockTitle'); } - if (this.setupState_ === null) { - return this.i18n('multideviceNotificationAccessSetupAckTitle'); - } - const Status = NotificationAccessSetupOperationStatus; + const Status = PermissionsSetupStatus; switch (this.setupState_) { case Status.CONNECTION_REQUESTED: case Status.CONNECTING: @@ -307,14 +355,15 @@ * @private */ getDescription_() { - if (this.flowState_ === SetupFlowStatus.SET_LOCKSCREEN) { - return ''; - } - if (this.setupState_ === null) { + if (this.flowState_ === SetupFlowStatus.INTRO) { return this.i18n('multideviceNotificationAccessSetupAckSummary'); } - const Status = NotificationAccessSetupOperationStatus; + if (this.flowState_ === SetupFlowStatus.SET_LOCKSCREEN) { + return ''; + } + + const Status = PermissionsSetupStatus; switch (this.setupState_) { case Status.COMPLETED_SUCCESSFULLY: return this.i18n('multideviceNotificationAccessSetupCompletedSummary'); @@ -344,10 +393,9 @@ * @private */ shouldShowCancelButton_() { - return this.setupState_ !== - NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY && + return this.setupState_ !== PermissionsSetupStatus.COMPLETED_SUCCESSFULLY && this.setupState_ !== - NotificationAccessSetupOperationStatus.NOTIFICATION_ACCESS_PROHIBITED; + PermissionsSetupStatus.NOTIFICATION_ACCESS_PROHIBITED; }, /** @@ -355,10 +403,8 @@ * @private */ shouldShowTryAgainButton_() { - return this.setupState_ === - NotificationAccessSetupOperationStatus.TIMED_OUT_CONNECTING || - this.setupState_ === - NotificationAccessSetupOperationStatus.CONNECTION_DISCONNECTED; + return this.setupState_ === PermissionsSetupStatus.TIMED_OUT_CONNECTING || + this.setupState_ === PermissionsSetupStatus.CONNECTION_DISCONNECTED; }, /**
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js index 12a828e6..7a80cd7 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js
@@ -220,11 +220,15 @@ /** @private */ handlePhoneHubAppsSetupClick_() { - // TODO: Fire event to show a setup dialog. + this.fire( + 'permission-setup-requested', + {mode: PhoneHubPermissionsSetupMode.APPS_SETUP_MODE}); }, /** @private */ handlePhoneHubCombinedSetupClick_() { - // TODO: Fire event to show a setup dialog. + this.fire( + 'permission-setup-requested', + {mode: PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE}); }, });
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn index 5286361..d280dd99 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
@@ -46,7 +46,6 @@ "./app_management_page:store_client", "./app_notifications_page:mojo_interface_provider", "//chrome/browser/ui/webui/settings/chromeos/os_apps_page/mojom:mojom_js_library_for_compile", - "//ui/webui/resources/cr_components/app_management:constants", "//ui/webui/resources/cr_components/chromeos/localized_link:localized_link", "//ui/webui/resources/cr_components/chromeos/localized_link:localized_link", "//ui/webui/resources/js:cr.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn index c69e3c9..3524b85 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -20,7 +20,6 @@ ":chrome_app_detail_view", ":dom_switch", ":fake_page_handler", - ":icons", ":main_view", ":more_permissions_item", ":pin_to_shelf_item", @@ -38,6 +37,9 @@ ] } +js_library("types") { +} + js_library("actions") { deps = [ "//ui/webui/resources/cr_components/app_management:mojo_bindings_js_library_for_compile", @@ -75,6 +77,7 @@ ":util", "//ui/webui/resources/js:load_time_data.m", ] + externs_list = [ "./types.js" ] } js_library("app_management_page") { @@ -97,8 +100,6 @@ ":store_client", ":supported_links_item", ":util", - "//ui/webui/resources/cr_components/app_management:constants", - "//ui/webui/resources/cr_components/app_management:permission_item", ] } @@ -133,10 +134,7 @@ "//ui/webui/resources/cr_components/app_management:mojo_bindings_js_library_for_compile", "//ui/webui/resources/js:promise_resolver.m", ] -} - -js_library("icons") { - deps = [] + externs_list = [ "./types.js" ] } js_library("main_view") { @@ -148,7 +146,6 @@ "../..:os_route.m", "../..:route_observer_behavior", "../../..:router", - "//ui/webui/resources/cr_components/app_management:constants", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m", ] @@ -163,9 +160,7 @@ ":browser_proxy", ":util", "../..:metrics_recorder.m", - "//ui/webui/resources/cr_components/app_management:constants", - "//ui/webui/resources/cr_components/app_management:toggle_row", - "//ui/webui/resources/cr_components/app_management:types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", ] } @@ -178,15 +173,12 @@ ":store_client", ":supported_links_item", ":util", - "//ui/webui/resources/cr_components/app_management:constants", - "//ui/webui/resources/cr_components/app_management:permission_item", ] } js_library("reducers") { deps = [ ":util", - "//ui/webui/resources/cr_components/app_management:types", "//ui/webui/resources/js:cr.m", ] } @@ -195,15 +187,12 @@ deps = [ ":browser_proxy", ":util", - "//ui/webui/resources/cr_components/app_management:constants", - "//ui/webui/resources/cr_components/app_management:toggle_row", - "//ui/webui/resources/cr_components/app_management:types", "//ui/webui/resources/js:assert.m", ] } js_library("shared_style") { - deps = [ "//ui/webui/resources/cr_components/app_management:shared_style" ] + deps = [] } js_library("store") { @@ -216,11 +205,12 @@ js_library("store_client") { deps = [ ":store", - "//ui/webui/resources/cr_components/app_management:types", + "//ui/webui/resources/cr_components/app_management:mojo_bindings_js_library_for_compile", "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js/cr/ui:store", "//ui/webui/resources/js/cr/ui:store_client", ] + externs_list = [ "./types.js" ] } js_library("supported_links_overlapping_apps_dialog") { @@ -249,7 +239,6 @@ ":supported_links_overlapping_apps_dialog", ":util", "../..:metrics_recorder.m", - "//ui/webui/resources/cr_components/app_management:constants", "//ui/webui/resources/cr_components/chromeos/localized_link:localized_link", "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m", "//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group.m", @@ -283,7 +272,6 @@ "arc_detail_view.js", "chrome_app_detail_view.js", "dom_switch.js", - "icons.js", "main_view.js", "more_permissions_item.js", "pin_to_shelf_item.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js index d06db7b..ce8ef03 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js
@@ -54,8 +54,8 @@ }, /** - * @param {AppType} appType - * @return {AppManagementEntryPoint} + * @param {apps.mojom.AppType} appType + * @return {AppManagementEntryPointType} */ getAppManagementEntryPoint_(appType) { switch (appType) {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/arc_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/arc_detail_view.js index 4b2ec16..4221e23f 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/arc_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/arc_detail_view.js
@@ -1,12 +1,12 @@ // Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './icons.js'; import './more_permissions_item.js'; import './pin_to_shelf_item.js'; import './resize_lock_item.js'; import './supported_links_item.js'; import './shared_style.js'; +import '//resources/cr_components/app_management/icons.js'; import '//resources/cr_components/app_management/permission_item.js'; import '//resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn index 1124ca5..6abe519 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn
@@ -19,7 +19,6 @@ "../:util", "../../..:os_route.m", "../../../..:router", - "//ui/webui/resources/cr_components/app_management:permission_item", ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js index e0adc74..e2d097a7 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js
@@ -6,9 +6,9 @@ import {Polymer, html} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import '../icons.js'; import '../pin_to_shelf_item.js'; import '../shared_style.js'; +import '//resources/cr_components/app_management/icons.js'; import '//resources/cr_components/app_management/permission_item.js'; import '//resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js index 79b4d77..eb0eada 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js
@@ -112,11 +112,8 @@ this.fakeHandler.setApps(appList); } else { - this.handler = new appManagement.mojom.PageHandlerRemote(); - const factory = appManagement.mojom.PageHandlerFactory.getRemote(); - factory.createPageHandler( - this.callbackRouter.$.bindNewPipeAndPassRemote(), - this.handler.$.bindNewPipeAndPassReceiver()); + this.handler = ComponentBrowserProxy.getInstance().handler; + this.callbackRouter = ComponentBrowserProxy.getInstance().callbackRouter; } } }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js index cfb5bbf..93d8d78e 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js
@@ -70,7 +70,7 @@ } /** - * @param {AppType} appType + * @param {apps.mojom.AppType} appType * @return {!Object<number, Permission>} */ static createPermissions(appType) { @@ -211,7 +211,7 @@ /** * @param {string} appId - * @param {OptionalBool} pinnedValue + * @param {apps.mojom.OptionalBool} pinnedValue */ setPinned(appId, pinnedValue) { const app = AppManagementStore.getInstance().data.apps[appId];
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js index 5dea01fd..4da9c69 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js
@@ -87,7 +87,10 @@ toggleSetting_() { const newState = assert(toggleOptionalBool(this.app.isPinned)); const newStateBool = convertOptionalBoolToBool(newState); - assert(newStateBool === this.$['toggle-row'].isChecked()); + assert( + newStateBool === + (/** @type {AppManagementToggleRowElement} */ (this.$['toggle-row'])) + .isChecked()); BrowserProxy.getInstance().handler.setPinned( this.app.id, newState,
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn index 4b517b6..3a889b1 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn
@@ -26,8 +26,7 @@ "../:util", "../../..:os_route.m", "../../../..:router", - "//ui/webui/resources/cr_components/app_management:constants", - "//ui/webui/resources/cr_components/app_management:permission_item", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js index 3a92aa5d..1db34689 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '../icons.js'; import '../pin_to_shelf_item.js'; +import '//resources/cr_components/app_management/icons.js'; import '//resources/cr_components/app_management/permission_item.js'; import '../shared_style.js'; import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; @@ -75,7 +75,8 @@ * @private */ onPermissionChanged_: async function(e) { - this.pendingPermissionItem_ = /** @type {Element} */ (e.target); + this.pendingPermissionItem_ = + /** @type {AppManamentPermissionItemElement} */ (e.target); switch (e.target.permissionType) { case 'kCamera': this.dialogText_ =
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js index 45b476d..dd7fd09 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js
@@ -1,11 +1,11 @@ // Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './icons.js'; import './more_permissions_item.js'; import './pin_to_shelf_item.js'; import './supported_links_item.js'; import './shared_style.js'; +import '//resources/cr_components/app_management/icons.js'; import '//resources/cr_components/app_management/permission_item.js'; import '//resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/types.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/types.js new file mode 100644 index 0000000..ff5e86b --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/types.js
@@ -0,0 +1,116 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Closure typedefs for App Management. + */ + +/** + * @typedef {appManagement.mojom.App} + */ +let App; + +/** + * @typedef {appManagement.mojom.ExtensionAppPermissionMessage} + */ +let ExtensionAppPermissionMessage; + +/** + * @typedef {apps.mojom.Permission} + */ +let Permission; + +/** + * Maps app ids to Apps. + * @typedef {!Object<string, App>} + */ +let AppMap; + +/** + * @typedef {{ + * apps: !AppMap, + * selectedAppId: ?string, + * }} + */ +let AppManagementPageState; + +/** + * @typedef {apps.mojom.WindowMode} + */ +let WindowMode; + +/** + * Must be kept in sync with + * ui/webui/resources/cr_components/app_management/constants.ts + * @enum {number} + */ +const AppManagementEntryPointType = { + AppListContextMenuAppInfoArc: 0, + AppListContextMenuAppInfoChromeApp: 1, + AppListContextMenuAppInfoWebApp: 2, + ShelfContextMenuAppInfoArc: 3, + ShelfContextMenuAppInfoChromeApp: 4, + ShelfContextMenuAppInfoWebApp: 5, + MainViewArc: 6, + MainViewChromeApp: 7, + MainViewWebApp: 8, + OsSettingsMainPage: 9, + MainViewPluginVm: 10, + DBusServicePluginVm: 11, + MainViewBorealis: 12, +}; + +/** + * Must be kept in sync with + * ui/webui/resources/cr_components/app_management/constants.ts + * @enum {number} + */ +const AppManagementUserAction = { + ViewOpened: 0, + NativeSettingsOpened: 1, + UninstallDialogLaunched: 2, + PinToShelfTurnedOn: 3, + PinToShelfTurnedOff: 4, + NotificationsTurnedOn: 5, + NotificationsTurnedOff: 6, + LocationTurnedOn: 7, + LocationTurnedOff: 8, + CameraTurnedOn: 9, + CameraTurnedOff: 10, + MicrophoneTurnedOn: 11, + MicrophoneTurnedOff: 12, + ContactsTurnedOn: 13, + ContactsTurnedOff: 14, + StorageTurnedOn: 15, + StorageTurnedOff: 16, + PrintingTurnedOn: 17, + PrintingTurnedOff: 18, + ResizeLockTurnedOn: 19, + ResizeLockTurnedOff: 20, + PreferredAppTurnedOn: 21, + PreferredAppTurnedOff: 22, + SupportedLinksListShown: 23, + OverlappingAppsDialogShown: 24, +}; + +/** + * @constructor + * @extends {HTMLElement} + */ +function AppManamentPermissionItemElement() {} + +/** @type {boolean} */ +AppManamentPermissionItemElement.prototype.permissionType; + +AppManamentPermissionItemElement.prototype.syncPermission = function() {}; +AppManamentPermissionItemElement.prototype.resetToggle = function() {}; + +/** + * @constructor + * @extends {HTMLElement} + */ +function AppManagementToggleRowElement() {} + +/** @return {boolean} */ +AppManagementToggleRowElement.prototype.isChecked = function() {};
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn index 8c5df21..a6c50a84 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn
@@ -42,8 +42,6 @@ deps = [ "../..:metrics_recorder.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_components/app_management:permission_constants", - "//ui/webui/resources/cr_components/app_management:permission_util", ] externs_list = [ "$externs_path/metrics_private.js" ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn index 7998e16..088bedf8 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn
@@ -86,6 +86,7 @@ ":os_bluetooth_change_device_name_dialog", "..:os_route.m", "..:route_observer_behavior", + "..:route_origin_behavior.m", "../..:router", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/bluetooth:bluetooth_device_battery_info",
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.html index 855080c5..7104b7d 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.html
@@ -85,6 +85,14 @@ </template> </div> </div> + <template is="dom-if" + if="[[shouldShowNonAudioOutputDeviceMessage_(device_.*)]]" restamp> + <div id="nonAudioOutputDeviceMessage" + class="settings-box settings-box-text continuation" + aria-live="polite"> + [[getNonAudioOutputDeviceMessage_(device_.*)]] + </div> + </template> <div id="deviceNameSettings" class="settings-box"> <div id="bluetoothDeviceName" class="bluetooth-middle settings-box-text no-padding"
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js index 1ad8e6a..745ef13 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js
@@ -26,6 +26,7 @@ import {Route, Router} from '../../router.js'; import {routes} from '../os_route.m.js'; import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js'; +import {RouteOriginBehavior, RouteOriginBehaviorInterface} from '../route_origin_behavior.m.js'; const mojom = chromeos.bluetoothConfig.mojom; @@ -42,10 +43,11 @@ * @constructor * @extends {PolymerElement} * @implements {RouteObserverBehaviorInterface} + * @implements {RouteOriginBehaviorInterface} * @implements {I18nBehaviorInterface} */ -const SettingsBluetoothDeviceDetailSubpageElementBase = - mixinBehaviors([RouteObserverBehavior, I18nBehavior], PolymerElement); +const SettingsBluetoothDeviceDetailSubpageElementBase = mixinBehaviors( + [RouteObserverBehavior, RouteOriginBehavior, I18nBehavior], PolymerElement); /** @polymer */ class SettingsBluetoothDeviceDetailSubpageElement extends @@ -112,12 +114,30 @@ ]; } + constructor() { + super(); + + /** RouteOriginBehaviorInterface override */ + this.route_ = routes.BLUETOOTH_DEVICE_DETAIL; + } + + /** @override */ + ready() { + super.ready(); + + this.addFocusConfig(routes.POINTERS, '#changeMouseSettings'); + this.addFocusConfig(routes.KEYBOARD, '#changeKeyboardSettings'); + } + /** * RouteObserverBehaviorInterface override * @param {!Route} route + * @param {!Route=} opt_oldRoute */ - currentRouteChanged(route) { - if (route !== routes.BLUETOOTH_DEVICE_DETAIL) { + currentRouteChanged(route, opt_oldRoute) { + super.currentRouteChanged(route, opt_oldRoute); + + if (route !== this.route_) { this.deviceId_ = ''; this.pageState_ = PageState.DISCONNECTED; return; @@ -257,6 +277,36 @@ } } + /** + * @return {boolean} + * @private + */ + shouldShowNonAudioOutputDeviceMessage_() { + if (!this.device_) { + return false; + } + return this.device_.deviceProperties.audioCapability !== + mojom.AudioOutputCapability.kCapableOfAudioOutput; + } + + /** + * Message displayed for devices that are human interactive. + * @return {string} + * @private + */ + getNonAudioOutputDeviceMessage_() { + if (!this.device_) { + return ''; + } + + if (this.device_.deviceProperties.connectionState === + mojom.DeviceConnectionState.kConnected) { + return this.i18n('bluetoothDeviceDetailHIDMessageConnected'); + } + + return this.i18n('bluetoothDeviceDetailHIDMessageDisconnected'); + } + /** @private */ onChangeNameClick_() { this.shouldShowChangeDeviceNameDialog_ = true;
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js index 602a3b2..66e1d992 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js
@@ -16,7 +16,8 @@ import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getBluetoothConfig} from 'chrome://resources/cr_components/chromeos/bluetooth/cros_bluetooth_config.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {Route} from '../../router.js'; + +import {Route, Router} from '../../router.js'; import {routes} from '../os_route.m.js'; import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js'; @@ -99,16 +100,49 @@ }; } + constructor() { + super(); + + /** + * The id of the last device that was selected to view its detail page. + * @private {?string} + */ + this.lastSelectedDeviceId_ = null; + } + /** * RouteObserverBehaviorInterface override * @param {!Route} route + * @param {!Route=} oldRoute */ - currentRouteChanged(route) { + currentRouteChanged(route, oldRoute) { + // If we're navigating to a device's detail page, save the id of the device. + if (route === routes.BLUETOOTH_DEVICE_DETAIL && + oldRoute === routes.BLUETOOTH_DEVICES) { + const queryParams = Router.getInstance().getQueryParameters(); + this.lastSelectedDeviceId_ = queryParams.get('id'); + return; + } + if (route !== routes.BLUETOOTH_DEVICES) { return; } recordBluetoothUiSurfaceMetrics( BluetoothUiSurface.SETTINGS_DEVICE_LIST_SUBPAGE); + + // If a backwards navigation occurred from a Bluetooth device's detail page, + // focus the list item corresponding to that device. + if (oldRoute !== routes.BLUETOOTH_DEVICE_DETAIL) { + return; + } + + // Don't attempt to focus any item unless the last navigation was a + // 'pop' (backwards) navigation. + if (!Router.getInstance().lastRouteChangeWasPopstate()) { + return; + } + + this.focusLastSelectedDeviceItem_(); } /** @private */ @@ -129,6 +163,36 @@ mojom.DeviceConnectionState.kNotConnected); } + /** @private */ + focusLastSelectedDeviceItem_() { + const focusItem = (deviceListSelector, index) => { + const deviceList = this.shadowRoot.querySelector(deviceListSelector); + const items = deviceList.shadowRoot.querySelectorAll( + 'os-settings-paired-bluetooth-list-item'); + if (index >= items.length) { + return; + } + items[index].focus(); + }; + + // Search |connectedDevices_| for the device. + let index = this.connectedDevices_.findIndex( + device => device.deviceProperties.id === this.lastSelectedDeviceId_); + if (index >= 0) { + focusItem(/*deviceListSelector=*/ '#connectedDeviceList', index); + return; + } + + // If |connectedDevices_| doesn't contain the device, search + // |unconnectedDevices_|. + index = this.unconnectedDevices_.findIndex( + device => device.deviceProperties.id === this.lastSelectedDeviceId_); + if (index < 0) { + return; + } + focusItem(/*deviceListSelector=*/ '#unconnectedDeviceList', index); + } + /** * Observer for isBluetoothToggleOn_ that returns early until the previous * value was not undefined to avoid wrongly toggling the Bluetooth state.
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 33e1582..fbc8fce 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -117,6 +117,7 @@ "settings.MetricsConsentState|MetricsConsentState", "settings.PersonalizationHubBrowserProxy|PersonalizationHubBrowserProxy", "settings.PhoneHubNotificationAccessStatus|PhoneHubNotificationAccessStatus", + "settings.PhoneHubPermissionsSetupMode|PhoneHubPermissionsSetupMode", "settings.PowerSource|PowerSource", "settings.PowerManagementSettings|PowerManagementSettings", "settings.printing.alphabeticalSort|alphabeticalSort", @@ -214,7 +215,7 @@ "chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.html|KerberosAccount,KerberosAccountsBrowserProxyImpl,KerberosAccountsBrowserProxy,KerberosErrorType,KerberosConfigErrorCode,ValidateKerberosConfigResult", "chrome/browser/resources/settings/chromeos/metrics_recorder.html|recordSettingChange, recordSearch, setUserActionRecorderForTesting,recordPageFocus,recordPageBlur,recordClick,recordNavigation", "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html|MultiDeviceBrowserProxy,MultiDeviceBrowserProxyImpl", - "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.html|MultiDeviceSettingsMode,MultiDeviceFeature,MultiDeviceFeatureState,MultiDevicePageContentData,PhoneHubNotificationAccessStatus,SmartLockSignInEnabledState", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.html|MultiDeviceSettingsMode,MultiDeviceFeature,MultiDeviceFeatureState,MultiDevicePageContentData,PhoneHubNotificationAccessStatus,PhoneHubPermissionsSetupMode,SmartLockSignInEnabledState", "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.html|MultiDeviceFeatureBehavior", "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html|MultiDeviceBrowserProxy,MultiDeviceBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_account_manager_browser_proxy.html|NearbyAccountManagerBrowserProxy,NearbyAccountManagerBrowserProxyImpl",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index dd7844f6..22a81698 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -54,7 +54,7 @@ import './os_apps_page/app_management_page/borealis_page/borealis_detail_view.js'; import './os_apps_page/app_management_page/chrome_app_detail_view.js'; import './os_apps_page/app_management_page/dom_switch.js'; -import './os_apps_page/app_management_page/icons.js'; +import '//resources/cr_components/app_management/icons.js'; import './os_apps_page/app_management_page/main_view.js'; import './os_apps_page/app_management_page/pin_to_shelf_item.js'; import './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js'; @@ -119,8 +119,9 @@ export {KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType} from './kerberos_page/kerberos_accounts_browser_proxy.js'; export {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from './metrics_recorder.m.js'; export {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_page/multidevice_browser_proxy.m.js'; -export {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubNotificationAccessStatus, SmartLockSignInEnabledState} from './multidevice_page/multidevice_constants.m.js'; +export {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubNotificationAccessStatus, PhoneHubPermissionsSetupMode, SmartLockSignInEnabledState} from './multidevice_page/multidevice_constants.m.js'; export {NotificationAccessSetupOperationStatus} from './multidevice_page/multidevice_notification_access_setup_dialog.m.js'; +export {PermissionsSetupStatus} from './multidevice_page/multidevice_permissions_setup_dialog.m.js'; export {Account, NearbyAccountManagerBrowserProxy, NearbyAccountManagerBrowserProxyImpl} from './nearby_share_page/nearby_account_manager_browser_proxy.m.js'; export {getReceiveManager, observeReceiveManager, setReceiveManagerForTesting} from './nearby_share_page/nearby_share_receive_manager.m.js'; export {dataUsageStringToEnum, NearbyShareDataUsage} from './nearby_share_page/types.m.js';
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts index 8e7ade3..56d35f5 100644 --- a/chrome/browser/resources/settings/lazy_load.ts +++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -141,6 +141,7 @@ export {SettingsOmniboxExtensionEntryElement} from './search_engines_page/omnibox_extension_entry.js'; export {SettingsSearchEngineDialogElement} from './search_engines_page/search_engine_dialog.js'; export {SettingsSearchEngineEntryElement} from './search_engines_page/search_engine_entry.js'; +export {SettingsSearchEnginesListElement} from './search_engines_page/search_engines_list.js'; export {SettingsSearchEnginesPageElement} from './search_engines_page/search_engines_page.js'; export {AddSiteDialogElement} from './site_settings/add_site_dialog.js'; export {AllSitesElement} from './site_settings/all_sites.js';
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html index 4c593ea4..310251147 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
@@ -10,14 +10,7 @@ autofocus> </cr-input> <cr-input id="keyword" - label="$i18n{searchEnginesKeyword}" - hidden="[[isActiveSearchEnginesFlagEnabled_]]" - error-message="$i18n{notValid}" - value="{{keyword_}}" on-focus="validate_" on-input="validate_"> - </cr-input> - <cr-input id="keyword" - label="$i18n{searchEnginesShortcut}" - hidden="[[!isActiveSearchEnginesFlagEnabled_]]" + label="[[keywordFieldLabel_]]" error-message="$i18n{notValid}" value="{{keyword_}}" on-focus="validate_" on-input="validate_"> </cr-input>
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.ts b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.ts index 0bdae75..e0bb024 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.ts +++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.ts
@@ -56,6 +56,7 @@ keyword_: String, queryUrl_: String, dialogTitle_: String, + keywordFieldLabel_: String, actionButtonText_: String, isActiveSearchEnginesFlagEnabled_: { @@ -71,6 +72,7 @@ private keyword_: string; private queryUrl_: string; private dialogTitle_: string; + private keywordFieldLabel_: string; private actionButtonText_: string; private browserProxy_: SearchEnginesBrowserProxy = SearchEnginesBrowserProxyImpl.getInstance(); @@ -106,6 +108,10 @@ this.actionButtonText_ = loadTimeData.getString('add'); } + this.keywordFieldLabel_ = this.isActiveSearchEnginesFlagEnabled_ ? + loadTimeData.getString('searchEnginesShortcut') : + loadTimeData.getString('searchEnginesKeyword'); + this.addEventListener('cancel', () => { this.browserProxy_.searchEngineEditCancelled(); });
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html index 0c97e09f..73e6a7a 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
@@ -54,7 +54,8 @@ hidden="[[isActiveSearchEnginesFlagEnabled]]"> $i18n{searchEnginesQueryURL} </span> - <span class="url" role="columnheader" hidden="[[!showQueryUrl]]"> + <span class="url-padded" role="columnheader" + hidden="[[!showQueryUrl]]"> $i18n{searchEnginesQueryURL} </span> <span class="icon-placeholder"></span>
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html index 7718a71..cd8429b 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -110,7 +110,7 @@ </settings-search-engines-list> </template> - <div hidden="[[isActiveSearchEnginesFlagEnabled_]]"> + <template is="dom-if" if="[[!isActiveSearchEnginesFlagEnabled_]]"> <div class="cr-row first"> <h2 class="flex">$i18n{searchEnginesOther}</h2> <cr-button class="secondary-button header-aligned-button" @@ -126,7 +126,7 @@ "[[isActiveSearchEnginesFlagEnabled_]]" name-column-header="$i18n{searchEnginesSearchEngine}"> </settings-search-engines-list> - </div> + </template> <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled_]]"> <div class="cr-row first">
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc index 6ab5a4a8..ecf0a12 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc
@@ -56,11 +56,6 @@ return false; } -bool ChromeEnterpriseRealTimeUrlLookupService::CanAttachReferrerChain() const { - return base::FeatureList::IsEnabled( - kRealTimeUrlLookupReferrerChainForEnterprise); -} - int ChromeEnterpriseRealTimeUrlLookupService::GetReferrerUserGestureLimit() const { return 2;
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h index d869aa8b..48bc2f27 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h
@@ -60,7 +60,6 @@ GURL GetRealTimeLookupUrl() const override; net::NetworkTrafficAnnotationTag GetTrafficAnnotationTag() const override; bool CanPerformFullURLLookupWithToken() const override; - bool CanAttachReferrerChain() const override; int GetReferrerUserGestureLimit() const override; bool CanSendPageLoadToken() const override; void GetAccessToken(
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc index 6ea84c3..2290f74 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/enterprise/connectors/connectors_service.h" #include "chrome/browser/policy/dm_token_utils.h" #include "chrome/browser/safe_browsing/chrome_user_population_helper.h" @@ -18,7 +17,6 @@ #include "components/safe_browsing/core/browser/referrer_chain_provider.h" #include "components/safe_browsing/core/browser/sync/sync_utils.h" #include "components/safe_browsing/core/browser/verdict_cache_manager.h" -#include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/sync/driver/test_sync_service.h" @@ -208,9 +206,6 @@ TEST_F(ChromeEnterpriseRealTimeUrlLookupServiceTest, TestStartLookup_RequestWithDmToken) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - kRealTimeUrlLookupReferrerChainForEnterprise); GURL url("http://example.test/"); SetUpRTLookupResponse(RTLookupResponse::ThreatInfo::DANGEROUS, RTLookupResponse::ThreatInfo::SOCIAL_ENGINEERING, 60,
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 4408423..71a69cc 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -613,6 +613,8 @@ trigger_manager_->StartCollectingThreatDetails( safe_browsing::TriggerType::GAIA_PASSWORD_REUSE, web_contents, resource, url_loader_factory, /*history_service=*/nullptr, + base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, + profile_), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( profile_), TriggerManager::GetSBErrorDisplayOptions(*profile_->GetPrefs(),
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc index e291803..cb7b78621 100644 --- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc +++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/interstitials/chrome_settings_page_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/chrome_controller_client.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -68,6 +69,7 @@ display_options, should_trigger_reporting, HistoryServiceFactory::GetForProfile(profile, ServiceAccessType::EXPLICIT_ACCESS), + base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, profile), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( web_contents->GetBrowserContext()), SafeBrowsingMetricsCollectorFactory::GetForProfile(profile),
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc index f881f5b2..a8f015aa 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_factory.h" #include "chrome/browser/safe_browsing/download_protection/check_client_download_request.h" @@ -485,6 +486,8 @@ report->set_did_proceed(true); report->set_download_verdict( DownloadDangerTypeToDownloadResponseVerdict(item->GetDangerType())); + *report->mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile); std::string serialized_report; if (report->SerializeToString(&serialized_report)) { sb_service_->SendSerializedDownloadReport(profile, serialized_report);
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 6d61f265..da11913e 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -50,6 +50,7 @@ #include "chrome/browser/policy/dm_token_utils.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_factory.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h" @@ -199,8 +200,9 @@ } void SendSerializedDownloadReport(Profile* profile, - const std::string& unused_report) override { + const std::string& report) override { download_report_count_++; + latest_report_ = report; } network::TestURLLoaderFactory* GetTestURLLoaderFactory(Profile* profile) { @@ -220,6 +222,8 @@ int download_report_count() { return download_report_count_; } + std::string latest_report() { return latest_report_; } + protected: ~FakeSafeBrowsingService() override = default; @@ -243,6 +247,7 @@ scoped_refptr<MockSafeBrowsingDatabaseManager> mock_database_manager_; int download_report_count_ = 0; + std::string latest_report_ = ""; }; using NiceMockDownloadItem = NiceMock<download::MockDownloadItem>; @@ -2715,6 +2720,7 @@ FILE_PATH_LITERAL("a.tmp"), // tmp_path FILE_PATH_LITERAL("a.exe")); // final_path content::DownloadItemUtils::AttachInfoForTesting(&item, profile(), nullptr); + std::string token = "token"; ASSERT_EQ(0, sb_service_->download_report_count()); // No report sent if download item without token field. @@ -2722,7 +2728,7 @@ EXPECT_EQ(0, sb_service_->download_report_count()); // No report sent if user is in incognito mode. - DownloadProtectionService::SetDownloadPingToken(&item, "token"); + DownloadProtectionService::SetDownloadPingToken(&item, token); content::DownloadItemUtils::AttachInfoForTesting( &item, profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true), nullptr); @@ -2744,10 +2750,29 @@ // incognito, download item has a token stored and the download is detected to // be dangerous. EXPECT_CALL(item, IsDangerous()).WillRepeatedly(Return(true)); + auto validate_report_contents = [this, token](bool show_download_in_folder) { + ClientSafeBrowsingReportRequest expected_report; + expected_report.set_url(GURL::EmptyGURL().spec()); + expected_report.set_type( + ClientSafeBrowsingReportRequest::DANGEROUS_DOWNLOAD_OPENED); + *expected_report.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); + expected_report.set_download_verdict(ClientDownloadResponse::SAFE); + expected_report.set_did_proceed(true); + expected_report.set_token(token); + expected_report.set_show_download_in_folder(show_download_in_folder); + std::string expected_report_serialized; + expected_report.SerializeToString(&expected_report_serialized); + + EXPECT_EQ(expected_report_serialized, sb_service_->latest_report()); + }; + download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false); EXPECT_EQ(1, sb_service_->download_report_count()); + validate_report_contents(/* show_download_in_folder */ false); download_service_->MaybeSendDangerousDownloadOpenedReport(&item, true); EXPECT_EQ(2, sb_service_->download_report_count()); + validate_report_contents(/* show_download_in_folder */ true); } TEST_F(DownloadProtectionServiceTest,
diff --git a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc index c0cd773..caad629 100644 --- a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc +++ b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc
@@ -59,7 +59,8 @@ extension_info->set_installed_by_default( extension.was_installed_by_default()); extension_info->set_installed_by_oem(extension.was_installed_by_oem()); - extension_info->set_from_bookmark(extension.from_bookmark()); + // TODO(crbug.com/1065748): Remove this setter. + extension_info->set_from_bookmark(false); extension_info->set_from_webstore(extension.from_webstore()); extension_info->set_converted_from_user_script( extension.converted_from_user_script());
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index bce8dd1c..adc7ae90 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -34,6 +34,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" @@ -329,13 +330,15 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) override { auto details = base::WrapUnique(new ThreatDetails( delegate, web_contents, unsafe_resource, url_loader_factory, - history_service, referrer_chain_provider, trim_to_ad_tags, - std::move(done_callback))); + history_service, get_user_population_callback, referrer_chain_provider, + trim_to_ad_tags, std::move(done_callback))); details_ = details.get(); details->StartCollection(); return details; @@ -371,6 +374,9 @@ HistoryServiceFactory::GetForProfile( Profile::FromBrowserContext(web_contents->GetBrowserContext()), ServiceAccessType::EXPLICIT_ACCESS), + base::BindRepeating( + &safe_browsing::GetUserPopulationForProfile, + Profile::FromBrowserContext(web_contents->GetBrowserContext())), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( web_contents->GetBrowserContext()), SafeBrowsingMetricsCollectorFactory::GetForProfile(
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc index d8ff0caf8..cc589bd9 100644 --- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc +++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_key.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "components/keyed_service/core/service_access_type.h" @@ -225,6 +226,8 @@ report->set_type(ClientSafeBrowsingReportRequest::APK_DOWNLOAD); report->set_url(item->GetOriginalUrl().spec()); report->set_page_url(item->GetTabUrl().spec()); + *report->mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile_); // Fill referrer chain. content::WebContents* web_contents =
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc index b5b94d52..68b8895 100644 --- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc +++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc
@@ -12,6 +12,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/test/base/testing_browser_process.h" @@ -288,6 +289,14 @@ ASSERT_TRUE(report->has_page_url()); EXPECT_EQ(kTabURL, report->page_url()); + ASSERT_TRUE(report->has_population()); + std::string actual_population_serialized; + std::string expected_population_serialized; + report->population().SerializeToString(&actual_population_serialized); + safe_browsing::GetUserPopulationForProfile(profile()).SerializeToString( + &expected_population_serialized); + EXPECT_EQ(expected_population_serialized, actual_population_serialized); + ASSERT_TRUE(report->has_download_item_info()); ASSERT_TRUE(report->download_item_info().has_url()); EXPECT_EQ(kItemURL, report->download_item_info().url());
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index c9573b71..7a272cf 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/chrome_ui_manager_delegate.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -103,12 +104,15 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider) : ThreatDetails(ui_manager, web_contents, unsafe_resource, url_loader_factory, history_service, + get_user_population_callback, referrer_chain_provider, /*trim_to_ad_tags=*/false, base::BindOnce(&ThreatDetailsWrap::ThreatDetailsDone, @@ -122,6 +126,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags) : ThreatDetails(ui_manager, @@ -129,6 +135,7 @@ unsafe_resource, url_loader_factory, history_service, + get_user_population_callback, referrer_chain_provider, trim_to_ad_tags, base::BindOnce(&ThreatDetailsWrap::ThreatDetailsDone, @@ -245,6 +252,11 @@ profile(), ServiceAccessType::EXPLICIT_ACCESS); } + base::RepeatingCallback<ChromeUserPopulation()> user_population_callback() { + return base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, + profile()); + } + bool ReportWasSent() { return ui_manager_->ReportWasSent(); } protected: @@ -320,6 +332,12 @@ report_pb.client_properties().url_api_type()); EXPECT_EQ(expected_pb.complete(), report_pb.complete()); + std::string expected_population_serialized; + std::string actual_population_serialized; + report_pb.population().SerializeToString(&actual_population_serialized); + expected_pb.population().SerializeToString(&expected_population_serialized); + EXPECT_EQ(expected_population_serialized, actual_population_serialized); + EXPECT_EQ(expected_pb.referrer_chain_size(), report_pb.referrer_chain_size()); // TODO: check each elem url @@ -434,7 +452,56 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); + report->StartCollection(); + + std::string serialized = WaitForThreatDetailsDone( + report.get(), true /* did_proceed*/, 1 /* num_visit */); + + ClientSafeBrowsingReportRequest actual; + actual.ParseFromString(serialized); + + ClientSafeBrowsingReportRequest expected; + expected.set_type(ClientSafeBrowsingReportRequest::URL_MALWARE); + expected.set_url(kThreatURL); + expected.set_page_url(kLandingURL); + // The referrer is stripped to its origin because it's a cross-origin URL. + expected.set_referrer_url( + GURL(kReferrerURL).DeprecatedGetOriginAsURL().spec()); + expected.set_did_proceed(true); + expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); + + ClientSafeBrowsingReportRequest::Resource* pb_resource = + expected.add_resources(); + pb_resource->set_id(0); + pb_resource->set_url(kLandingURL); + pb_resource = expected.add_resources(); + pb_resource->set_id(1); + pb_resource->set_url(kThreatURL); + pb_resource = expected.add_resources(); + pb_resource->set_id(2); + pb_resource->set_url(GURL(kReferrerURL).DeprecatedGetOriginAsURL().spec()); + + VerifyResults(actual, expected); +} + +// Tests creating a simple threat report where no user population is present +TEST_F(ThreatDetailsTest, NoUserPopulation) { + auto navigation = content::NavigationSimulator::CreateBrowserInitiated( + GURL(kLandingURL), web_contents()); + navigation->SetReferrer(blink::mojom::Referrer::New( + GURL(kReferrerURL), network::mojom::ReferrerPolicy::kDefault)); + navigation->Commit(); + + UnsafeResource resource; + InitResource(SB_THREAT_TYPE_URL_MALWARE, ThreatSource::CLIENT_SIDE_DETECTION, + true /* is_subresource */, GURL(kThreatURL), &resource); + + auto report = std::make_unique<ThreatDetailsWrap>( + ui_manager_.get(), web_contents(), resource, nullptr, history_service(), + base::NullCallback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -490,7 +557,7 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -510,6 +577,8 @@ GURL(kReferrerURL).DeprecatedGetOriginAsURL().spec()); expected.set_did_proceed(true); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -541,7 +610,7 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -559,6 +628,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(false); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -590,7 +661,7 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); // Send a message from the DOM, with 2 nodes, a parent and a child. @@ -609,7 +680,8 @@ parent_node->children.push_back(GURL(kDOMChildURL)); params.push_back(std::move(parent_node)); report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(params)); + main_rfh()->GetGlobalId(), + std::move(params)); std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); @@ -625,6 +697,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(false); expected.set_repeat_visit(false); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -742,6 +816,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(false); expected.set_repeat_visit(false); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -814,7 +890,7 @@ { auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::vector<mojom::ThreatDOMDetailsNodePtr> outer_params_copy; @@ -828,10 +904,11 @@ // Send both sets of nodes from different render frames. report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), + main_rfh()->GetGlobalId(), std::move(outer_params_copy)); report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - child_rfh, std::move(inner_params_copy)); + child_rfh->GetGlobalId(), + std::move(inner_params_copy)); std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); @@ -872,14 +949,16 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); // Send both sets of nodes from different render frames. report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - child_rfh, std::move(inner_params)); + child_rfh->GetGlobalId(), + std::move(inner_params)); report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(outer_params)); + main_rfh()->GetGlobalId(), + std::move(outer_params)); std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); @@ -947,6 +1026,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(false); expected.set_repeat_visit(false); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -996,16 +1077,18 @@ true /* is_subresource */, GURL(kThreatURL), &resource); auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); base::HistogramTester histograms; // Send both sets of nodes from different render frames. report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(outer_params)); + main_rfh()->GetGlobalId(), + std::move(outer_params)); report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - child_rfh, std::move(inner_params)); + child_rfh->GetGlobalId(), + std::move(inner_params)); std::string serialized = WaitForThreatDetailsDone( report.get(), false /* did_proceed*/, 0 /* num_visit */); ClientSafeBrowsingReportRequest actual; @@ -1157,6 +1240,8 @@ expected.set_did_proceed(false); expected.set_repeat_visit(false); expected.set_complete(false); // Since the cache was missing. + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1264,16 +1349,16 @@ // Send both sets of nodes, from different render frames. auto trimmed_report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get(), + user_population_callback(), referrer_chain_provider_.get(), /*trim_to_ad_tags=*/true); trimmed_report->StartCollection(); // Send both sets of nodes from different render frames. trimmed_report->OnReceivedThreatDOMDetails( - mojo::Remote<mojom::ThreatReporter>(), child_rfh, + mojo::Remote<mojom::ThreatReporter>(), child_rfh->GetGlobalId(), std::move(inner_params)); trimmed_report->OnReceivedThreatDOMDetails( - mojo::Remote<mojom::ThreatReporter>(), main_rfh(), + mojo::Remote<mojom::ThreatReporter>(), main_rfh()->GetGlobalId(), std::move(outer_params)); std::string serialized = WaitForThreatDetailsDone( @@ -1340,16 +1425,16 @@ // Send both sets of nodes, from different render frames. auto trimmed_report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get(), + user_population_callback(), referrer_chain_provider_.get(), /*trim_to_ad_tags=*/true); trimmed_report->StartCollection(); // Send both sets of nodes from different render frames. trimmed_report->OnReceivedThreatDOMDetails( - mojo::Remote<mojom::ThreatReporter>(), child_rfh, + mojo::Remote<mojom::ThreatReporter>(), child_rfh->GetGlobalId(), std::move(inner_params)); trimmed_report->OnReceivedThreatDOMDetails( - mojo::Remote<mojom::ThreatReporter>(), main_rfh(), + mojo::Remote<mojom::ThreatReporter>(), main_rfh()->GetGlobalId(), std::move(outer_params)); std::string serialized = WaitForThreatDetailsDone( @@ -1375,7 +1460,7 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -1392,6 +1477,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(true); expected.set_repeat_visit(false); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1449,7 +1536,7 @@ // Start ThreatDetails collection. auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); // Simulate clicking don't proceed. @@ -1471,6 +1558,8 @@ expected.set_referrer_url(kReferrerURL); expected.set_did_proceed(false); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1511,7 +1600,7 @@ // Do ThreatDetails collection. auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -1531,6 +1620,8 @@ GURL(kReferrerURL).DeprecatedGetOriginAsURL().spec()); expected.set_did_proceed(true); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1563,7 +1654,7 @@ // Do ThreatDetails collection. auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); std::string serialized = WaitForThreatDetailsDone( @@ -1577,6 +1668,8 @@ expected.set_url(kThreatURL); expected.set_did_proceed(true); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1598,7 +1691,8 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, test_shared_loader_factory_, - history_service(), referrer_chain_provider_.get()); + history_service(), user_population_callback(), + referrer_chain_provider_.get()); report->StartCollection(); SimulateFillCache(kThreatURL); @@ -1606,7 +1700,8 @@ // The cache collection starts after the IPC from the DOM is fired. std::vector<mojom::ThreatDOMDetailsNodePtr> params; report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(params)); + main_rfh()->GetGlobalId(), + std::move(params)); // Let the cache callbacks complete. base::RunLoop().RunUntilIdle(); @@ -1623,6 +1718,8 @@ expected.set_page_url(kLandingURL); expected.set_referrer_url(""); expected.set_did_proceed(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1678,7 +1775,8 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, test_shared_loader_factory_, - history_service(), referrer_chain_provider_.get()); + history_service(), user_population_callback(), + referrer_chain_provider_.get()); report->StartCollection(); SimulateFillCache(kThreatURLHttps); @@ -1686,7 +1784,8 @@ // The cache collection starts after the IPC from the DOM is fired. std::vector<mojom::ThreatDOMDetailsNodePtr> params; report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(params)); + main_rfh()->GetGlobalId(), + std::move(params)); // Let the cache callbacks complete. base::RunLoop().RunUntilIdle(); @@ -1703,6 +1802,8 @@ expected.set_page_url(kLandingURL); expected.set_referrer_url(""); expected.set_did_proceed(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1755,7 +1856,8 @@ auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, test_shared_loader_factory_, - history_service(), referrer_chain_provider_.get()); + history_service(), user_population_callback(), + referrer_chain_provider_.get()); report->StartCollection(); // Simulate no cache entry found. @@ -1769,7 +1871,8 @@ // The cache collection starts after the IPC from the DOM is fired. std::vector<mojom::ThreatDOMDetailsNodePtr> params; report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(params)); + main_rfh()->GetGlobalId(), + std::move(params)); // Let the cache callbacks complete. base::RunLoop().RunUntilIdle(); @@ -1788,6 +1891,8 @@ expected.set_page_url(kLandingURL); expected.set_referrer_url(""); expected.set_did_proceed(false); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources(); @@ -1822,13 +1927,14 @@ true /* is_subresource */, GURL(kThreatURL), &resource); auto report = std::make_unique<ThreatDetailsWrap>( ui_manager_.get(), web_contents(), resource, nullptr, history_service(), - referrer_chain_provider_.get()); + user_population_callback(), referrer_chain_provider_.get()); report->StartCollection(); // The redirects collection starts after the IPC from the DOM is fired. std::vector<mojom::ThreatDOMDetailsNodePtr> params; report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(), - main_rfh(), std::move(params)); + main_rfh()->GetGlobalId(), + std::move(params)); // Let the redirects callbacks complete. base::RunLoop().RunUntilIdle(); @@ -1847,6 +1953,8 @@ expected.set_referrer_url(""); expected.set_did_proceed(true); expected.set_repeat_visit(true); + *expected.mutable_population() = + safe_browsing::GetUserPopulationForProfile(profile()); ClientSafeBrowsingReportRequest::Resource* pb_resource = expected.add_resources();
diff --git a/chrome/browser/safe_browsing/trigger_creator.cc b/chrome/browser/safe_browsing/trigger_creator.cc index b7cb275..fc568af 100644 --- a/chrome/browser/safe_browsing/trigger_creator.cc +++ b/chrome/browser/safe_browsing/trigger_creator.cc
@@ -7,6 +7,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/chrome_user_population_helper.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "components/prefs/pref_service.h" @@ -59,6 +60,8 @@ web_contents, trigger_manager, profile->GetPrefs(), url_loader_factory, HistoryServiceFactory::GetForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS), + base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, + profile), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( profile)); } @@ -71,6 +74,8 @@ web_contents, trigger_manager, profile->GetPrefs(), url_loader_factory, HistoryServiceFactory::GetForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS), + base::BindRepeating(&safe_browsing::GetUserPopulationForProfile, + profile), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( profile), monitor_mode);
diff --git a/chrome/browser/send_tab_to_self/desktop_notification_handler.h b/chrome/browser/send_tab_to_self/desktop_notification_handler.h index 618905a2..aec6a9f 100644 --- a/chrome/browser/send_tab_to_self/desktop_notification_handler.h +++ b/chrome/browser/send_tab_to_self/desktop_notification_handler.h
@@ -21,6 +21,9 @@ // Handler for desktop notifications shown by SendTabToSelf. // Will only be used on desktop platform. // Will be created and owned by the NativeNotificationDisplayService. +// +// TODO(https://crbug.com/1280681): Remove this class, which is only used in +// STTSv1. class DesktopNotificationHandler : public NotificationHandler, public ReceivingUiHandler { public:
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc index a47c038..981ebb835 100644 --- a/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc +++ b/chrome/browser/send_tab_to_self/receiving_ui_handler_registry.cc
@@ -38,18 +38,7 @@ // Instantiates all the handlers relevant to this platform. void ReceivingUiHandlerRegistry::InstantiatePlatformSpecificHandlers( Profile* profile) { -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ - defined(OS_WIN) || defined(OS_FUCHSIA) - - // If STTS 2.0 is enabled the handler will be created when the toolbar - // button registers itself as the delegate. - if (!base::FeatureList::IsEnabled(kSendTabToSelfV2) && - !share::AreUpcomingSharingFeaturesEnabled()) { - applicable_handlers_.push_back( - std::make_unique<send_tab_to_self::DesktopNotificationHandler>( - profile)); - } -#elif defined(OS_ANDROID) +#if defined(OS_ANDROID) applicable_handlers_.push_back( std::make_unique<AndroidNotificationHandler>(profile)); #endif
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc index af95dfd..f28c29b1 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc
@@ -61,19 +61,10 @@ // TODO(skare): ReceivingUiHandler should be able to filter at its level, // or the registry should not be a singleton so we don't need to filter at // all. This narrow patch is less risky, but we should make a larger change. - if (base::FeatureList::IsEnabled(kSendTabToSelfV2) || - share::AreUpcomingSharingFeaturesEnabled()) { - auto* button_controller = - static_cast<SendTabToSelfToolbarIconController*>(handler.get()); - if (button_controller && button_controller->profile() == profile_) { - handler->DisplayNewEntries(new_entries); - } - } else { - auto* desktop_handler = - static_cast<DesktopNotificationHandler*>(handler.get()); - if (desktop_handler && desktop_handler->profile() == profile_) { - handler->DisplayNewEntries(new_entries); - } + auto* button_controller = + static_cast<SendTabToSelfToolbarIconController*>(handler.get()); + if (button_controller && button_controller->profile() == profile_) { + handler->DisplayNewEntries(new_entries); } #else handler->DisplayNewEntries(new_entries);
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.cc index aea823fb..412393f 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.cc +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.cc
@@ -54,6 +54,9 @@ DCHECK(model); if (!model->IsReady()) { + // TODO(https://crbug.com/1280681): Is this legit? In STTSv2, there may not + // *be* a DesktopNotificationHandler for profile, and we're violating the + // lifetime rules of DesktopNotificationHandler here I think. DesktopNotificationHandler(profile).DisplayFailureMessage(shared_url); return; }
diff --git a/chrome/browser/serial/chrome_serial_delegate.cc b/chrome/browser/serial/chrome_serial_delegate.cc index 5beb339..c9bb6fe0 100644 --- a/chrome/browser/serial/chrome_serial_delegate.cc +++ b/chrome/browser/serial/chrome_serial_delegate.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/serial/serial_chooser.h" #include "chrome/browser/ui/serial/serial_chooser_controller.h" -#include "content/public/browser/web_contents.h" +#include "content/public/browser/render_frame_host.h" namespace { @@ -39,23 +39,19 @@ bool ChromeSerialDelegate::CanRequestPortPermission( content::RenderFrameHost* frame) { - auto* web_contents = content::WebContents::FromRenderFrameHost(frame); - auto* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); + auto* profile = Profile::FromBrowserContext(frame->GetBrowserContext()); auto* chooser_context = SerialChooserContextFactory::GetForProfile(profile); return chooser_context->CanRequestObjectPermission( - web_contents->GetMainFrame()->GetLastCommittedOrigin()); + frame->GetMainFrame()->GetLastCommittedOrigin()); } bool ChromeSerialDelegate::HasPortPermission( content::RenderFrameHost* frame, const device::mojom::SerialPortInfo& port) { - auto* web_contents = content::WebContents::FromRenderFrameHost(frame); - auto* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); + auto* profile = Profile::FromBrowserContext(frame->GetBrowserContext()); auto* chooser_context = SerialChooserContextFactory::GetForProfile(profile); return chooser_context->HasPortPermission( - web_contents->GetMainFrame()->GetLastCommittedOrigin(), port); + frame->GetMainFrame()->GetLastCommittedOrigin(), port); } device::mojom::SerialPortManager* ChromeSerialDelegate::GetPortManager(
diff --git a/chrome/browser/sessions/session_restore_interactive_uitest.cc b/chrome/browser/sessions/session_restore_interactive_uitest.cc index 9e546d9..89a1a96 100644 --- a/chrome/browser/sessions/session_restore_interactive_uitest.cc +++ b/chrome/browser/sessions/session_restore_interactive_uitest.cc
@@ -131,7 +131,10 @@ }; // TODO(https://crbug.com/1152160): Enable FocusOnLaunch on Lacros builds. -#if BUILDFLAG(IS_CHROMEOS_LACROS) +// TODO(https://crbug.com/1284590): Flaky on Linux ASAN/TSAN builders. +#if BUILDFLAG(IS_CHROMEOS_LACROS) || \ + (defined(OS_LINUX) && \ + (defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER))) #define MAYBE_FocusOnLaunch DISABLED_FocusOnLaunch #else #define MAYBE_FocusOnLaunch FocusOnLaunch
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsCoordinatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsCoordinatorTest.java index 11214e6..dcc6548 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsCoordinatorTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsCoordinatorTest.java
@@ -18,19 +18,16 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.share.long_screenshots.bitmap_generation.EntryManager; import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.modules.image_editor.ImageEditorModuleProvider; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.url.JUnitTestGURLs; /** Tests for the LongScreenshotsCoordinator. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class LongScreenshotsCoordinatorTest { private LongScreenshotsCoordinator mCoordinator;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMediatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMediatorTest.java index fba7e07..1551470c 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMediatorTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMediatorTest.java
@@ -26,12 +26,10 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.share.long_screenshots.bitmap_generation.EntryManager; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.ui.test.util.DummyUiActivity; /** Tests for the LongScreenshotsMediator. */ @RunWith(ChromeJUnit4ClassRunner.class) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class LongScreenshotsMediatorTest { private Activity mActivity;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/EntryManagerTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/EntryManagerTest.java index c60f4438..761782c0 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/EntryManagerTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/EntryManagerTest.java
@@ -30,10 +30,8 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.share.long_screenshots.bitmap_generation.LongScreenshotsEntry.EntryStatus; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.paintpreview.player.CompositorStatus; import org.chromium.content_public.browser.WebContents; import org.chromium.url.GURL; @@ -44,7 +42,6 @@ */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class EntryManagerTest { private static final long FAKE_CAPTURE_ADDR = 123L;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsCompositorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsCompositorTest.java index 461714c..33963e0 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsCompositorTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsCompositorTest.java
@@ -22,8 +22,6 @@ import org.chromium.base.Callback; import org.chromium.base.UnguessableToken; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; import org.chromium.components.paintpreview.player.CompositorStatus; import org.chromium.components.paintpreview.player.PlayerCompositorDelegate; @@ -34,7 +32,6 @@ */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class LongScreenshotsCompositorTest { private TestPlayerCompositorDelegate mCompositorDelegate; private Bitmap mTestBitmap = Bitmap.createBitmap(512, 1024, Bitmap.Config.ARGB_8888);
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsEntryTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsEntryTest.java index bf6342d6..48507eb 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsEntryTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsEntryTest.java
@@ -23,16 +23,13 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.share.long_screenshots.bitmap_generation.LongScreenshotsEntry.EntryStatus; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.paintpreview.player.CompositorStatus; /** Tests for the LongScreenshotsEntry. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class LongScreenshotsEntryTest { @Mock private Context mContext;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceJUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceJUnitTest.java index aa21dc6c..fcd6775 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceJUnitTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceJUnitTest.java
@@ -27,14 +27,11 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.test.util.browser.Features; /** Unit tests for the Long Screenshot Tab Service Test. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class LongScreenshotsTabServiceJUnitTest { public static final long FAKE_NATIVE_ADDR = 345L;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java index 01524ed..dd2158b 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java
@@ -18,16 +18,13 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Matchers; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.net.test.EmbeddedTestServer; /** Tests for the Paint Preview Tab Manager. */ @RunWith(ChromeJUnit4ClassRunner.class) @@ -72,7 +69,8 @@ @Before public void setUp() throws Exception { - mActivityTestRule.startMainActivityOnBlankPage(); + mActivityTestRule.startMainActivityWithURL( + mActivityTestRule.getTestServer().getURL("/chrome/test/data/android/about.html")); mTab = mActivityTestRule.getActivity().getActivityTab(); mProcessor = new TestCaptureProcessor(); @@ -88,15 +86,8 @@ @Test @MediumTest @Feature({"LongScreenshots"}) - @DisableIf.Build(message = "Flaky on emulators; see https://crbug.com/1282258", - supported_abis_includes = "x86") - public void - testCapturedFilesystem() throws Exception { - EmbeddedTestServer testServer = mActivityTestRule.getTestServer(); - final String url = testServer.getURL("/chrome/test/data/android/about.html"); - + public void testCapturedFilesystem() throws Exception { TestThreadUtils.runOnUiThreadBlocking(() -> { - mTab.loadUrl(new LoadUrlParams(url)); mLongScreenshotsTabService.captureTab( mTab, new Rect(0, 0, 100, 100), /*inMemory=*/false); }); @@ -120,11 +111,7 @@ @MediumTest @Feature({"LongScreenshots"}) public void testCapturedMemory() throws Exception { - EmbeddedTestServer testServer = mActivityTestRule.getTestServer(); - final String url = testServer.getURL("/chrome/test/data/android/about.html"); - TestThreadUtils.runOnUiThreadBlocking(() -> { - mTab.loadUrl(new LoadUrlParams(url)); mLongScreenshotsTabService.captureTab( mTab, new Rect(0, 0, 100, 100), /*inMemory=*/true); });
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/ScreenshotBoundsManagerTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/ScreenshotBoundsManagerTest.java index e0a1c63f..f1e2a8c1 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/ScreenshotBoundsManagerTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/ScreenshotBoundsManagerTest.java
@@ -22,16 +22,13 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.content.browser.RenderCoordinatesImpl; import org.chromium.content.browser.webcontents.WebContentsImpl; /** Tests for the ScreenshotBoundsManager */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -@Features.EnableFeatures(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) public class ScreenshotBoundsManagerTest { @Mock private Context mContext;
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java index 7765a6c0..11f292c 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -136,7 +136,6 @@ @Test @MediumTest - @Features.EnableFeatures({ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT}) @Features.DisableFeatures({ChromeFeatureList.LIGHTWEIGHT_REACTIONS}) @DisabledTest(message = "https://crbug.com/1233184") public void getPropertyModels_screenshotEnabled() { @@ -164,7 +163,6 @@ @Test @MediumTest @Features.EnableFeatures({ChromeFeatureList.LIGHTWEIGHT_REACTIONS}) - @Features.DisableFeatures({ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT}) public void getPropertyModels_lightweightReactionsEnabled() { setUpChromeProvidedSharingOptionsProviderTest( /*printingEnabled=*/false, LinkGeneration.MAX); @@ -178,6 +176,7 @@ ImmutableList.of( mActivity.getResources().getString(R.string.sharing_webnotes_create_card), mActivity.getResources().getString(R.string.sharing_screenshot), + mActivity.getResources().getString(R.string.sharing_long_screenshot), mActivity.getResources().getString(R.string.sharing_lightweight_reactions), mActivity.getResources().getString(R.string.sharing_copy_image), mActivity.getResources().getString(R.string.sharing_copy), @@ -189,11 +188,9 @@ @Test @MediumTest - @Features.DisableFeatures({ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT, - ChromeFeatureList.LIGHTWEIGHT_REACTIONS}) + @Features.DisableFeatures({ChromeFeatureList.LIGHTWEIGHT_REACTIONS}) @DisabledTest(message = "https://crbug.com/1233184") - public void - getPropertyModels_printingEnabled_includesPrinting() { + public void getPropertyModels_printingEnabled_includesPrinting() { setUpChromeProvidedSharingOptionsProviderTest( /*printingEnabled=*/true, LinkGeneration.MAX); List<PropertyModel> propertyModels = @@ -206,6 +203,7 @@ ImmutableList.of( mActivity.getResources().getString(R.string.sharing_webnotes_create_card), mActivity.getResources().getString(R.string.sharing_screenshot), + mActivity.getResources().getString(R.string.sharing_long_screenshot), mActivity.getResources().getString(R.string.sharing_copy_image), mActivity.getResources().getString(R.string.sharing_copy), mActivity.getResources().getString(
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc index 9f551a89e..2d53c36 100644 --- a/chrome/browser/shell_integration_linux.cc +++ b/chrome/browser/shell_integration_linux.cc
@@ -44,6 +44,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/shell_integration.h" +#include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_shortcut.h" #include "chrome/common/buildflags.h" #include "chrome/common/channel_info.h" @@ -325,6 +326,14 @@ return app_name; } +std::string GetXdgAppIdForWebApp(std::string app_name, + const base::FilePath& profile_path) { + if (base::StartsWith(app_name, web_app::kCrxAppPrefix)) + app_name = app_name.substr(strlen(web_app::kCrxAppPrefix)); + return GetDesktopBaseName( + web_app::GetAppShortcutFilename(profile_path, app_name).AsUTF8Unsafe()); +} + base::FilePath GetDataWriteLocation(base::Environment* env) { return base::nix::GetXDGDirectory(env, "XDG_DATA_HOME", ".local/share"); }
diff --git a/chrome/browser/shell_integration_linux.h b/chrome/browser/shell_integration_linux.h index e58ee09..ceb0752 100644 --- a/chrome/browser/shell_integration_linux.h +++ b/chrome/browser/shell_integration_linux.h
@@ -118,6 +118,12 @@ // them as a separate application. std::string GetWMClassFromAppName(std::string app_name); +// Wayland version of GetWMClassFromAppName explained above. +// The XDG application ID must match the name of the desktop entry file, where +// the latter looks like 'chrome-<web app id>-<profile name>.desktop'. +std::string GetXdgAppIdForWebApp(std::string app_name, + const base::FilePath& profile_path); + // Helper to launch xdg scripts. We don't want them to ask any questions on the // terminal etc. The function returns true if the utility launches and exits // cleanly, in which case |exit_code| returns the utility's exit code.
diff --git a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc index ecd8893..9a596217 100644 --- a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc +++ b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc
@@ -165,7 +165,7 @@ GURL url_to_open = GURL(chrome::kChromeUINewTabURL); // If the intercepted web contents is still alive, close it now. if (web_contents_) { - url_to_open = web_contents_->GetURL(); + url_to_open = web_contents_->GetLastCommittedURL(); web_contents_->Close(); }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc index 5a53ea9..45ec0382 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -369,8 +369,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 2u); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::kInterceptMultiUser); @@ -449,8 +450,9 @@ ASSERT_TRUE(added_browser); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch); @@ -528,8 +530,9 @@ EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); EXPECT_EQ(other_browser->tab_strip_model()->count(), other_original_tab_count + 1); - EXPECT_EQ(other_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + other_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch); @@ -589,8 +592,9 @@ ASSERT_TRUE(added_browser); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - GURL("chrome://newtab/")); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + GURL("chrome://newtab/")); } class DiceWebSigninInterceptorEnterpriseBrowserTest @@ -703,8 +707,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 2u); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::kInterceptEnterprise); @@ -799,8 +804,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 2u); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms( histogram_tester, @@ -878,8 +884,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 2u); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms( histogram_tester, @@ -952,8 +959,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 1u); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count); - EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms( histogram_tester, @@ -1019,8 +1027,9 @@ ASSERT_EQ(BrowserList::GetInstance()->size(), 1u); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count); - EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::kAbortAccountNotNew, @@ -1095,8 +1104,9 @@ ASSERT_TRUE(added_browser); EXPECT_EQ(added_browser->profile(), new_profile); EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); - EXPECT_EQ(added_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + added_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome:: @@ -1187,8 +1197,9 @@ EXPECT_EQ(browser()->tab_strip_model()->count(), original_tab_count - 1); EXPECT_EQ(other_browser->tab_strip_model()->count(), other_original_tab_count + 1); - EXPECT_EQ(other_browser->tab_strip_model()->GetActiveWebContents()->GetURL(), - intercepted_url); + EXPECT_EQ( + other_browser->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + intercepted_url); CheckHistograms(histogram_tester, SigninInterceptionHeuristicOutcome::
diff --git a/chrome/browser/ssl/connection_help_tab_helper.cc b/chrome/browser/ssl/connection_help_tab_helper.cc index 0ee80e3d..20c4ed17 100644 --- a/chrome/browser/ssl/connection_help_tab_helper.cc +++ b/chrome/browser/ssl/connection_help_tab_helper.cc
@@ -20,7 +20,7 @@ void RedirectToBundledHelp(content::WebContents* web_contents) { GURL::Replacements replacements; - std::string error_code = web_contents->GetURL().ref(); + std::string error_code = web_contents->GetLastCommittedURL().ref(); replacements.SetRefStr(error_code); web_contents->GetController().LoadURL( GURL(kBundledConnectionHelpUrl).ReplaceComponents(replacements), @@ -35,8 +35,10 @@ content::NavigationHandle* navigation_handle) { // Ignore pre-rendering navigations. if (navigation_handle->IsInPrimaryMainFrame() && - (web_contents()->GetURL().EqualsIgnoringRef(GetHelpCenterURL()) || - web_contents()->GetURL().EqualsIgnoringRef(GURL(kSymantecSupportUrl))) && + (web_contents()->GetLastCommittedURL().EqualsIgnoringRef( + GetHelpCenterURL()) || + web_contents()->GetLastCommittedURL().EqualsIgnoringRef( + GURL(kSymantecSupportUrl))) && navigation_handle->IsErrorPage() && net::IsCertificateError(navigation_handle->GetNetErrorCode())) { RedirectToBundledHelp(web_contents());
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index 912ac61..2b691f8 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -1573,7 +1573,7 @@ // The inner content of test.example.org_test.sxg has // "<script> document.title = document.location.href; </script>". EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); - ASSERT_EQ(inner_url, contents->GetURL()); + ASSERT_EQ(inner_url, contents->GetLastCommittedURL()); CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), @@ -1618,7 +1618,7 @@ // The inner content of test.example.org_test.sxg has // "<script> document.title = document.location.href; </script>". EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); - ASSERT_EQ(inner_url, contents->GetURL()); + ASSERT_EQ(inner_url, contents->GetLastCommittedURL()); } CheckSecurityInfoForSecure(
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index b117c4a..9bafc48f 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -4363,7 +4363,7 @@ EXPECT_EQ(2, browser()->tab_strip_model()->count()); WebContents* new_tab = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(new_tab); - EXPECT_EQ(mock_help_center_url.host(), new_tab->GetURL().host()); + EXPECT_EQ(mock_help_center_url.host(), new_tab->GetLastCommittedURL().host()); } // Verifies that switching tabs, while showing interstitial page, will not
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc index 64da37b7..68a0922c 100644 --- a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc +++ b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc
@@ -122,9 +122,10 @@ EXPECT_THAT( fixture.changed_prefs()->FindBoolPath(prefs::kForceGoogleSafeSearch), Optional(true)); - int force_youtube_restrict = safe_search_util::YOUTUBE_RESTRICT_OFF; - EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict, - &force_youtube_restrict)); + int force_youtube_restrict = + fixture.changed_prefs() + ->FindIntPath(prefs::kForceYouTubeRestrict) + .value_or(safe_search_util::YOUTUBE_RESTRICT_OFF); EXPECT_EQ(force_youtube_restrict, safe_search_util::YOUTUBE_RESTRICT_MODERATE); @@ -160,8 +161,11 @@ EXPECT_THAT( fixture.changed_prefs()->FindBoolPath(prefs::kForceGoogleSafeSearch), Optional(false)); - EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict, - &force_youtube_restrict)); + + force_youtube_restrict = + fixture.changed_prefs() + ->FindIntPath(prefs::kForceYouTubeRestrict) + .value_or(safe_search_util::YOUTUBE_RESTRICT_MODERATE); EXPECT_EQ(force_youtube_restrict, safe_search_util::YOUTUBE_RESTRICT_OFF); #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index 9453b77..fda171ab 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -792,8 +792,8 @@ // management; in particular we don't want to override the force-install list. if (extensions::Manifest::IsComponentLocation(extension.location()) || extensions::Manifest::IsPolicyLocation(extension.location()) || - extension.is_theme() || extension.from_bookmark() || - extension.is_shared_module() || was_installed_by_default) { + extension.is_theme() || extension.is_shared_module() || + was_installed_by_default) { return ExtensionState::ALLOWED; }
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn index 8900107..619931c 100644 --- a/chrome/browser/tab/BUILD.gn +++ b/chrome/browser/tab/BUILD.gn
@@ -24,6 +24,7 @@ "java/src/org/chromium/chrome/browser/tab/TabObserver.java", "java/src/org/chromium/chrome/browser/tab/TabResolver.java", "java/src/org/chromium/chrome/browser/tab/TabState.java", + "java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java", "java/src/org/chromium/chrome/browser/tab/TabViewManager.java", "java/src/org/chromium/chrome/browser/tab/TabViewProvider.java", "java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java",
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java index 188f6605..d9cdc11 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -273,14 +273,6 @@ void goForward(); /** - * Set whether the TabState representing this Tab has been updated. - * This method will ultimately be deprecated when the migration - * to CriticalPersistedTabData is complete. - * @param isDirty Whether the Tab's state has changed. - */ - void setIsTabStateDirty(boolean isTabStateDirty); - - /** * Set whether {@link Tab} metadata (specifically all {@link PersistedTabData}) * will be saved. Not all Tabs need to be persisted across restarts. * The default value when a Tab is initialized is false.
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java new file mode 100644 index 0000000..098c9e7 --- /dev/null +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java
@@ -0,0 +1,45 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.tab; + +import org.chromium.base.UserData; +import org.chromium.base.UserDataHost; + +/** + * Attributes related to {@link TabState} + */ +public class TabStateAttributes implements UserData { + private static final Class<TabStateAttributes> USER_DATA_KEY = TabStateAttributes.class; + /** Whether or not the TabState has changed. */ + private boolean mIsTabStateDirty = true; + + /** + * @return {@link TabStateAttributes} for a {@link Tab} + */ + public static TabStateAttributes from(Tab tab) { + UserDataHost host = tab.getUserDataHost(); + TabStateAttributes attrs = host.getUserData(USER_DATA_KEY); + return attrs != null ? attrs : host.setUserData(USER_DATA_KEY, new TabStateAttributes()); + } + + private TabStateAttributes() {} + + /** + * @return true if the {@link TabState} has been changed + */ + public boolean isTabStateDirty() { + return mIsTabStateDirty; + } + + /** + * Set whether the TabState representing this Tab has been updated. + * This method will ultimately be deprecated when the migration + * to CriticalPersistedTabData is complete. + * @param isTabStateDirty whether the Tab's state has changed. + */ + public void setIsTabStateDirty(boolean isTabStateDirty) { + mIsTabStateDirty = isTabStateDirty; + } +}
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java index c24c0f1..ef8a8acb 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
@@ -20,6 +20,7 @@ import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tab.TabUserAgent; import org.chromium.chrome.browser.tab.WebContentsState; import org.chromium.chrome.browser.tab.WebContentsStateBridge; @@ -564,13 +565,13 @@ * Set root id */ public void setRootId(int rootId) { - if (mRootId == rootId) return; + if (mRootId == rootId || mTab.isDestroyed()) return; // TODO(crbug.com/1059640) add in setters for all mutable fields mRootId = rootId; for (CriticalPersistedTabDataObserver observer : mObservers) { observer.onRootIdChanged(mTab, rootId); } - mTab.setIsTabStateDirty(true); + TabStateAttributes.from(mTab).setIsTabStateDirty(true); save(); }
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java index 2e15550..e98ea2b 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
@@ -89,7 +89,7 @@ } @Override - public void setIndex(int i, @TabSelectionType int type) {} + public void setIndex(int i, @TabSelectionType int type, boolean skipLoadingTab) {} @Override public boolean isActiveModel() {
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java index 83ca67b..50c112f 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
@@ -186,8 +186,8 @@ } @Override - public void setIndex(int i, @TabSelectionType int type) { - mDelegateModel.setIndex(i, type); + public void setIndex(int i, @TabSelectionType int type, boolean skipLoadingTab) { + mDelegateModel.setIndex(i, type, skipLoadingTab); } @Override
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java index ba656852..b0134377 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
@@ -140,8 +140,9 @@ * Selects a tab by its index. * @param i The index of the tab to select. * @param type The type of selection. + * @param skipLoadingTab Whether to skip loading the Tab. */ - public void setIndex(int i, final @TabSelectionType int type); + public void setIndex(int i, final @TabSelectionType int type, boolean skipLoadingTab); /** * @return Whether this tab model is currently selected in the correspond
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java index b2cbc46..380d008 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java
@@ -150,9 +150,10 @@ * type to {@link TabModel#setIndex(int, TabSelectionType)}. * @param model The {@link TabModel} to act on. * @param index The index of the {@link Tab} to select. + * @param skipLoadingTab Whether to skip loading the Tab. */ - public static void setIndex(TabModel model, int index) { - model.setIndex(index, TabSelectionType.FROM_USER); + public static void setIndex(TabModel model, int index, boolean skipLoadingTab) { + model.setIndex(index, TabSelectionType.FROM_USER, skipLoadingTab); } /**
diff --git a/chrome/browser/translate/translate_model_service_browsertest.cc b/chrome/browser/translate/translate_model_service_browsertest.cc index 045a25a..82ec520 100644 --- a/chrome/browser/translate/translate_model_service_browsertest.cc +++ b/chrome/browser/translate/translate_model_service_browsertest.cc
@@ -331,8 +331,11 @@ "LanguageDetection.TFLiteModel.WasModelAvailableForDetection", true, 1); } -// Disabled on macOS+ASAN due to high failure rate: crbug.com/1199854. -#if (defined(OS_MAC) && defined(ADDRESS_SANITIZER)) || defined(OS_WIN) +// Disabled on macOS+ASAN, chromeOS+ASAN and windows due to high failure rate: +// crbug.com/1199854. +#if ((defined(OS_MAC) || defined(OS_CHROMEOS)) && \ + defined(ADDRESS_SANITIZER)) || \ + defined(OS_WIN) #define MAYBE_LanguageDetectionWithBackgroundTab \ DISABLED_LanguageDetectionWithBackgroundTab #else
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 58f3ee04..40b59a79 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -695,7 +695,10 @@ ] } if (is_chromeos) { - deps += [ "//chromeos/crosapi/cpp:cpp" ] + deps += [ + "//chromeos/constants", + "//chromeos/crosapi/cpp", + ] } if (!is_fuchsia) { @@ -1974,8 +1977,6 @@ "app_list/search/os_settings_provider.h", "app_list/search/ranking/answer_ranker.cc", "app_list/search/ranking/answer_ranker.h", - "app_list/search/ranking/burn_in_ranker.cc", - "app_list/search/ranking/burn_in_ranker.h", "app_list/search/ranking/category_item_ranker.cc", "app_list/search/ranking/category_item_ranker.h", "app_list/search/ranking/category_usage_ranker.cc", @@ -2189,22 +2190,6 @@ "ash/projector/projector_client_impl.h", "ash/projector/projector_soda_installation_controller.cc", "ash/projector/projector_soda_installation_controller.h", - "ash/quick_answers/quick_answers_access_token_fetcher.cc", - "ash/quick_answers/quick_answers_access_token_fetcher.h", - "ash/quick_answers/quick_answers_controller_impl.cc", - "ash/quick_answers/quick_answers_controller_impl.h", - "ash/quick_answers/quick_answers_state_controller.cc", - "ash/quick_answers/quick_answers_state_controller.h", - "ash/quick_answers/quick_answers_ui_controller.cc", - "ash/quick_answers/quick_answers_ui_controller.h", - "ash/quick_answers/ui/quick_answers_focus_search.cc", - "ash/quick_answers/ui/quick_answers_focus_search.h", - "ash/quick_answers/ui/quick_answers_pre_target_handler.cc", - "ash/quick_answers/ui/quick_answers_pre_target_handler.h", - "ash/quick_answers/ui/quick_answers_view.cc", - "ash/quick_answers/ui/quick_answers_view.h", - "ash/quick_answers/ui/user_consent_view.cc", - "ash/quick_answers/ui/user_consent_view.h", "ash/screen_orientation_delegate_chromeos.cc", "ash/screen_orientation_delegate_chromeos.h", "ash/screenshot_area.cc", @@ -2327,6 +2312,22 @@ "ash/window_properties.h", "browser_commands_chromeos.cc", "browser_commands_chromeos.h", + "quick_answers/quick_answers_access_token_fetcher.cc", + "quick_answers/quick_answers_access_token_fetcher.h", + "quick_answers/quick_answers_controller_impl.cc", + "quick_answers/quick_answers_controller_impl.h", + "quick_answers/quick_answers_state_controller.cc", + "quick_answers/quick_answers_state_controller.h", + "quick_answers/quick_answers_ui_controller.cc", + "quick_answers/quick_answers_ui_controller.h", + "quick_answers/ui/quick_answers_focus_search.cc", + "quick_answers/ui/quick_answers_focus_search.h", + "quick_answers/ui/quick_answers_pre_target_handler.cc", + "quick_answers/ui/quick_answers_pre_target_handler.h", + "quick_answers/ui/quick_answers_view.cc", + "quick_answers/ui/quick_answers_view.h", + "quick_answers/ui/user_consent_view.cc", + "quick_answers/ui/user_consent_view.h", "settings_window_manager_chromeos.cc", "settings_window_manager_chromeos.h", "settings_window_manager_observer_chromeos.h",
diff --git a/chrome/browser/ui/android/appmenu/internal/BUILD.gn b/chrome/browser/ui/android/appmenu/internal/BUILD.gn index 279c7cd..f741b3c 100644 --- a/chrome/browser/ui/android/appmenu/internal/BUILD.gn +++ b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
@@ -28,6 +28,7 @@ "//chrome/browser/android/lifecycle:java", "//chrome/browser/flags:java", "//chrome/browser/ui/android/appmenu:java", + "//components/browser_ui/styles/android:java", "//components/browser_ui/widget/android:java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", @@ -39,11 +40,13 @@ android_resources("java_resources") { sources = [ + "java/res/drawable-v24/menu_action_bar_bg.xml", "java/res/drawable/menu_action_bar_bg.xml", "java/res/layout/icon_row_menu_item.xml", "java/res/layout/menu_item.xml", "java/res/layout/menu_item_start_with_icon.xml", "java/res/layout/title_button_menu_item.xml", + "java/res/values-night/dimens.xml", "java/res/values/dimens.xml", ]
diff --git a/chrome/browser/ui/android/appmenu/internal/java/res/drawable-v24/menu_action_bar_bg.xml b/chrome/browser/ui/android/appmenu/internal/java/res/drawable-v24/menu_action_bar_bg.xml new file mode 100644 index 0000000..68b9e0fd --- /dev/null +++ b/chrome/browser/ui/android/appmenu/internal/java/res/drawable-v24/menu_action_bar_bg.xml
@@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<org.chromium.components.browser_ui.widget.SurfaceColorDrawable + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:shape="rectangle" + app:surfaceElevation="@dimen/menu_action_bar_bg_elev"> + <corners + android:radius="1dp" + android:topLeftRadius="@dimen/app_menu_corner_size" + android:topRightRadius="@dimen/app_menu_corner_size" + android:bottomLeftRadius="0dp" + android:bottomRightRadius="0dp" /> +</org.chromium.components.browser_ui.widget.SurfaceColorDrawable>
diff --git a/chrome/browser/ui/android/appmenu/internal/java/res/values-night/dimens.xml b/chrome/browser/ui/android/appmenu/internal/java/res/values-night/dimens.xml new file mode 100644 index 0000000..629942e5 --- /dev/null +++ b/chrome/browser/ui/android/appmenu/internal/java/res/values-night/dimens.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<resources> + + <!-- Menu action bar bg elevation --> + <dimen name="menu_action_bar_bg_elev">@dimen/default_elevation_6</dimen> +</resources>
diff --git a/chrome/browser/ui/android/appmenu/internal/java/res/values/dimens.xml b/chrome/browser/ui/android/appmenu/internal/java/res/values/dimens.xml index 562fce6..e562f9e 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/res/values/dimens.xml +++ b/chrome/browser/ui/android/appmenu/internal/java/res/values/dimens.xml
@@ -14,4 +14,7 @@ <!-- Menu chip dimensions --> <dimen name="menu_chip_highlight_extension">4dp</dimen> + + <!-- Menu action bar bg elevation --> + <dimen name="menu_action_bar_bg_elev">@dimen/default_elevation_1</dimen> </resources>
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java index 96ffb62..fd0c62f 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java
@@ -185,8 +185,7 @@ R.id.menu_item_enter_anim_id, AppMenuUtil.buildIconItemEnterAnimator(buttons)); // Tint action bar's background. - view.setBackgroundDrawable(ApiCompatibilityUtils.getDrawable( - view.getContext().getResources(), R.drawable.menu_action_bar_bg)); + view.setBackgroundResource(R.drawable.menu_action_bar_bg); view.setEnabled(false); }
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSource.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSource.java index 64b098d..5503aca 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSource.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSource.java
@@ -10,7 +10,6 @@ import org.chromium.chrome.browser.feedback.FeedbackSource; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.night_mode.WebContentsDarkModeController.AutoDarkModeEnabledState; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.url.GURL; @@ -26,19 +25,7 @@ /** Feature flag for auto dark is disabled. */ @VisibleForTesting - static final String DISABLED_FEATURE_VALUE = "DisabledFeatureGroup"; - - /** User settings for auto dark is disabled. */ - @VisibleForTesting - static final String DISABLED_GLOBAL_SETTINGS_VALUE = "DisabledGlobalSettings"; - - /** Whether the current URL has auto dark enabled. */ - @VisibleForTesting - static final String DISABLED_URL_SETTINGS_VALUE = "DisabledUrlSettings"; - - /** Settings is enabled, theme is in light */ - @VisibleForTesting - static final String DISABLED_BY_LIGHT_MODE_VALUE = "DisabledByLightMode"; + static final String DISABLED_VALUE = "Disabled"; private final HashMap<String, String> mMap; @@ -50,26 +37,11 @@ if (!ChromeFeatureList.isEnabled( ChromeFeatureList.DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING)) { - mMap.put(AUTO_DARK_FEEDBACK_KEY, DISABLED_FEATURE_VALUE); + mMap.put(AUTO_DARK_FEEDBACK_KEY, DISABLED_VALUE); } else { - @AutoDarkModeEnabledState - int enabledState = WebContentsDarkModeController.getEnabledState(profile, context, url); - mMap.put(AUTO_DARK_FEEDBACK_KEY, toFeedbackValue(enabledState)); - } - } - - private String toFeedbackValue(@AutoDarkModeEnabledState int enabledState) { - switch (enabledState) { - case AutoDarkModeEnabledState.ENABLED: - return ENABLED_VALUE; - case AutoDarkModeEnabledState.DISABLED_GLOBAL_SETTINGS: - return DISABLED_GLOBAL_SETTINGS_VALUE; - case AutoDarkModeEnabledState.DISABLED_URL_SETTINGS: - return DISABLED_URL_SETTINGS_VALUE; - case AutoDarkModeEnabledState.DISABLED_LIGHT_MODE: - return DISABLED_BY_LIGHT_MODE_VALUE; - default: - throw new RuntimeException("Invalid enabled state."); + boolean enabledState = + WebContentsDarkModeController.getEnabledState(profile, context, url); + mMap.put(AUTO_DARK_FEEDBACK_KEY, enabledState ? ENABLED_VALUE : DISABLED_VALUE); } }
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSourceUnitTest.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSourceUnitTest.java index 1943944..7950109 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSourceUnitTest.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSourceUnitTest.java
@@ -24,7 +24,6 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.night_mode.AutoDarkFeedbackSourceUnitTest.ShadowWebContentsDarkModeController; -import org.chromium.chrome.browser.night_mode.WebContentsDarkModeController.AutoDarkModeEnabledState; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.BrowserContextHandle; @@ -37,10 +36,10 @@ public class AutoDarkFeedbackSourceUnitTest { @Implements(WebContentsDarkModeController.class) static class ShadowWebContentsDarkModeController { - static @AutoDarkModeEnabledState int sEnabledState; + static boolean sEnabledState; @Implementation - public static @AutoDarkModeEnabledState int getEnabledState( + public static boolean getEnabledState( BrowserContextHandle browserContextHandle, Context context, GURL url) { return sEnabledState; } @@ -58,12 +57,12 @@ @Before public void setup() { - ShadowWebContentsDarkModeController.sEnabledState = AutoDarkModeEnabledState.INVALID; + ShadowWebContentsDarkModeController.sEnabledState = false; } @After public void tearDown() { - ShadowWebContentsDarkModeController.sEnabledState = -1; + ShadowWebContentsDarkModeController.sEnabledState = false; } @Test @@ -75,34 +74,20 @@ @Test @Features.DisableFeatures(ChromeFeatureList.DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING) public void testDisabled_FeatureNotEnabled() { - doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_FEATURE_VALUE); + ShadowWebContentsDarkModeController.sEnabledState = true; + doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_VALUE); } @Test public void testAutoDarkEnabledState_Enabled() { - ShadowWebContentsDarkModeController.sEnabledState = AutoDarkModeEnabledState.ENABLED; + ShadowWebContentsDarkModeController.sEnabledState = true; doTestFeedbackSource(AutoDarkFeedbackSource.ENABLED_VALUE); } @Test public void testAutoDarkEnabledState_DisabledGlobalSettings() { - ShadowWebContentsDarkModeController.sEnabledState = - AutoDarkModeEnabledState.DISABLED_GLOBAL_SETTINGS; - doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_GLOBAL_SETTINGS_VALUE); - } - - @Test - public void testAutoDarkEnabledState_DisabledLightMode() { - ShadowWebContentsDarkModeController.sEnabledState = - AutoDarkModeEnabledState.DISABLED_LIGHT_MODE; - doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_BY_LIGHT_MODE_VALUE); - } - - @Test - public void testAutoDarkEnabledState_DisabledUrlSettings() { - ShadowWebContentsDarkModeController.sEnabledState = - AutoDarkModeEnabledState.DISABLED_URL_SETTINGS; - doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_URL_SETTINGS_VALUE); + ShadowWebContentsDarkModeController.sEnabledState = false; + doTestFeedbackSource(AutoDarkFeedbackSource.DISABLED_VALUE); } private void doTestFeedbackSource(String expectedPsdValue) {
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java index 0f5fd64..c2a0c28 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
@@ -6,8 +6,6 @@ import android.content.Context; -import androidx.annotation.IntDef; - import org.chromium.components.browser_ui.site_settings.AutoDarkMetrics; import org.chromium.components.browser_ui.site_settings.AutoDarkMetrics.AutoDarkSettingsChangeSource; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; @@ -19,32 +17,12 @@ import org.chromium.ui.util.ColorUtils; import org.chromium.url.GURL; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * A controller class could enable or disable web content dark mode feature based on the content * settings {@link ContentSettingsType.AUTO_DARK_WEB_CONTENT}. */ public class WebContentsDarkModeController { /** - * Enum class that explained the enabled state for auto dark mode. See {@link #getEnabledState} - */ - @IntDef({AutoDarkModeEnabledState.INVALID, AutoDarkModeEnabledState.ENABLED, - AutoDarkModeEnabledState.DISABLED_GLOBAL_SETTINGS, - AutoDarkModeEnabledState.DISABLED_LIGHT_MODE, - AutoDarkModeEnabledState.DISABLED_URL_SETTINGS}) - @Retention(RetentionPolicy.SOURCE) - public @interface AutoDarkModeEnabledState { - // INVALID state used as test placeholder. - int INVALID = -1; - int ENABLED = 0; - int DISABLED_GLOBAL_SETTINGS = 1; - int DISABLED_LIGHT_MODE = 2; - int DISABLED_URL_SETTINGS = 3; - } - - /** * Return whether auto dark mode is enable for a given URL. * @param browserContextHandle Current browser context handle. * @param url Queried URL to check whether auto dark is enabled. @@ -137,19 +115,19 @@ * @param browserContextHandle Current browser context handle. * @param context {@link Context} used to check whether UI is in night mode. * @param url Queried URL whether auto dark is enabled. - * @return The current enabled state in {@link AutoDarkModeEnabledState}. + * @return Whether auto dark is enabled for the given input. */ - public static @AutoDarkModeEnabledState int getEnabledState( + public static boolean getEnabledState( BrowserContextHandle browserContextHandle, Context context, GURL url) { if (!isGlobalUserSettingsEnabled(browserContextHandle)) { - return AutoDarkModeEnabledState.DISABLED_GLOBAL_SETTINGS; + return false; } if (!ColorUtils.inNightMode(context)) { - return AutoDarkModeEnabledState.DISABLED_LIGHT_MODE; + return false; } if (!url.isEmpty() && !isEnabledForUrl(browserContextHandle, url)) { - return AutoDarkModeEnabledState.DISABLED_URL_SETTINGS; + return false; } - return AutoDarkModeEnabledState.ENABLED; + return true; } }
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java index 473b72e..cbdbc84 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java
@@ -26,7 +26,6 @@ import org.chromium.base.metrics.test.ShadowRecordHistogram; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.browser.night_mode.WebContentsDarkModeController.AutoDarkModeEnabledState; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.browser_ui.site_settings.AutoDarkMetrics.AutoDarkSettingsChangeSource; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; @@ -105,7 +104,7 @@ Assert.assertTrue( "Feature should be enabled, if both global settings and night mode enabled.", WebContentsDarkModeController.isFeatureEnabled(mMockContext, mMockProfile)); - assertEnabledState(GURL.emptyGURL(), AutoDarkModeEnabledState.ENABLED); + assertEnabledState(GURL.emptyGURL(), true); } @Test @@ -114,7 +113,7 @@ mIsGlobalSettingsEnabled = true; Assert.assertFalse("Feature should be disabled when not in night mode.", WebContentsDarkModeController.isFeatureEnabled(mMockContext, mMockProfile)); - assertEnabledState(GURL.emptyGURL(), AutoDarkModeEnabledState.DISABLED_LIGHT_MODE); + assertEnabledState(GURL.emptyGURL(), false); } @Test @@ -123,7 +122,7 @@ mIsGlobalSettingsEnabled = false; Assert.assertFalse("Feature should be disabled when global settings disabled.", WebContentsDarkModeController.isFeatureEnabled(mMockContext, mMockProfile)); - assertEnabledState(GURL.emptyGURL(), AutoDarkModeEnabledState.DISABLED_GLOBAL_SETTINGS); + assertEnabledState(GURL.emptyGURL(), false); } private void doTestSetAutoDarkGlobalSettingsEnabled(boolean enabled) { @@ -175,7 +174,7 @@ ShadowColorUtils.sInNightMode = true; mIsGlobalSettingsEnabled = true; mIsAutoDarkEnabledForUrlContentSettingValue = ContentSettingValues.ALLOW; - assertEnabledState(mMockGurl, AutoDarkModeEnabledState.ENABLED); + assertEnabledState(mMockGurl, true); } @Test @@ -183,7 +182,7 @@ ShadowColorUtils.sInNightMode = true; mIsGlobalSettingsEnabled = true; mIsAutoDarkEnabledForUrlContentSettingValue = ContentSettingValues.BLOCK; - assertEnabledState(mMockGurl, AutoDarkModeEnabledState.DISABLED_URL_SETTINGS); + assertEnabledState(mMockGurl, false); } private void assertAutoDarkModeChangeSourceRecorded( @@ -196,8 +195,8 @@ expectedCounts, actualCount); } - private void assertEnabledState(GURL url, @AutoDarkModeEnabledState int expectedEnabledState) { - int actualEnabledState = + private void assertEnabledState(GURL url, boolean expectedEnabledState) { + boolean actualEnabledState = WebContentsDarkModeController.getEnabledState(mMockProfile, mMockContext, url); Assert.assertEquals("AutoDarkModeEnabledState does not match.", expectedEnabledState, actualEnabledState);
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/colors.xml b/chrome/browser/ui/android/omnibox/java/res/values/colors.xml index 68a72c6e..a867761 100644 --- a/chrome/browser/ui/android/omnibox/java/res/values/colors.xml +++ b/chrome/browser/ui/android/omnibox/java/res/values/colors.xml
@@ -15,10 +15,18 @@ <!-- LocationBar colors --> <color name="locationbar_dark_hint_text">@color/search_box_hint</color> <color name="locationbar_light_hint_text">@color/default_text_color_secondary_light</color> - <color name="locationbar_status_offline_color">@color/modern_grey_900</color> + + <color name="locationbar_status_offline_color_dark">@color/default_text_color_secondary_dark</color> <color name="locationbar_status_offline_color_light">@android:color/white</color> - <color name="locationbar_status_preview_color">@color/modern_blue_600</color> - <color name="locationbar_status_preview_color_light">@color/modern_blue_300</color> + <color name="locationbar_status_offline_color_incognito">@color/default_text_color_secondary_light</color> + + <color name="locationbar_status_preview_color_dark">@color/default_text_color_secondary_dark</color> + <color name="locationbar_status_preview_color_light">@android:color/white</color> + <color name="locationbar_status_preview_color_incognito">@color/modern_blue_300</color> + + <color name="locationbar_status_separator_color_dark">@color/baseline_neutral_variant_500</color> + <color name="locationbar_status_separator_color_light">@color/white_alpha_60</color> + <color name="locationbar_status_separator_color_incognito">@color/baseline_neutral_variant_400</color> <color name="omnibox_focused_fading_background_color">@color/black_alpha_65</color> <color name="omnibox_focused_fading_background_color_light">@color/white_alpha_65</color>
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java index 609ecb5..48806cf 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -55,6 +55,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; @@ -72,7 +73,6 @@ import org.chromium.ui.base.PageTransition; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.interpolators.BakedBezierInterpolator; -import org.chromium.ui.util.ColorUtils; import java.util.ArrayList; import java.util.List; @@ -928,22 +928,18 @@ */ @VisibleForTesting /* package */ void updateBrandedColorScheme() { - // TODO(crbug.com/1114183): Unify light and dark color logic in chrome and make it clear - // whether the foreground or background color is dark. - final boolean useDarkForegroundColors = - !ColorUtils.shouldUseLightForegroundOnBackground(getPrimaryBackgroundColor()); final @BrandedColorScheme int brandedColorScheme = OmniboxResourceProvider.getBrandedColorScheme(mContext, mLocationBarDataProvider.isIncognito(), getPrimaryBackgroundColor()); mLocationBarLayout.setDeleteButtonTint( - ChromeColors.getPrimaryIconTint(mContext, !useDarkForegroundColors)); + ThemeUtils.getThemedToolbarIconTint(mContext, brandedColorScheme)); // If the URL changed colors and is not focused, update the URL to account for the new // color scheme. if (mUrlCoordinator.setBrandedColorScheme(brandedColorScheme) && !isUrlBarFocused()) { updateUrl(); } - mStatusCoordinator.setUseDarkForegroundColors(useDarkForegroundColors); + mStatusCoordinator.setBrandedColorScheme(brandedColorScheme); if (mAutocompleteCoordinator != null) { mAutocompleteCoordinator.updateVisualsForState(brandedColorScheme); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java index 4635ff0..0748d771 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java
@@ -666,7 +666,7 @@ mMediator.updateBrandedColorScheme(); verify(mLocationBarLayout).setDeleteButtonTint(any(ColorStateList.class)); - verify(mStatusCoordinator).setUseDarkForegroundColors(true); + verify(mStatusCoordinator).setBrandedColorScheme(BrandedColorScheme.LIGHT_BRANDED_THEME); verify(mAutocompleteCoordinator) .updateVisualsForState(BrandedColorScheme.LIGHT_BRANDED_THEME); } @@ -679,7 +679,7 @@ mMediator.updateBrandedColorScheme(); verify(mLocationBarLayout).setDeleteButtonTint(any(ColorStateList.class)); - verify(mStatusCoordinator).setUseDarkForegroundColors(false); + verify(mStatusCoordinator).setBrandedColorScheme(BrandedColorScheme.DARK_BRANDED_THEME); verify(mAutocompleteCoordinator) .updateVisualsForState(BrandedColorScheme.DARK_BRANDED_THEME); } @@ -693,7 +693,7 @@ mMediator.updateBrandedColorScheme(); verify(mLocationBarLayout).setDeleteButtonTint(any(ColorStateList.class)); - verify(mStatusCoordinator).setUseDarkForegroundColors(false); + verify(mStatusCoordinator).setBrandedColorScheme(BrandedColorScheme.INCOGNITO); verify(mAutocompleteCoordinator).updateVisualsForState(BrandedColorScheme.INCOGNITO); } @@ -706,7 +706,7 @@ mMediator.updateBrandedColorScheme(); verify(mLocationBarLayout).setDeleteButtonTint(any(ColorStateList.class)); - verify(mStatusCoordinator).setUseDarkForegroundColors(true); + verify(mStatusCoordinator).setBrandedColorScheme(BrandedColorScheme.APP_DEFAULT); verify(mAutocompleteCoordinator).updateVisualsForState(BrandedColorScheme.APP_DEFAULT); } @@ -723,7 +723,7 @@ verify(mUrlCoordinator) .setUrlBarData( urlBarData, UrlBar.ScrollType.SCROLL_TO_TLD, SelectionState.SELECT_ALL); - verify(mStatusCoordinator).setUseDarkForegroundColors(false); + verify(mStatusCoordinator).setBrandedColorScheme(BrandedColorScheme.DARK_BRANDED_THEME); verify(mAutocompleteCoordinator) .updateVisualsForState(BrandedColorScheme.DARK_BRANDED_THEME); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java index b7c95de..5dc42d1 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.ui.favicon.FaviconHelper; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.widget.RoundedIconGenerator; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.search_engines.TemplateUrlService; @@ -145,14 +146,15 @@ * circumstances, such as: no logo url found, network/cache error, etc. * * @param resources Provides access to Android resources. - * @param inNightMode Whether the device is currently in night mode, used to tint icons. + * @param brandedColorScheme The {@link BrandedColorScheme}, used to tint icons. * @param profile The current profile. When null, falls back to locally-provided icons. * @param templateUrlService The current templateUrlService. When null, falls back to * locally-provided icons. * @param callback How the bitmap will be returned to the caller. */ - public void getSearchEngineLogo(@NonNull Resources resources, boolean inNightMode, - @Nullable Profile profile, @Nullable TemplateUrlService templateUrlService, + public void getSearchEngineLogo(@NonNull Resources resources, + @BrandedColorScheme int brandedColorScheme, @Nullable Profile profile, + @Nullable TemplateUrlService templateUrlService, @NonNull Callback<StatusIconResource> callback) { // In the following cases, we fallback to the search loupe: // - Either of the nullable dependencies are null. @@ -162,7 +164,7 @@ // then we serve the Google icon we have locally. // Otherwise, the search engine is non-Google and we go to the network to fetch it. if (profile == null || templateUrlService == null || needToCheckForSearchEnginePromo()) { - callback.onResult(getSearchLoupeResource(inNightMode)); + callback.onResult(getSearchLoupeResource(brandedColorScheme)); return; } else if (templateUrlService.isDefaultSearchEngineGoogle()) { callback.onResult(new StatusIconResource(R.drawable.ic_logo_googleg_20dp, 0)); @@ -176,7 +178,7 @@ String logoUrl = getSearchLogoUrl(templateUrlService); if (logoUrl == null) { - callback.onResult(getSearchLoupeResource(inNightMode)); + callback.onResult(getSearchLoupeResource(brandedColorScheme)); recordEvent(Events.FETCH_FAILED_NULL_URL); return; } @@ -192,7 +194,7 @@ boolean willCallbackBeCalled = mFaviconHelper.getLocalFaviconImageForURL( profile, logoUrl, logoSizePixels, (image, iconUrl) -> { if (image == null) { - callback.onResult(getSearchLoupeResource(inNightMode)); + callback.onResult(getSearchLoupeResource(brandedColorScheme)); recordEvent(Events.FETCH_FAILED_RETURNED_BITMAP_NULL); return; } @@ -201,16 +203,15 @@ recordEvent(Events.FETCH_SUCCESS); }); if (!willCallbackBeCalled) { - callback.onResult(getSearchLoupeResource(inNightMode)); + callback.onResult(getSearchLoupeResource(brandedColorScheme)); recordEvent(Events.FETCH_FAILED_FAVICON_HELPER_ERROR); } } @VisibleForTesting - StatusIconResource getSearchLoupeResource(boolean inNightMode) { - return new StatusIconResource(R.drawable.ic_search, - inNightMode ? R.color.default_icon_color_secondary_tint_list - : ThemeUtils.getThemedToolbarIconTintRes(/* useLight= */ true)); + StatusIconResource getSearchLoupeResource(@BrandedColorScheme int brandedColorScheme) { + return new StatusIconResource( + R.drawable.ic_search, ThemeUtils.getThemedToolbarIconTintRes(brandedColorScheme)); } /** Returns whether the search engine promo is complete. */
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtilsUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtilsUnitTest.java index 21d28d3..719b406 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtilsUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtilsUnitTest.java
@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.ui.favicon.FaviconHelper; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.widget.RoundedIconGenerator; import org.chromium.components.search_engines.TemplateUrlService; @@ -135,7 +136,7 @@ StatusIconResource expected = new StatusIconResource(LOGO_URL, mBitmap, 0); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mFaviconHelper) .getLocalFaviconImageForURL( @@ -155,12 +156,12 @@ @Test public void getSearchEngineLogo_nullProfileOrTemplateUrlService() { StatusIconResource expected = - mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ false); + mSearchEngineLogoUtils.getSearchLoupeResource(BrandedColorScheme.APP_DEFAULT); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, null, mTemplateUrlService, mCallback); + BrandedColorScheme.APP_DEFAULT, null, mTemplateUrlService, mCallback); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), null, mCallback); + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), null, mCallback); verify(mCallback, times(2)).onResult(expected); } @@ -171,7 +172,7 @@ doReturn(true).when(mTemplateUrlService).isDefaultSearchEngineGoogle(); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mCallback).onResult(expected); } @@ -181,7 +182,7 @@ StatusIconResource expected = new StatusIconResource(LOGO_URL, mBitmap, 0); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mFaviconHelper) .getLocalFaviconImageForURL( @@ -189,7 +190,7 @@ FaviconHelper.FaviconImageCallback faviconCallback = mCallbackCaptor.getValue(); faviconCallback.onFaviconAvailable(mBitmap, JUnitTestGURLs.getGURL(LOGO_URL)); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mCallback, times(2)).onResult(expected); @@ -207,11 +208,11 @@ @Test public void getSearchEngineLogo_nullUrl() { StatusIconResource expected = - mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ false); + mSearchEngineLogoUtils.getSearchLoupeResource(BrandedColorScheme.APP_DEFAULT); doReturn(null).when(mTemplateUrlService).getUrlForSearchQuery(any()); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mCallback).onResult(eq(expected)); @@ -226,14 +227,14 @@ @Test public void getSearchEngineLogo_faviconHelperError() { StatusIconResource expected = - mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ false); + mSearchEngineLogoUtils.getSearchLoupeResource(BrandedColorScheme.APP_DEFAULT); when(mFaviconHelper.getLocalFaviconImageForURL( any(), anyString(), anyInt(), mCallbackCaptor.capture())) .thenReturn(false); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mCallback).onResult(expected); @@ -248,10 +249,10 @@ @Test public void getSearchEngineLogo_returnedBitmapNull() { StatusIconResource expected = - mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ false); + mSearchEngineLogoUtils.getSearchLoupeResource(BrandedColorScheme.APP_DEFAULT); mSearchEngineLogoUtils.getSearchEngineLogo(Mockito.mock(Resources.class), - /* inNightMode= */ false, Mockito.mock(Profile.class), mTemplateUrlService, + BrandedColorScheme.APP_DEFAULT, Mockito.mock(Profile.class), mTemplateUrlService, mCallback); verify(mFaviconHelper) .getLocalFaviconImageForURL( @@ -271,14 +272,15 @@ @Test public void getSearchLoupeResource() { StatusIconResource expected = new StatusIconResource( - R.drawable.ic_search, R.color.default_icon_color_secondary_tint_list); - Assert.assertEquals( - expected, mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ true)); + R.drawable.ic_search, R.color.default_icon_color_white_tint_list); + Assert.assertEquals(expected, + mSearchEngineLogoUtils.getSearchLoupeResource( + BrandedColorScheme.DARK_BRANDED_THEME)); expected = new StatusIconResource( R.drawable.ic_search, ThemeUtils.getThemedToolbarIconTintRes(/* useLight */ true)); - Assert.assertEquals( - expected, mSearchEngineLogoUtils.getSearchLoupeResource(/* inNightMode= */ false)); + Assert.assertEquals(expected, + mSearchEngineLogoUtils.getSearchLoupeResource(BrandedColorScheme.INCOGNITO)); } @Test
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarData.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarData.java index ea249d8f..2b0a1b9 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarData.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarData.java
@@ -11,7 +11,9 @@ import androidx.annotation.Nullable; import org.chromium.base.CollectionUtil; +import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.components.embedder_support.util.UrlConstants; +import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.content_public.common.ContentUrlConstants; import java.util.HashSet; @@ -59,6 +61,11 @@ return forUrlAndText(url, displayText, null); } + /** Returns whether supplied URL should be shown in the Omnibox/Suggestions list. */ + public static boolean shouldShowUrl(String url, boolean isIncognito) { + return !(NativePage.isNativePageUrl(url, isIncognito) || UrlUtilities.isNTPUrl(url)); + } + public static UrlBarData forUrlAndText( String url, CharSequence displayText, @Nullable String editingText) { int pathSearchOffset = 0;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusCoordinator.java index 6e94f520..9d807ef 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusCoordinator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusCoordinator.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.browser.user_education.IPHCommandBuilder; import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.components.embedder_support.util.UrlConstants; @@ -170,11 +171,10 @@ } /** - * @param useDarkForegroundColors Whether dark foreground colors should be for the status icon - * and text. + * @param brandedColorScheme The {@link BrandedColorScheme} to use for the status icon and text. */ - public void setUseDarkForegroundColors(boolean useDarkForegroundColors) { - mMediator.setUseDarkColors(useDarkForegroundColors); + public void setBrandedColorScheme(@BrandedColorScheme int brandedColorScheme) { + mMediator.setBrandedColorScheme(brandedColorScheme); // TODO(ender): remove this once icon selection has complete set of // corresponding properties (for tinting etc).
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java index bc9800f..41d0234d 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
@@ -11,6 +11,7 @@ import android.text.TextUtils; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; @@ -29,9 +30,11 @@ import org.chromium.chrome.browser.omnibox.status.StatusProperties.PermissionIconResource; import org.chromium.chrome.browser.omnibox.status.StatusProperties.StatusIconResource; import org.chromium.chrome.browser.omnibox.status.StatusView.IconTransitionType; +import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider; import org.chromium.chrome.browser.page_info.ChromePageInfoHighlight; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.theme.ThemeUtils; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.site_settings.ContentSettingsResources; import org.chromium.components.browser_ui.site_settings.SiteSettingsUtil; import org.chromium.components.content_settings.ContentSettingValues; @@ -61,7 +64,6 @@ private final Supplier<Profile> mProfileSupplier; private final Supplier<MerchantTrustSignalsCoordinator> mMerchantTrustSignalsCoordinatorSupplier; - private boolean mDarkTheme; private boolean mUrlHasFocus; private boolean mVerboseStatusSpaceAvailable; private boolean mPageIsPaintPreview; @@ -78,10 +80,11 @@ private @ConnectionSecurityLevel int mPageSecurityLevel; + private @BrandedColorScheme int mBrandedColorScheme = BrandedColorScheme.APP_DEFAULT; private @DrawableRes int mSecurityIconRes; private @DrawableRes int mSecurityIconTintRes; private @StringRes int mSecurityIconDescriptionRes; - private @DrawableRes int mNavigationIconTintRes; + private @ColorRes int mNavigationIconTintRes; private Resources mResources; private Context mContext; @@ -148,9 +151,8 @@ templateUrlService.addObserver(this); updateLocationBarIcon(IconTransitionType.CROSSFADE); }); - mProfileSupplier = profileSupplier; - updateColorTheme(); + mProfileSupplier = profileSupplier; mResources = resources; mContext = context; mUrlBarEditingTextStateProvider = urlBarEditingTextStateProvider; @@ -170,6 +172,7 @@ mPermissionDialogController = permissionDialogController; mPermissionDialogController.addObserver(this); + updateColorTheme(); setStatusIconShown(/* show= */ !mLocationBarDataProvider.isIncognito()); updateLocationBarIcon(IconTransitionType.CROSSFADE); } @@ -389,11 +392,11 @@ } /** - * Toggle between dark and light UI color theme. + * Set the {@link BrandedColorScheme}. */ - void setUseDarkColors(boolean useDarkColors) { - if (mDarkTheme != useDarkColors) { - mDarkTheme = useDarkColors; + void setBrandedColorScheme(@BrandedColorScheme int brandedColorScheme) { + if (mBrandedColorScheme != brandedColorScheme) { + mBrandedColorScheme = brandedColorScheme; updateColorTheme(); } } @@ -435,30 +438,29 @@ * Update color theme for all status components. */ private void updateColorTheme() { - @ColorRes - int separatorColor = mDarkTheme ? R.color.divider_line_bg_color_dark - : R.color.divider_line_bg_color_light; + final @ColorInt int separatorColor = + OmniboxResourceProvider.getStatusSeparatorColor(mContext, mBrandedColorScheme); + mModel.set(StatusProperties.SEPARATOR_COLOR, separatorColor); + mNavigationIconTintRes = ThemeUtils.getThemedToolbarIconTintRes(mBrandedColorScheme); - @ColorRes - int textColor = 0; - if (mPageIsPaintPreview) { - textColor = mDarkTheme ? R.color.locationbar_status_preview_color - : R.color.locationbar_status_preview_color_light; - } else if (mPageIsOffline) { - textColor = mDarkTheme ? R.color.locationbar_status_offline_color - : R.color.locationbar_status_offline_color_light; + final @ColorInt int textColor = getTextColor(); + if (textColor != 0) { + mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_COLOR, textColor); } - @ColorRes - int tintColor = ThemeUtils.getThemedToolbarIconTintRes(!mDarkTheme); - - mModel.set(StatusProperties.SEPARATOR_COLOR_RES, separatorColor); - mNavigationIconTintRes = tintColor; - if (textColor != 0) mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES, textColor); - updateLocationBarIcon(IconTransitionType.CROSSFADE); } + private @ColorInt int getTextColor() { + if (mPageIsPaintPreview) { + return OmniboxResourceProvider.getStatusPreviewTextColor(mContext, mBrandedColorScheme); + } + if (mPageIsOffline) { + return OmniboxResourceProvider.getStatusOfflineTextColor(mContext, mBrandedColorScheme); + } + return 0; + } + /** * Reports whether security icon is shown. */ @@ -577,9 +579,9 @@ // If the current url text is a valid url, then swap the dse icon for a globe. if (!mUrlBarTextIsSearch) { resourceCallback.onResult(new StatusIconResource(R.drawable.ic_globe_24dp, - ThemeUtils.getThemedToolbarIconTintRes(/* useLight= */ !mDarkTheme))); + ThemeUtils.getThemedToolbarIconTintRes(mBrandedColorScheme))); } else { - mSearchEngineLogoUtils.getSearchEngineLogo(mResources, mDarkTheme, + mSearchEngineLogoUtils.getSearchEngineLogo(mResources, mBrandedColorScheme, mProfileSupplier.get(), mTemplateUrlServiceSupplier.get(), resourceCallback); } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java index 822327d..c0c22f8 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java
@@ -207,7 +207,7 @@ new WritableBooleanPropertyKey(); /** The status separator color. */ - static final WritableIntPropertyKey SEPARATOR_COLOR_RES = new WritableIntPropertyKey(); + static final WritableIntPropertyKey SEPARATOR_COLOR = new WritableIntPropertyKey(); /** Whether the icon is shown. */ static final WritableBooleanPropertyKey SHOW_STATUS_ICON = new WritableBooleanPropertyKey(); @@ -235,8 +235,7 @@ new WritableObjectPropertyKey<>(); /** Text color of the verbose status text field. */ - static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_COLOR_RES = - new WritableIntPropertyKey(); + static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_COLOR = new WritableIntPropertyKey(); /** The string resource used for the content of the verbose status text field. */ static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_STRING_RES = @@ -253,7 +252,7 @@ public static final PropertyKey[] ALL_KEYS = new PropertyKey[] { ANIMATIONS_ENABLED, INCOGNITO_BADGE_VISIBLE, - SEPARATOR_COLOR_RES, + SEPARATOR_COLOR, SHOW_STATUS_ICON, STATUS_CLICK_LISTENER, STATUS_ACCESSIBILITY_TOAST_RES, @@ -261,7 +260,7 @@ STATUS_ICON_ALPHA, STATUS_ICON_DESCRIPTION_RES, STATUS_ICON_RESOURCE, - VERBOSE_STATUS_TEXT_COLOR_RES, + VERBOSE_STATUS_TEXT_COLOR, VERBOSE_STATUS_TEXT_STRING_RES, VERBOSE_STATUS_TEXT_VISIBLE, VERBOSE_STATUS_TEXT_WIDTH,
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java index 527b217..e0a9822 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
@@ -12,7 +12,6 @@ import android.util.AttributeSet; import android.view.TouchDelegate; import android.view.View; -import android.view.View.AccessibilityDelegate; import android.view.ViewGroup; import android.view.ViewStub; import android.view.accessibility.AccessibilityNodeInfo; @@ -21,13 +20,12 @@ import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.ColorRes; +import androidx.annotation.ColorInt; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.browser.omnibox.LocationBarDataProvider; import org.chromium.chrome.browser.omnibox.R; import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils; @@ -357,17 +355,15 @@ /** * Select color of Separator view. */ - void setSeparatorColor(@ColorRes int separatorColor) { - mSeparatorView.setBackgroundColor( - ApiCompatibilityUtils.getColor(getResources(), separatorColor)); + void setSeparatorColor(@ColorInt int separatorColor) { + mSeparatorView.setBackgroundColor(separatorColor); } /** * Select color of verbose status text. */ - void setVerboseStatusTextColor(@ColorRes int textColor) { - mVerboseStatusTextView.setTextColor( - ApiCompatibilityUtils.getColor(getResources(), textColor)); + void setVerboseStatusTextColor(@ColorInt int textColor) { + mVerboseStatusTextView.setTextColor(textColor); } /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java index 5cc6c90..af4c7b4 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java
@@ -21,8 +21,8 @@ view.setAnimationsEnabled(model.get(StatusProperties.ANIMATIONS_ENABLED)); } else if (StatusProperties.INCOGNITO_BADGE_VISIBLE.equals(propertyKey)) { view.setIncognitoBadgeVisibility(model.get(StatusProperties.INCOGNITO_BADGE_VISIBLE)); - } else if (StatusProperties.SEPARATOR_COLOR_RES.equals(propertyKey)) { - view.setSeparatorColor(model.get(StatusProperties.SEPARATOR_COLOR_RES)); + } else if (StatusProperties.SEPARATOR_COLOR.equals(propertyKey)) { + view.setSeparatorColor(model.get(StatusProperties.SEPARATOR_COLOR)); } else if (StatusProperties.SHOW_STATUS_ICON.equals(propertyKey)) { view.setStatusIconShown(model.get(StatusProperties.SHOW_STATUS_ICON)); } else if (StatusProperties.STATUS_CLICK_LISTENER.equals(propertyKey)) { @@ -46,9 +46,8 @@ } view.setStatusIconResources(res.getDrawable(view.getContext(), view.getResources()), res.getTransitionType(), res.getAnimationFinishedCallback()); - } else if (StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES.equals(propertyKey)) { - view.setVerboseStatusTextColor( - model.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); + } else if (StatusProperties.VERBOSE_STATUS_TEXT_COLOR.equals(propertyKey)) { + view.setVerboseStatusTextColor(model.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR)); } else if (StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES.equals(propertyKey)) { view.setVerboseStatusTextContent( model.get(StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES));
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java index b3dbe9e..37000338 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java
@@ -225,6 +225,69 @@ } /** + * Returns the separator line color for the status view. + * + * @param context The context to retrieve the resources from. + * @param brandedColorScheme The {@link BrandedColorScheme}. + * @return Status view separator color. + */ + public static @ColorInt int getStatusSeparatorColor( + Context context, @BrandedColorScheme int brandedColorScheme) { + if (brandedColorScheme == BrandedColorScheme.LIGHT_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_separator_color_dark); + } + if (brandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_separator_color_light); + } + if (brandedColorScheme == BrandedColorScheme.INCOGNITO) { + return context.getColor(R.color.locationbar_status_separator_color_incognito); + } + return MaterialColors.getColor(context, R.attr.colorOutline, TAG); + } + + /** + * Returns the preview text color for the status view. + * + * @param context The context to retrieve the resources from. + * @param brandedColorScheme The {@link BrandedColorScheme}. + * @return Status view preview text color. + */ + public static @ColorInt int getStatusPreviewTextColor( + Context context, @BrandedColorScheme int brandedColorScheme) { + if (brandedColorScheme == BrandedColorScheme.LIGHT_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_preview_color_dark); + } + if (brandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_preview_color_light); + } + if (brandedColorScheme == BrandedColorScheme.INCOGNITO) { + return context.getColor(R.color.locationbar_status_preview_color_incognito); + } + return MaterialColors.getColor(context, R.attr.colorPrimary, TAG); + } + + /** + * Returns the offline text color for the status view. + * + * @param context The context to retrieve the resources from. + * @param brandedColorScheme The {@link BrandedColorScheme}. + * @return Status view offline text color. + */ + public static @ColorInt int getStatusOfflineTextColor( + Context context, @BrandedColorScheme int brandedColorScheme) { + if (brandedColorScheme == BrandedColorScheme.LIGHT_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_offline_color_dark); + } + if (brandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME) { + return context.getColor(R.color.locationbar_status_offline_color_light); + } + if (brandedColorScheme == BrandedColorScheme.INCOGNITO) { + return context.getColor(R.color.locationbar_status_offline_color_incognito); + } + return context.getColor(R.color.default_text_color_secondary_list); + } + + /** * Wraps the context if necessary to force dark resources for incognito. * * @param context The {@link Context} to be wrapped.
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProviderTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProviderTest.java index a11ce92..9dfa6cb2 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProviderTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProviderTest.java
@@ -235,4 +235,74 @@ OmniboxResourceProvider.getSuggestionUrlTextColor( mActivity, BrandedColorScheme.APP_DEFAULT)); } + + @Test + public void getStatusSeparatorColor() { + final Resources resources = mActivity.getResources(); + final int darkColor = resources.getColor(R.color.locationbar_status_separator_color_dark); + final int lightColor = resources.getColor(R.color.locationbar_status_separator_color_light); + final int incognitoColor = + resources.getColor(R.color.locationbar_status_separator_color_incognito); + final int defaultColor = MaterialColors.getColor(mActivity, R.attr.colorOutline, TAG); + + assertEquals("Wrong status separator color for LIGHT_THEME.", darkColor, + OmniboxResourceProvider.getStatusSeparatorColor( + mActivity, BrandedColorScheme.LIGHT_BRANDED_THEME)); + assertEquals("Wrong status separator color for DARK_THEME.", lightColor, + OmniboxResourceProvider.getStatusSeparatorColor( + mActivity, BrandedColorScheme.DARK_BRANDED_THEME)); + assertEquals("Wrong status separator color for INCOGNITO.", incognitoColor, + OmniboxResourceProvider.getStatusSeparatorColor( + mActivity, BrandedColorScheme.INCOGNITO)); + assertEquals("Wrong status separator color for DEFAULT.", defaultColor, + OmniboxResourceProvider.getStatusSeparatorColor( + mActivity, BrandedColorScheme.APP_DEFAULT)); + } + + @Test + public void getStatusPreviewTextColor() { + final Resources resources = mActivity.getResources(); + final int darkColor = resources.getColor(R.color.locationbar_status_preview_color_dark); + final int lightColor = resources.getColor(R.color.locationbar_status_preview_color_light); + final int incognitoColor = + resources.getColor(R.color.locationbar_status_preview_color_incognito); + final int defaultColor = MaterialColors.getColor(mActivity, R.attr.colorPrimary, TAG); + + assertEquals("Wrong status preview text color for LIGHT_THEME.", darkColor, + OmniboxResourceProvider.getStatusPreviewTextColor( + mActivity, BrandedColorScheme.LIGHT_BRANDED_THEME)); + assertEquals("Wrong status preview text color for DARK_THEME.", lightColor, + OmniboxResourceProvider.getStatusPreviewTextColor( + mActivity, BrandedColorScheme.DARK_BRANDED_THEME)); + assertEquals("Wrong status preview text color for INCOGNITO.", incognitoColor, + OmniboxResourceProvider.getStatusPreviewTextColor( + mActivity, BrandedColorScheme.INCOGNITO)); + assertEquals("Wrong status preview text color for DEFAULT.", defaultColor, + OmniboxResourceProvider.getStatusPreviewTextColor( + mActivity, BrandedColorScheme.APP_DEFAULT)); + } + + @Test + public void getStatusOfflineTextColor() { + final Resources resources = mActivity.getResources(); + final int darkColor = resources.getColor(R.color.locationbar_status_offline_color_dark); + final int lightColor = resources.getColor(R.color.locationbar_status_offline_color_light); + final int incognitoColor = + resources.getColor(R.color.locationbar_status_offline_color_incognito); + final int defaultColor = + MaterialColors.getColor(mActivity, R.attr.colorOnSurfaceVariant, TAG); + + assertEquals("Wrong status offline text color for LIGHT_THEME.", darkColor, + OmniboxResourceProvider.getStatusOfflineTextColor( + mActivity, BrandedColorScheme.LIGHT_BRANDED_THEME)); + assertEquals("Wrong status offline text color for DARK_THEME.", lightColor, + OmniboxResourceProvider.getStatusOfflineTextColor( + mActivity, BrandedColorScheme.DARK_BRANDED_THEME)); + assertEquals("Wrong status offline text color for INCOGNITO.", incognitoColor, + OmniboxResourceProvider.getStatusOfflineTextColor( + mActivity, BrandedColorScheme.INCOGNITO)); + assertEquals("Wrong status offline text color for DEFAULT.", defaultColor, + OmniboxResourceProvider.getStatusOfflineTextColor( + mActivity, BrandedColorScheme.APP_DEFAULT)); + } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index d986081c7..bf2c89ee 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -300,8 +300,8 @@ * Update the visuals of the autocomplete UI. * @param brandedColorScheme The {@link @BrandedColorScheme}. */ - public void updateVisualsForState(@BrandedColorScheme int colorScheme) { - mMediator.updateVisualsForState(colorScheme); + public void updateVisualsForState(@BrandedColorScheme int brandedColorScheme) { + mMediator.updateVisualsForState(brandedColorScheme); } /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index eed7e0d0..eaa5220 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -446,7 +446,7 @@ assert tabModel != null; int tabIndex = TabModelUtils.getTabIndexById(tabModel, tab.getId()); - tabModel.setIndex(tabIndex, TabSelectionType.FROM_OMNIBOX); + tabModel.setIndex(tabIndex, TabSelectionType.FROM_OMNIBOX, false); } else { mBringTabToFrontCallback.onResult(tab); } @@ -509,6 +509,7 @@ new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) .with(ModalDialogProperties.CONTROLLER, dialogController) .with(ModalDialogProperties.TITLE, suggestion.getDisplayText()) + .with(ModalDialogProperties.TITLE_MAX_LINES, 1) .with(ModalDialogProperties.MESSAGE, resources.getString(dialogMessageId)) .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, R.string.ok) .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources,
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java index c5961c1..af599e7d 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.omnibox.MatchClassificationStyle; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.R; +import org.chromium.chrome.browser.omnibox.UrlBarData; import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionUiType; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionHost; @@ -164,7 +165,8 @@ boolean urlHighlighted = false; if (!isSearchSuggestion) { - if (!suggestion.getUrl().isEmpty()) { + if (!suggestion.getUrl().isEmpty() + && UrlBarData.shouldShowUrl(suggestion.getUrl().getSpec(), false)) { SuggestionSpannable str = new SuggestionSpannable(suggestion.getDisplayText()); urlHighlighted = applyHighlightToMatchRegions( str, suggestion.getDisplayTextClassifications());
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index aa971a10..a9cdf42d4 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -585,17 +585,14 @@ <message name="IDS_PASSWORDS_CHECK_DESCRIPTION" desc="Text explaining the benefits of checking the passwords, to be displayed under the Check Passwords button title."> Keep your passwords safe from data breaches and other security issues </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL" desc="Title for the trusted vault banner in password settings."> - Trusted vault + <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL" desc="Title for the on-device encryption banner in password settings."> + On-device encryption </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN" desc="Sub-label for the trusted vault banner when the user is offered to opt in to trusted vault encryption."> - Opt in to trusted vault + <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN" desc="Sub-label for the on-device encryption banner when the user is offered to opt in."> + Encrypt passwords on your device before they‘re saved to Google Password Manager </message> - <!-- TODO(crbug.com/1202088): Remove "translateable=false" once definitive string is available, and update description. --> - <message translateable="false" name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN" desc="Sub-label for the trusted vault banner when the user is already opted in to trusted vault encryption."> - You are opted in to trusted vault + <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN" desc="Sub-label for the on-device encryption banner when the user is already opted in."> + Your password are encrypted on your device before they’re saved to Google Password Manager </message> <message name="IDS_SECTION_SAVED_PASSWORDS_EXCEPTIONS" desc="Header for the list of websites for which user selected to never save passwords. [CHAR_LIMIT=32]"> Never saved
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1 new file mode 100644 index 0000000..ddcbe96 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1
@@ -0,0 +1 @@ +5c8c39e592b62d13ae9c22ffb968bc80ba090260 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1 new file mode 100644 index 0000000..ddcbe96 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1
@@ -0,0 +1 @@ +5c8c39e592b62d13ae9c22ffb968bc80ba090260 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1 new file mode 100644 index 0000000..5d43d771 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1
@@ -0,0 +1 @@ +14e7a6481c100f68c9b09cd8b591038199933e2a \ No newline at end of file
diff --git a/chrome/browser/ui/android/theme/BUILD.gn b/chrome/browser/ui/android/theme/BUILD.gn index 36e61e78..226babee 100644 --- a/chrome/browser/ui/android/theme/BUILD.gn +++ b/chrome/browser/ui/android/theme/BUILD.gn
@@ -50,7 +50,6 @@ android_resources("java_resources") { sources = [ - "java/res/color/toolbar_icon_tint_dark.xml", "java/res/values/colors.xml", "java/res/values/values.xml", ]
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeColorProvider.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeColorProvider.java index 1da27f1..e799b13 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeColorProvider.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeColorProvider.java
@@ -8,10 +8,11 @@ import android.content.res.ColorStateList; import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.chromium.base.ObserverList; -import org.chromium.ui.util.ColorUtils; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; /** * An abstract class that provides the current theme color. @@ -34,25 +35,19 @@ public interface TintObserver { /** * @param tint The new tint the observer should use. - * @param useLight Whether the observer should use light mode. + * @param brandedColorScheme The {@link BrandedColorScheme} the observer should use. */ - void onTintChanged(ColorStateList tint, boolean useLight); + void onTintChanged(ColorStateList tint, @BrandedColorScheme int brandedColorScheme); } - /** Light mode tint (used when color is dark). */ - private final ColorStateList mLightModeTint; - - /** Dark mode tint (used when color is light). */ - private final ColorStateList mDarkModeTint; - /** Current primary color. */ private int mPrimaryColor; - /** - * Whether should use light tint (corresponds to dark color). If null, the state is not - * initialized. - */ - private @Nullable Boolean mUseLightTint; + /** The current {@link BrandedColorScheme}. */ + private @Nullable @BrandedColorScheme Integer mBrandedColorScheme; + + /** The current tint. */ + private ColorStateList mTint; /** List of {@link ThemeColorObserver}s. These are used to broadcast events to listeners. */ private final ObserverList<ThemeColorObserver> mThemeColorObservers; @@ -66,8 +61,7 @@ public ThemeColorProvider(Context context) { mThemeColorObservers = new ObserverList<ThemeColorObserver>(); mTintObservers = new ObserverList<TintObserver>(); - mLightModeTint = ThemeUtils.getThemedToolbarIconTint(context, true); - mDarkModeTint = ThemeUtils.getThemedToolbarIconTint(context, false); + mTint = ThemeUtils.getThemedToolbarIconTint(context, BrandedColorScheme.APP_DEFAULT); } /** @@ -112,14 +106,14 @@ * @return The current tint of this provider. */ public ColorStateList getTint() { - return useLight() ? mLightModeTint : mDarkModeTint; + return mTint; } /** - * @return Whether or not this provider is using light tints. + * @return The current {@link BrandedColorScheme} of this provider. */ - public boolean useLight() { - return mUseLightTint != null ? mUseLightTint : false; + public @BrandedColorScheme int getBrandedColorScheme() { + return mBrandedColorScheme != null ? mBrandedColorScheme : BrandedColorScheme.APP_DEFAULT; } /** @@ -136,16 +130,16 @@ for (ThemeColorObserver observer : mThemeColorObservers) { observer.onThemeColorChanged(color, shouldAnimate); } - updateTint(); } - private void updateTint() { - final boolean useLight = ColorUtils.shouldUseLightForegroundOnBackground(mPrimaryColor); - if (mUseLightTint != null && useLight == mUseLightTint) return; - mUseLightTint = useLight; - final ColorStateList tint = useLight ? mLightModeTint : mDarkModeTint; + protected void updateTint( + @NonNull ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { + if (tint == mTint) return; + mTint = tint; + mBrandedColorScheme = brandedColorScheme; + for (TintObserver observer : mTintObservers) { - observer.onTintChanged(tint, useLight); + observer.onTintChanged(tint, brandedColorScheme); } } }
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java index 8ef7b43..a2ba90a 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.native_page.NativePage; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.content_public.browser.RenderWidgetHostView; import org.chromium.content_public.browser.WebContents; @@ -129,7 +130,40 @@ // Light toolbar theme colors may be used in night mode, so use toolbar_icon_tint_dark which // is not overridden in night- resources. return useLight ? R.color.default_icon_color_light_tint_list - : R.color.toolbar_icon_tint_dark; + : R.color.default_icon_color_dark_tint_list; + } + + /** + * Returns the themed toolbar icon tint list. + * + * @param context The context to retrieve the resources from. + * @param brandedColorScheme The {@link BrandedColorScheme}. + * @return Primary icon tint list. + */ + public static ColorStateList getThemedToolbarIconTint( + Context context, @BrandedColorScheme int brandedColorScheme) { + return AppCompatResources.getColorStateList( + context, getThemedToolbarIconTintRes(brandedColorScheme)); + } + + /** + * Returns the themed toolbar icon tint resource. + * + * @param brandedColorScheme The {@link BrandedColorScheme}. + * @return Primary icon tint resource. + */ + public static @ColorRes int getThemedToolbarIconTintRes( + @BrandedColorScheme int brandedColorScheme) { + @ColorRes + int colorId = R.color.default_icon_color_tint_list; + if (brandedColorScheme == BrandedColorScheme.INCOGNITO) { + colorId = R.color.default_icon_color_light_tint_list; + } else if (brandedColorScheme == BrandedColorScheme.LIGHT_BRANDED_THEME) { + colorId = R.color.default_icon_color_dark_tint_list; + } else if (brandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME) { + colorId = R.color.default_icon_color_white_tint_list; + } + return colorId; } /**
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java index 60d506a..d6481ba 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.theme; import android.content.Context; +import android.content.res.ColorStateList; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -17,6 +18,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.ui.native_page.NativePage; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.ui.util.ColorUtils; @@ -103,6 +105,21 @@ private void updateColor(Tab tab, int themeColor, boolean shouldAnimate) { updatePrimaryColor(calculateColor(tab, themeColor), shouldAnimate); mIsDefaultColorUsed = isUsingDefaultColor(tab, themeColor); + final @BrandedColorScheme int brandedColorScheme = + calculateBrandedColorScheme(tab.isIncognito(), mIsDefaultColorUsed); + final ColorStateList iconTint = + ThemeUtils.getThemedToolbarIconTint(mContext, brandedColorScheme); + updateTint(iconTint, brandedColorScheme); + } + + private int calculateBrandedColorScheme(boolean isIncognito, boolean isDefaultColor) { + if (isIncognito) return BrandedColorScheme.INCOGNITO; + if (isDefaultColor) return BrandedColorScheme.APP_DEFAULT; + + final boolean isDarkTheme = + ColorUtils.shouldUseLightForegroundOnBackground(getThemeColor()); + return isDarkTheme ? BrandedColorScheme.DARK_BRANDED_THEME + : BrandedColorScheme.LIGHT_BRANDED_THEME; } /**
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn index 8d56518..0231a777 100644 --- a/chrome/browser/ui/android/toolbar/BUILD.gn +++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -237,8 +237,10 @@ "java/res/layout/tab_switcher_toolbar.xml", "java/res/layout/toolbar_phone.xml", "java/res/layout/toolbar_tablet.xml", + "java/res/values-night/drawables.xml", "java/res/values-sw600dp/dimens.xml", "java/res/values/dimens.xml", + "java/res/values/drawables.xml", "java/res/values/ids.xml", "java/res/values/styles.xml", "java/res/values/values.xml",
diff --git a/chrome/browser/ui/android/toolbar/java/res/values-night/drawables.xml b/chrome/browser/ui/android/toolbar/java/res/values-night/drawables.xml new file mode 100644 index 0000000..5b4031d --- /dev/null +++ b/chrome/browser/ui/android/toolbar/java/res/values-night/drawables.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<resources> + <drawable name="badge_update">@drawable/badge_update_light</drawable> + <drawable name="ic_error_24dp_filled">@drawable/ic_error_white_24dp_filled</drawable> +</resources>
diff --git a/chrome/browser/ui/android/toolbar/java/res/values/drawables.xml b/chrome/browser/ui/android/toolbar/java/res/values/drawables.xml new file mode 100644 index 0000000..4539df5 --- /dev/null +++ b/chrome/browser/ui/android/toolbar/java/res/values/drawables.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<resources> + <drawable name="badge_update">@drawable/badge_update_dark</drawable> + <drawable name="ic_error_24dp_filled">@drawable/ic_error_grey800_24dp_filled</drawable> +</resources>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java index d0632e7..10d11b8 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -34,7 +34,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TrustedCdn; import org.chromium.chrome.browser.theme.ThemeUtils; -import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.components.browser_ui.styles.ChromeColors; @@ -248,11 +247,12 @@ @Override public UrlBarData getUrlBarData() { - if (!hasTab()) return UrlBarData.EMPTY; + if (!hasTab() || StartSurfaceConfiguration.shouldHandleAsNtp(getTab())) { + return UrlBarData.EMPTY; + } String url = getCurrentUrl(); - if (NativePage.isNativePageUrl(url, isIncognito()) || UrlUtilities.isNTPUrl(url) - || StartSurfaceConfiguration.shouldHandleAsNtp(getTab())) { + if (!UrlBarData.shouldShowUrl(url, isIncognito())) { return UrlBarData.EMPTY; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java index d0cdbfc..4784bb4 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java
@@ -5,8 +5,10 @@ package org.chromium.chrome.browser.toolbar; import android.content.Context; +import android.content.res.ColorStateList; import org.chromium.chrome.browser.theme.ThemeColorProvider; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; /** * {@link ThemeColorProvider} that blindly tracks whatever primary color it's set to. @@ -28,4 +30,11 @@ public void setPrimaryColor(int color, boolean shouldAnimate) { updatePrimaryColor(color, shouldAnimate); } + + /** + * Sets the tint to the specified value. + */ + public void setTint(ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { + updateTint(tint, brandedColorScheme); + } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java index 2479bc7..2f3eb0f 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.browser.theme.ThemeColorProvider; import org.chromium.chrome.browser.theme.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.toolbar.TabCountProvider.TabCountObserver; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -53,7 +54,8 @@ mThemeColorProvider = themeColorProvider; mTintObserver = new TintObserver() { @Override - public void onTintChanged(ColorStateList tint, boolean useLight) { + public void onTintChanged( + ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { mTabSwitcherButtonModel.set(TabSwitcherButtonProperties.TINT, tint); } };
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java index 1d43cc5..0a74b322 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.widget.animation.Interpolators; import org.chromium.components.browser_ui.widget.highlight.PulseDrawable; import org.chromium.ui.interpolators.BakedBezierInterpolator; @@ -44,7 +45,7 @@ /** The view for the update badge. */ private ImageView mUpdateBadgeView; - private boolean mUseLightDrawables; + private @BrandedColorScheme int mBrandedColorScheme; private AppMenuButtonHelper mAppMenuButtonHelper; @@ -121,7 +122,7 @@ mMenuImageButton.getWidth() - mMenuImageButton.getPaddingRight(), mMenuImageButton.getHeight() - mMenuImageButton.getPaddingBottom()); mMenuImageButtonAnimationDrawable.setGravity(Gravity.CENTER); - int color = ThemeUtils.getThemedToolbarIconTint(getContext(), mUseLightDrawables) + int color = ThemeUtils.getThemedToolbarIconTint(getContext(), mBrandedColorScheme) .getDefaultColor(); mMenuImageButtonAnimationDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); @@ -130,7 +131,7 @@ MenuButtonState buttonState = mStateSupplier.get(); if (buttonState == null || mUpdateBadgeView == null) return; @DrawableRes - int drawable = mUseLightDrawables ? buttonState.lightBadgeIcon : buttonState.darkBadgeIcon; + int drawable = getUpdateBadgeIcon(buttonState, mBrandedColorScheme); mUpdateBadgeView.setImageDrawable( ApiCompatibilityUtils.getDrawable(getResources(), drawable)); mUpdateBadgeAnimationDrawable = (BitmapDrawable) mUpdateBadgeView.getDrawable() @@ -144,6 +145,19 @@ mUpdateBadgeAnimationDrawable.setGravity(Gravity.CENTER); } + private @DrawableRes int getUpdateBadgeIcon( + MenuButtonState buttonState, @BrandedColorScheme int brandedColorScheme) { + @DrawableRes + int drawable = buttonState.adaptiveBadgeIcon; + if (brandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME + || brandedColorScheme == BrandedColorScheme.INCOGNITO) { + drawable = buttonState.lightBadgeIcon; + } else if (brandedColorScheme == BrandedColorScheme.LIGHT_BRANDED_THEME) { + drawable = buttonState.darkBadgeIcon; + } + return drawable; + } + /** * Set the supplier of menu button state. * @param supplier Supplier of menu button state. @@ -261,7 +275,10 @@ ViewCompat.getPaddingEnd(mMenuImageButton), mMenuImageButton.getPaddingBottom()); } - mHighlightDrawable.setUseLightPulseColor(getContext(), mUseLightDrawables); + // TODO(https://crbug.com/1233703) This doesn't work well with website themes. + boolean isLightPulseColor = mBrandedColorScheme == BrandedColorScheme.DARK_BRANDED_THEME + || mBrandedColorScheme == BrandedColorScheme.INCOGNITO; + mHighlightDrawable.setUseLightPulseColor(getContext(), isLightPulseColor); setBackground(mHighlightDrawable); mHighlightDrawable.start(); } else { @@ -287,14 +304,14 @@ } @VisibleForTesting - public boolean getUseLightDrawablesForTesting() { - return mUseLightDrawables; + public @BrandedColorScheme int getBrandedColorSchemeForTesting() { + return mBrandedColorScheme; } @Override - public void onTintChanged(ColorStateList tintList, boolean useLight) { + public void onTintChanged(ColorStateList tintList, @BrandedColorScheme int brandedColorScheme) { ApiCompatibilityUtils.setImageTintList(mMenuImageButton, tintList); - mUseLightDrawables = useLight; + mBrandedColorScheme = brandedColorScheme; updateImageResources(); updateMenuButtonHighlightDrawable(); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java index 105fdd29..de7646d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java
@@ -77,7 +77,7 @@ new ShowBadgeProperty(false, false)) .with(MenuButtonProperties.THEME, new ThemeProperty(themeColorProvider.getTint(), - themeColorProvider.useLight())) + themeColorProvider.getBrandedColorScheme())) .with(MenuButtonProperties.IS_VISIBLE, true) .with(MenuButtonProperties.STATE_SUPPLIER, menuButtonStateSupplier) .build();
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java index 4c13daaf..46094d76 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; import org.chromium.chrome.browser.ui.appmenu.AppMenuObserver; import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; @@ -231,8 +232,10 @@ updateContentDescription(false, 0); } - private void onTintChanged(ColorStateList tintList, boolean useLight) { - mPropertyModel.set(MenuButtonProperties.THEME, new ThemeProperty(tintList, useLight)); + private void onTintChanged( + ColorStateList tintList, @BrandedColorScheme int brandedColorScheme) { + mPropertyModel.set( + MenuButtonProperties.THEME, new ThemeProperty(tintList, brandedColorScheme)); } /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java index f8f5d61..504a8c81 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java
@@ -88,7 +88,7 @@ new ShowBadgeProperty(false, false)) .with(MenuButtonProperties.THEME, new ThemeProperty(mThemeColorProvider.getTint(), - mThemeColorProvider.useLight())) + mThemeColorProvider.getBrandedColorScheme())) .with(MenuButtonProperties.IS_VISIBLE, true) .build(); doReturn(mAppMenuHandler).when(mAppMenuCoordinator).getAppMenuHandler();
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java index 5c652127..de41381 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java
@@ -10,6 +10,7 @@ import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey; @@ -19,11 +20,12 @@ static class ThemeProperty { @NonNull public ColorStateList mColorStateList; - public boolean mUseLightColors; + public @BrandedColorScheme int mBrandedColorScheme; - public ThemeProperty(@NonNull ColorStateList colorStateList, boolean useLight) { + public ThemeProperty(@NonNull ColorStateList colorStateList, + @BrandedColorScheme int brandedColorScheme) { mColorStateList = colorStateList; - mUseLightColors = useLight; + mBrandedColorScheme = brandedColorScheme; } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonState.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonState.java index ca15f97..e9d2803 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonState.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonState.java
@@ -26,4 +26,10 @@ * this object is not {@code null}. */ public @DrawableRes int lightBadgeIcon; + + /** + * An icon resource for the badge for the menu button that adapts to light and dark modes. + * Always set (not {@code 0}) if this object is not {@code null}. + */ + public @DrawableRes int adaptiveBadgeIcon; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java index a336e62..17174622 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java
@@ -35,6 +35,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.toolbar.R; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; /** * Unit tests for MenuButton. @@ -64,6 +65,7 @@ R.string.accessibility_toolbar_btn_menu_update; mMenuUiState.buttonState.darkBadgeIcon = R.drawable.badge_update_dark; mMenuUiState.buttonState.lightBadgeIcon = R.drawable.badge_update_light; + mMenuUiState.buttonState.adaptiveBadgeIcon = R.drawable.badge_update; mMenuButton.setStateSupplier(() -> mMenuUiState.buttonState); } @@ -94,7 +96,7 @@ assertEquals(drawnDrawable.getCreatedFromResId(), darkDrawable.getCreatedFromResId()); assertNotEquals(drawnDrawable.getCreatedFromResId(), lightDrawable.getCreatedFromResId()); - mMenuButton.onTintChanged(mColorStateList, true); + mMenuButton.onTintChanged(mColorStateList, BrandedColorScheme.DARK_BRANDED_THEME); drawnDrawable = shadowOf(mMenuButton.getTabSwitcherAnimationDrawable()); assertEquals(drawnDrawable.getCreatedFromResId(), lightDrawable.getCreatedFromResId()); assertNotEquals(drawnDrawable.getCreatedFromResId(), darkDrawable.getCreatedFromResId()); @@ -114,7 +116,7 @@ @Test public void testDrawTabSwitcherAnimationOverlay_correctBoundsAfterThemeChange() { mMenuButton.removeAppMenuUpdateBadge(false); - mMenuButton.onTintChanged(mColorStateList, true); + mMenuButton.onTintChanged(mColorStateList, BrandedColorScheme.DARK_BRANDED_THEME); // Run a manual layout pass so that mMenuButton's children get assigned sizes. mMenuButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java index 000c4d9..556e4ff 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java
@@ -47,7 +47,7 @@ } else if (propertyKey == MenuButtonProperties.THEME) { bind(model, view, MenuButtonProperties.STATE_SUPPLIER); ThemeProperty themeProperty = model.get(MenuButtonProperties.THEME); - view.onTintChanged(themeProperty.mColorStateList, themeProperty.mUseLightColors); + view.onTintChanged(themeProperty.mColorStateList, themeProperty.mBrandedColorScheme); } else if (propertyKey == MenuButtonProperties.TRANSLATION_X) { view.setTranslationX(model.get(MenuButtonProperties.TRANSLATION_X)); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index be5de17..f62e567 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -55,6 +55,7 @@ import org.chromium.chrome.browser.toolbar.top.ToolbarTablet.OfflineDownloader; import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.UrlExpansionObserver; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.ui.UiUtils; import org.chromium.ui.base.ViewUtils; @@ -206,15 +207,8 @@ return mThemeColorProvider == null ? mDefaultTint : mThemeColorProvider.getTint(); } - /** - * @return Whether to use light assets. - */ - protected boolean useLight() { - return mThemeColorProvider != null && mThemeColorProvider.useLight(); - } - @Override - public void onTintChanged(ColorStateList tint, boolean useLight) {} + public void onTintChanged(ColorStateList tint, @BrandedColorScheme int brandedColorScheme) {} @Override public void onThemeColorChanged(int color, boolean shouldAnimate) {}
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index ef28d03f..1e47554 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -66,6 +66,7 @@ import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator; import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.UrlExpansionObserver; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.components.browser_ui.widget.animation.Interpolators; @@ -147,7 +148,7 @@ @ViewDebug.ExportedProperty(category = "chrome") protected boolean mTextureCaptureMode; private boolean mForceTextureCapture; - private boolean mLightDrawablesUsedForLastTextureCapture; + private int mTintUsedForLastTextureCapture; private int mTabCountForLastTextureCapture; @ViewDebug.ExportedProperty(category = "chrome") @@ -1326,7 +1327,7 @@ mToolbarButtonsContainer, canvas, rgbAlpha); } - mLightDrawablesUsedForLastTextureCapture = useLight(); + mTintUsedForLastTextureCapture = getTint().getDefaultColor(); if (mTabSwitcherAnimationTabStackDrawable != null && mToggleTabStackButton != null) { mTabCountForLastTextureCapture = mTabSwitcherAnimationTabStackDrawable.getTabCount(); @@ -1557,7 +1558,7 @@ if (forceTextureCapture) { // Only force a texture capture if the tint for the toolbar drawables is changing or // if the tab count has changed since the last texture capture. - mForceTextureCapture = mLightDrawablesUsedForLastTextureCapture != useLight(); + mForceTextureCapture = mTintUsedForLastTextureCapture != getTint().getDefaultColor(); if (mTabSwitcherAnimationTabStackDrawable != null && mToggleTabStackButton != null) { mForceTextureCapture = mForceTextureCapture @@ -1635,16 +1636,21 @@ } @Override - public void onTintChanged(ColorStateList tint, boolean useLight) { + public void onThemeColorChanged(int color, boolean shouldAnimate) { + if (mToggleTabStackButton != null) { + final boolean useLight = ColorUtils.shouldUseLightForegroundOnBackground(color); + mToggleTabStackButton.setUseLightDrawables(useLight); + } + } + + @Override + public void onTintChanged(ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { if (mHomeButton != null) { ApiCompatibilityUtils.setImageTintList(mHomeButton, tint); } - if (mToggleTabStackButton != null) { - mToggleTabStackButton.setUseLightDrawables(useLight); - if (mTabSwitcherAnimationTabStackDrawable != null) { - mTabSwitcherAnimationTabStackDrawable.setTint(tint); - } + if (mToggleTabStackButton != null && mTabSwitcherAnimationTabStackDrawable != null) { + mTabSwitcherAnimationTabStackDrawable.setTint(tint); } if (mOptionalButton != null && mOptionalButtonUsesTint) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index 2f941cd..d4f7def4 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -49,10 +49,12 @@ import org.chromium.chrome.browser.toolbar.ToolbarTabController; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator; import org.chromium.chrome.browser.toolbar.top.NavigationPopup.HistoryDelegate; +import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.ui.UiUtils; import org.chromium.ui.base.DeviceFormFactor; +import org.chromium.ui.util.ColorUtils; import org.chromium.ui.widget.Toast; import java.util.ArrayList; @@ -379,13 +381,12 @@ } @Override - public void onTintChanged(ColorStateList tint, boolean useLight) { + public void onTintChanged(ColorStateList tint, @BrandedColorScheme int brandedColorScheme) { ApiCompatibilityUtils.setImageTintList(mHomeButton, tint); ApiCompatibilityUtils.setImageTintList(mBackButton, tint); ApiCompatibilityUtils.setImageTintList(mForwardButton, tint); ApiCompatibilityUtils.setImageTintList(mSaveOfflineButton, tint); ApiCompatibilityUtils.setImageTintList(mReloadButton, tint); - mAccessibilitySwitcherButton.setUseLightDrawables(useLight); if (mOptionalButton != null && mOptionalButtonUsesTint) { ApiCompatibilityUtils.setImageTintList(mOptionalButton, tint); @@ -400,6 +401,8 @@ mLocationBar.getTabletCoordinator().getBackground().setTint(textBoxColor); mLocationBar.updateVisualsForState(); setToolbarHairlineColor(color); + final boolean useLight = ColorUtils.shouldUseLightForegroundOnBackground(color); + mAccessibilitySwitcherButton.setUseLightDrawables(useLight); } /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediator.java index fa33c06e..07b35008 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediator.java
@@ -13,6 +13,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; import org.chromium.chrome.browser.layouts.LayoutType; @@ -209,8 +210,10 @@ // Update and set the progress info to trigger an update; the PROGRESS_BAR_INFO // property skips the object equality check. mProgressInfoCallback.onResult(mModel.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO)); - mModel.set(TopToolbarOverlayProperties.PROGRESS_BAR_INFO, - mModel.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO)); + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.DISABLE_COMPOSITED_PROGRESS_BAR)) { + mModel.set(TopToolbarOverlayProperties.PROGRESS_BAR_INFO, + mModel.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO)); + } } /** @return Whether this component is in tablet mode. */
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediatorTest.java index c3e05e9d..e2cb7ede 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediatorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediatorTest.java
@@ -13,7 +13,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; @@ -24,19 +26,26 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; +import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.ui.modelutil.PropertyModel; /** Tests for the top toolbar overlay's mediator (composited version of the top toolbar). */ @RunWith(BaseRobolectricTestRunner.class) +@DisableFeatures(ChromeFeatureList.DISABLE_COMPOSITED_PROGRESS_BAR) public class TopToolbarOverlayMediatorTest { private TopToolbarOverlayMediator mMediator; private PropertyModel mModel; + @Rule + public TestRule mProcessor = new Features.JUnitProcessor(); + @Mock private Context mContext;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarSceneLayer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarSceneLayer.java index 04710f2..84053b84 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarSceneLayer.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarSceneLayer.java
@@ -7,6 +7,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.base.supplier.Supplier; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer; import org.chromium.chrome.browser.layouts.scene_layer.SceneOverlayLayer; import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar.DrawingInfo; @@ -49,6 +50,10 @@ model.get(TopToolbarOverlayProperties.VISIBLE), model.get(TopToolbarOverlayProperties.ANONYMIZE)); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.DISABLE_COMPOSITED_PROGRESS_BAR)) { + return; + } + DrawingInfo progressInfo = model.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO); if (progressInfo == null) return;
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index 7c28175a..fcfbfad 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -66,6 +66,7 @@ virtual void PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) {} + virtual void ClearSearchResults() {} virtual std::vector<ChromeSearchResult*> GetPublishedSearchResultsForTest(); // Item field setters only used by ChromeAppListItem and its derived classes.
diff --git a/chrome/browser/ui/app_list/arc/intent.cc b/chrome/browser/ui/app_list/arc/intent.cc index b2ec476..d457bc4 100644 --- a/chrome/browser/ui/app_list/arc/intent.cc +++ b/chrome/browser/ui/app_list/arc/intent.cc
@@ -40,7 +40,7 @@ // static std::unique_ptr<Intent> Intent::Get(const std::string& intent_as_string) { const std::vector<base::StringPiece> parts = base::SplitStringPiece( - intent_as_string, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + intent_as_string, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); if (parts.size() < 2 || parts.front() != kIntentPrefix || parts.back() != kEndSuffix) { DVLOG(1) << "Failed to split intent " << intent_as_string << "."; @@ -52,6 +52,13 @@ for (size_t i = 1; i < parts.size() - 1; ++i) { const size_t separator = parts[i].find('='); if (separator == std::string::npos) { + if (parts[i].empty()) { + // Intent should not have empty param. The empty param would appear in + // intent string as ';;'. In the last case it would cause error in + // Android framework. Such intents must not appear in the system. + DVLOG(1) << "Found empty param in " << intent_as_string << "."; + return nullptr; + } intent->AddExtraParam(std::string(parts[i])); continue; } @@ -116,7 +123,8 @@ const std::string& activity, const std::vector<std::string>& extra_params) { const std::string extra_params_extracted = - base::JoinString(extra_params, ";") + ';'; + extra_params.empty() ? std::string() + : (base::JoinString(extra_params, ";") + ";"); // Remove the |package_name| prefix, if activity starts with it. const char* activity_compact_name =
diff --git a/chrome/browser/ui/app_list/arc/intent_unittest.cc b/chrome/browser/ui/app_list/arc/intent_unittest.cc index 930c89a..4d7f8524 100644 --- a/chrome/browser/ui/app_list/arc/intent_unittest.cc +++ b/chrome/browser/ui/app_list/arc/intent_unittest.cc
@@ -112,4 +112,23 @@ EXPECT_EQ(shelf_id2.app_id(), kPlayStoreAppId); } +TEST_F(ArcIntentTest, EmptyExtraParams) { + auto intent = + Intent::Get(GetLaunchIntent(kPlayStorePackage, kPlayStoreActivity, {})); + ASSERT_TRUE(intent); + EXPECT_TRUE(intent->extra_params().empty()); +} + +TEST_F(ArcIntentTest, WrongIntents) { + // ;; is bad part here. + EXPECT_FALSE( + Intent::Get("#Intent;action=android.intent.action.MAIN;category=android." + "intent.category.LAUNCHER;launchFlags=0x10200000;component=" + "com.android.vending/.AssetBrowserActivity;;end")); + EXPECT_TRUE( + Intent::Get("#Intent;action=android.intent.action.MAIN;category=android." + "intent.category.LAUNCHER;launchFlags=0x10200000;component=" + "com.android.vending/.AssetBrowserActivity;end")); +} + } // namespace arc
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index f63a118..5055e07a 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -319,6 +319,11 @@ search_model_.PublishResults(std::move(ash_results), categories); } +void ChromeAppListModelUpdater::ClearSearchResults() { + published_results_.clear(); + search_model_.DeleteAllResults(); +} + std::vector<ChromeSearchResult*> ChromeAppListModelUpdater::GetPublishedSearchResultsForTest() { return published_results_;
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index f52a6fa..695d2ff1 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -55,6 +55,7 @@ void PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) override; + void ClearSearchResults() override; std::vector<ChromeSearchResult*> GetPublishedSearchResultsForTest() override; // Methods only used by ChromeAppListItem that talk to ash directly.
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index a56d25e..f526c94 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -460,10 +460,14 @@ data_source->ViewClosing(); } -ash::AppListSearchResultType AppSearchProvider::ResultType() { +ash::AppListSearchResultType AppSearchProvider::ResultType() const { return ash::AppListSearchResultType::kInstalledApp; } +bool AppSearchProvider::ShouldBlockZeroState() const { + return true; +} + void AppSearchProvider::RefreshAppsAndUpdateResults() { // Clear any pending requests if any. refresh_apps_factory_.InvalidateWeakPtrs();
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.h b/chrome/browser/ui/app_list/search/app_search_provider.h index 6817171..ff6871c 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.h +++ b/chrome/browser/ui/app_list/search/app_search_provider.h
@@ -51,7 +51,8 @@ void Start(const std::u16string& query) override; void StartZeroState() override; void ViewClosing() override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; + bool ShouldBlockZeroState() const override; // Refreshes apps and updates results inline void RefreshAppsAndUpdateResults();
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc index 2cb3323b..20b18de 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
@@ -28,7 +28,7 @@ ArcAppShortcutsSearchProvider::~ArcAppShortcutsSearchProvider() = default; -ash::AppListSearchResultType ArcAppShortcutsSearchProvider::ResultType() { +ash::AppListSearchResultType ArcAppShortcutsSearchProvider::ResultType() const { return ash::AppListSearchResultType::kArcAppShortcut; }
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h index df34fc1d..883e276 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h +++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h
@@ -31,7 +31,7 @@ // SearchProvider: void Start(const std::u16string& query) override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; private: void OnGetAppShortcutGlobalQueryItems(
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc index 68ac6d0e..77dacde4 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
@@ -87,7 +87,7 @@ ArcPlayStoreSearchProvider::~ArcPlayStoreSearchProvider() = default; -ash::AppListSearchResultType ArcPlayStoreSearchProvider::ResultType() { +ash::AppListSearchResultType ArcPlayStoreSearchProvider::ResultType() const { return ash::AppListSearchResultType::kPlayStoreApp; }
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h index 637742a..3efe593 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h
@@ -34,7 +34,7 @@ // SearchProvider: void Start(const std::u16string& query) override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; private: void OnResults(const std::u16string& query,
diff --git a/chrome/browser/ui/app_list/search/assistant_text_search_provider.cc b/chrome/browser/ui/app_list/search/assistant_text_search_provider.cc index 2bcfe2bc..40a2562 100644 --- a/chrome/browser/ui/app_list/search/assistant_text_search_provider.cc +++ b/chrome/browser/ui/app_list/search/assistant_text_search_provider.cc
@@ -94,7 +94,7 @@ AssistantTextSearchProvider::~AssistantTextSearchProvider() = default; -ash::AppListSearchResultType AssistantTextSearchProvider::ResultType() { +ash::AppListSearchResultType AssistantTextSearchProvider::ResultType() const { return ash::AppListSearchResultType::kAssistantText; }
diff --git a/chrome/browser/ui/app_list/search/assistant_text_search_provider.h b/chrome/browser/ui/app_list/search/assistant_text_search_provider.h index f240bbb0a..f5a0033f 100644 --- a/chrome/browser/ui/app_list/search/assistant_text_search_provider.h +++ b/chrome/browser/ui/app_list/search/assistant_text_search_provider.h
@@ -15,8 +15,7 @@ // A search provider implementation serving results from Assistant. // This is currently only used to provide a single search result that runs an -// Assistant query of the search text. This is displayed when -// kEnableAssistantSearch feature is enabled. This search result does not go +// Assistant query of the search text. This search result does not go // through normal ranking procedures, but is instead appended to an existing // list of search results. class AssistantTextSearchProvider : public SearchProvider, @@ -34,7 +33,7 @@ private: // SearchProvider: - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; // ash::AssistantControllerObserver: void OnAssistantControllerDestroying() override;
diff --git a/chrome/browser/ui/app_list/search/files/drive_search_provider.cc b/chrome/browser/ui/app_list/search/files/drive_search_provider.cc index b66deb3..3848e92 100644 --- a/chrome/browser/ui/app_list/search/files/drive_search_provider.cc +++ b/chrome/browser/ui/app_list/search/files/drive_search_provider.cc
@@ -50,7 +50,7 @@ DriveSearchProvider::~DriveSearchProvider() = default; -ash::AppListSearchResultType DriveSearchProvider::ResultType() { +ash::AppListSearchResultType DriveSearchProvider::ResultType() const { return ash::AppListSearchResultType::kDriveSearch; }
diff --git a/chrome/browser/ui/app_list/search/files/drive_search_provider.h b/chrome/browser/ui/app_list/search/files/drive_search_provider.h index 2148d29..9ca6bb52 100644 --- a/chrome/browser/ui/app_list/search/files/drive_search_provider.h +++ b/chrome/browser/ui/app_list/search/files/drive_search_provider.h
@@ -35,7 +35,7 @@ DriveSearchProvider& operator=(const DriveSearchProvider&) = delete; // SearchProvider: - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; void Start(const std::u16string& query) override; private:
diff --git a/chrome/browser/ui/app_list/search/files/file_search_provider.cc b/chrome/browser/ui/app_list/search/files/file_search_provider.cc index b16a54c..b631abe 100644 --- a/chrome/browser/ui/app_list/search/files/file_search_provider.cc +++ b/chrome/browser/ui/app_list/search/files/file_search_provider.cc
@@ -100,7 +100,7 @@ FileSearchProvider::~FileSearchProvider() = default; -ash::AppListSearchResultType FileSearchProvider::ResultType() { +ash::AppListSearchResultType FileSearchProvider::ResultType() const { return ash::AppListSearchResultType::kFileSearch; }
diff --git a/chrome/browser/ui/app_list/search/files/file_search_provider.h b/chrome/browser/ui/app_list/search/files/file_search_provider.h index aa4eaac..ce91176 100644 --- a/chrome/browser/ui/app_list/search/files/file_search_provider.h +++ b/chrome/browser/ui/app_list/search/files/file_search_provider.h
@@ -45,7 +45,7 @@ FileSearchProvider& operator=(const FileSearchProvider&) = delete; // SearchProvider: - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; void Start(const std::u16string& query) override; void SetRootPathForTesting(const base::FilePath& root_path) {
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc index 08c021fc..97c43ed8 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc
@@ -192,10 +192,14 @@ item_suggest_cache_.UpdateCache(); } -ash::AppListSearchResultType ZeroStateDriveProvider::ResultType() { +ash::AppListSearchResultType ZeroStateDriveProvider::ResultType() const { return ash::AppListSearchResultType::kZeroStateDrive; } +bool ZeroStateDriveProvider::ShouldBlockZeroState() const { + return true; +} + void ZeroStateDriveProvider::StartZeroState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClearResultsSilently();
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h index 1690390..6fe9eb7f 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h
@@ -53,9 +53,10 @@ const power_manager::ScreenIdleState& proto) override; // SearchProvider: - void AppListShown() override; - ash::AppListSearchResultType ResultType() override; void StartZeroState() override; + void AppListShown() override; + ash::AppListSearchResultType ResultType() const override; + bool ShouldBlockZeroState() const override; void set_session_manager_for_testing( session_manager::SessionManager* session_manager) {
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc index 6385fac..fe0a3d8 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
@@ -103,10 +103,14 @@ ZeroStateFileProvider::~ZeroStateFileProvider() = default; -ash::AppListSearchResultType ZeroStateFileProvider::ResultType() { +ash::AppListSearchResultType ZeroStateFileProvider::ResultType() const { return ash::AppListSearchResultType::kZeroStateFile; } +bool ZeroStateFileProvider::ShouldBlockZeroState() const { + return true; +} + void ZeroStateFileProvider::StartZeroState() { query_start_time_ = base::TimeTicks::Now(); ClearResultsSilently();
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h index efdcaa3..c9804eaf 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
@@ -49,7 +49,8 @@ // SearchProvider: void StartZeroState() override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; + bool ShouldBlockZeroState() const override; // file_manager::file_tasks::FileTaskObserver: void OnFilesOpened(const std::vector<FileOpenEvent>& file_opens) override;
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.cc b/chrome/browser/ui/app_list/search/help_app_provider.cc index 16ed3bf..cc5a8c0c 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.cc +++ b/chrome/browser/ui/app_list/search/help_app_provider.cc
@@ -315,10 +315,14 @@ } } -ash::AppListSearchResultType HelpAppProvider::ResultType() { +ash::AppListSearchResultType HelpAppProvider::ResultType() const { return ash::AppListSearchResultType::kHelpApp; } +bool HelpAppProvider::ShouldBlockZeroState() const { + return true; +} + void HelpAppProvider::OnAppUpdate(const apps::AppUpdate& update) { if (update.AppId() == web_app::kHelpAppId && update.ReadinessChanged() && update.Readiness() == apps::mojom::Readiness::kReady) {
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.h b/chrome/browser/ui/app_list/search/help_app_provider.h index f7df0ae..be2f2d8 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.h +++ b/chrome/browser/ui/app_list/search/help_app_provider.h
@@ -80,7 +80,8 @@ void StartZeroState() override; void ViewClosing() override; void AppListShown() override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; + bool ShouldBlockZeroState() const override; // apps::AppRegistryCache::Observer: void OnAppUpdate(const apps::AppUpdate& update) override;
diff --git a/chrome/browser/ui/app_list/search/mixer_unittest.cc b/chrome/browser/ui/app_list/search/mixer_unittest.cc index 08bef62..2d473ea 100644 --- a/chrome/browser/ui/app_list/search/mixer_unittest.cc +++ b/chrome/browser/ui/app_list/search/mixer_unittest.cc
@@ -109,7 +109,7 @@ } } - ash::AppListSearchResultType ResultType() override { + ash::AppListSearchResultType ResultType() const override { return ash::AppListSearchResultType::kUnknown; }
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc index 50139c3..d2a147c 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.cc +++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc
@@ -97,7 +97,7 @@ Start(std::u16string()); } -ash::AppListSearchResultType OmniboxProvider::ResultType() { +ash::AppListSearchResultType OmniboxProvider::ResultType() const { return ash::AppListSearchResultType::kOmnibox; }
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.h b/chrome/browser/ui/app_list/search/omnibox_provider.h index bcde04e..32e9768 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.h +++ b/chrome/browser/ui/app_list/search/omnibox_provider.h
@@ -34,7 +34,7 @@ // SearchProvider overrides: void Start(const std::u16string& query) override; void StartZeroState() override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; private: // Populates result list from AutocompleteResult.
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.cc b/chrome/browser/ui/app_list/search/os_settings_provider.cc index fc55ebb..530cd9e 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.cc +++ b/chrome/browser/ui/app_list/search/os_settings_provider.cc
@@ -239,7 +239,7 @@ OsSettingsProvider::~OsSettingsProvider() = default; -ash::AppListSearchResultType OsSettingsProvider::ResultType() { +ash::AppListSearchResultType OsSettingsProvider::ResultType() const { return ash::AppListSearchResultType::kOsSettings; }
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.h b/chrome/browser/ui/app_list/search/os_settings_provider.h index 3424fc18..7449024a 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.h +++ b/chrome/browser/ui/app_list/search/os_settings_provider.h
@@ -73,7 +73,7 @@ // SearchProvider: void Start(const std::u16string& query) override; void ViewClosing() override; - ash::AppListSearchResultType ResultType() override; + ash::AppListSearchResultType ResultType() const override; // apps::AppRegistryCache::Observer: void OnAppUpdate(const apps::AppUpdate& update) override;
diff --git a/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.cc b/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.cc deleted file mode 100644 index 7dc9f72..0000000 --- a/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.cc +++ /dev/null
@@ -1,14 +0,0 @@ -// 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/app_list/search/ranking/burn_in_ranker.h" - -namespace app_list { - -void BurnInRanker::UpdateResultRanks(ResultsMap& results, - ProviderType provider) { - // TODO(crbug.com/1279686): Implement. -} - -} // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.h b/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.h deleted file mode 100644 index c8f6705..0000000 --- a/chrome/browser/ui/app_list/search/ranking/burn_in_ranker.h +++ /dev/null
@@ -1,39 +0,0 @@ -// 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_BROWSER_UI_APP_LIST_SEARCH_RANKING_BURN_IN_RANKER_H_ -#define CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_BURN_IN_RANKER_H_ - -#include "chrome/browser/ui/app_list/search/ranking/ranker.h" - -namespace app_list { - -// A ranker which implements a "burn-in" period for the updating of results. -// -// This ranker has two main tasks: -// -// 1) Delay the release of results until after the burn-in period has ended. -// The purpose of this is to prevent the rapid and jittery updating of the -// results list on initial display. -// -// 2) Mark each result as having arrived pre- or post-burn-in time. -// Post-burn-in results may undergo special handling (e.g. append-only), -// with exact details TBD. -// -// TODO(crbug.com/1279686): Update description when implemented. -class BurnInRanker : public Ranker { - public: - BurnInRanker() = default; - ~BurnInRanker() override = default; - - BurnInRanker(const BurnInRanker&) = delete; - BurnInRanker& operator=(const BurnInRanker&) = delete; - - // Ranker: - void UpdateResultRanks(ResultsMap& results, ProviderType provider) override; -}; - -} // namespace app_list - -#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_BURN_IN_RANKER_H_
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc index ff3b296..43ebbfa9 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc +++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/app_list/search/ranking/ranker_delegate.h" -#include "chrome/browser/ui/app_list/search/ranking/burn_in_ranker.h" #include "chrome/browser/ui/app_list/search/ranking/filtering_ranker.h" #include "chrome/browser/ui/app_list/search/ranking/ftrl_category_ranker.h" #include "chrome/browser/ui/app_list/search/ranking/ftrl_result_ranker.h" @@ -44,9 +43,6 @@ AddRanker(std::make_unique<RemovedResultsRanker>( PersistentProto<RemovedResultsProto>( state_dir.AppendASCII("removed_results.pb"), kNoWriteDelay))); - - // Burn-in period for results. - AddRanker(std::make_unique<BurnInRanker>()); } RankerDelegate::~RankerDelegate() {}
diff --git a/chrome/browser/ui/app_list/search/ranking/types.h b/chrome/browser/ui/app_list/search/ranking/types.h index bd01eb5..2160632 100644 --- a/chrome/browser/ui/app_list/search/ranking/types.h +++ b/chrome/browser/ui/app_list/search/ranking/types.h
@@ -33,6 +33,12 @@ double category_usage_score = 0.0f; double usage_score = 0.0f; + // A counter for the burn-in iteration number, where 0 signifies the + // pre-burn-in state, and 1 and above signify the post-burn-in state. + // Incremented during the post-burn-in period each time a provider + // returns. Not applicable to zero-state search. + int burnin_iteration = 0; + Scoring() {} Scoring(const Scoring&) = delete;
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index b39ae217..e3967fed 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -89,8 +89,7 @@ // Update the controller with the given results. Used only if the categorical // search feature flag is enabled. - virtual void SetResults(ash::AppListSearchResultType provider_type, - Results results) = 0; + virtual void SetResults(const SearchProvider* provider, Results results) = 0; virtual ChromeSearchResult* FindSearchResult( const std::string& result_id) = 0;
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index 97f45a0..0d2fe17 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -106,11 +106,9 @@ controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>( profile, list_controller)); - if (app_list_features::IsAssistantSearchEnabled()) { - size_t assistant_group_id = controller->AddGroup(kMaxAssistantTextResults); - controller->AddProvider(assistant_group_id, - std::make_unique<AssistantTextSearchProvider>()); - } + size_t assistant_group_id = controller->AddGroup(kMaxAssistantTextResults); + controller->AddProvider(assistant_group_id, + std::make_unique<AssistantTextSearchProvider>()); // File search providers are added only when not in guest session and running // on Chrome OS.
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.cc b/chrome/browser/ui/app_list/search/search_controller_impl.cc index d79267d..84f769f 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl.cc
@@ -136,9 +136,8 @@ providers_.emplace_back(std::move(provider)); } -void SearchControllerImpl::SetResults( - const ash::AppListSearchResultType provider_type, - Results results) { +void SearchControllerImpl::SetResults(const SearchProvider* provider, + Results results) { // Should only be called when IsCategoricalSearchEnabled is true. NOTREACHED(); }
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.h b/chrome/browser/ui/app_list/search/search_controller_impl.h index ab59286..65a7c96eb 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl.h
@@ -63,8 +63,7 @@ size_t AddGroup(size_t max_results) override; void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider) override; - void SetResults(ash::AppListSearchResultType provider_type, - Results results) override; + void SetResults(const SearchProvider* provider, Results results) override; ChromeSearchResult* FindSearchResult(const std::string& result_id) override; ChromeSearchResult* GetResultByTitleForTest( const std::string& title) override;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc index c9cb625..c2807a9 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -53,26 +53,38 @@ SearchControllerImplNew::~SearchControllerImplNew() {} void SearchControllerImplNew::StartSearch(const std::u16string& query) { - session_start_ = base::Time::Now(); - // For query searches, begin the burn-in timer. if (!query.empty()) { - burn_in_timer_.Start( - FROM_HERE, burnin_period_, - base::BindOnce(&SearchControllerImplNew::RankAndPublish, - base::Unretained(this), absl::nullopt)); + burn_in_timer_.Start(FROM_HERE, burnin_period_, + base::BindOnce(&SearchControllerImplNew::Publish, + base::Unretained(this))); } + // Cancel a pending zero-state publish if it exists. + zero_state_timeout_.Stop(); + // TODO(crbug.com/1199206): We should move this histogram logic somewhere // else. ash::RecordLauncherIssuedSearchQueryLength(query.length()); - last_query_ = query; + // Clear all results. + // - If the search is transitioning out of zero-state, clear the model updater + // so that old results are never shown. + // - Otherwise, do not publish this clear so that the results for the last + // query remain on-screen until the results are ready. results_.clear(); categories_ = CreateAllCategories(); + if (last_query_.empty()) + model_updater_->ClearSearchResults(); for (Observer& observer : observer_list_) observer.OnResultsCleared(); + burnin_iteration_counter_ = 0; + ids_to_burnin_iteration_.clear(); + + session_start_ = base::Time::Now(); + last_query_ = query; + ranker_->Start(query, results_, categories_); // Search all providers. The query can be empty if the user has entered and @@ -88,11 +100,39 @@ void SearchControllerImplNew::StartZeroState(base::OnceClosure on_done, base::TimeDelta timeout) { + // Cancel a pending search publish if it exists. + burn_in_timer_.Stop(); + + results_.clear(); // Categories currently are not used by zero-state, but may be required for // sorting in SetResults. categories_ = CreateAllCategories(); - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, std::move(on_done), timeout); + for (Observer& observer : observer_list_) + observer.OnResultsCleared(); + + last_query_.clear(); + + ranker_->Start(std::u16string(), results_, categories_); + + on_zero_state_done_ = std::move(on_done); + returned_zero_state_blockers_ = 0; + for (const auto& provider : providers_) + provider->StartZeroState(); + + zero_state_timeout_.Start( + FROM_HERE, timeout, + base::BindOnce(&SearchControllerImplNew::OnZeroStateTimedOut, + base::Unretained(this))); +} + +void SearchControllerImplNew::OnZeroStateTimedOut() { + // This will be nullopt if all zero-state blocking providers have returned. If + // it isn't, publish whatever results have been returned. + if (on_zero_state_done_.has_value()) { + Publish(); + std::move(on_zero_state_done_.value()).Run(); + on_zero_state_done_.reset(); + } } void SearchControllerImplNew::OpenResult(ChromeSearchResult* result, @@ -156,65 +196,97 @@ void SearchControllerImplNew::AddProvider( size_t group_id, std::unique_ptr<SearchProvider> provider) { + if (provider->ShouldBlockZeroState()) + ++total_zero_state_blockers_; provider->set_controller(this); providers_.emplace_back(std::move(provider)); } -void SearchControllerImplNew::SetResults( - const ash::AppListSearchResultType provider_type, - Results results) { +void SearchControllerImplNew::SetResults(const SearchProvider* provider, + Results results) { // Re-post onto the UI sequence if not called from there. auto ui_thread = content::GetUIThreadTaskRunner({}); if (!ui_thread->RunsTasksInCurrentSequence()) { - ui_thread->PostTask(FROM_HERE, - base::BindOnce(&SearchControllerImplNew::SetResults, - base::Unretained(this), provider_type, - std::move(results))); + ui_thread->PostTask( + FROM_HERE, + base::BindOnce(&SearchControllerImplNew::SetResults, + base::Unretained(this), provider, std::move(results))); return; } - results_[provider_type] = std::move(results); - - // If the burn-in period has not yet elapsed, don't call - // RankAndPublish here. This case is covered by a call scheduled - // from within Start(). - // TODO(crbug.com/1199206): Refactor SetResults to split into query search / - // zero state pathways, and remove burn-in period from zero state. - if (base::Time::Now() - session_start_ > burnin_period_) { - RankAndPublish(provider_type); + results_[provider->ResultType()] = std::move(results); + if (last_query_.empty()) { + SetZeroStateResults(provider); + } else { + SetSearchResults(provider); } } -void SearchControllerImplNew::RankAndPublish( - const absl::optional<ash::AppListSearchResultType> provider_type) { - DCHECK(ranker_); +void SearchControllerImplNew::SetSearchResults(const SearchProvider* provider) { + Rank(provider->ResultType()); - // TODO(crbug.com/1199206): Refactor RankAndPublish to split into query search - // / zero state pathways, and remove burn-in period from zero state. + // From here below is logic concerning the burn-in period. + const bool is_post_burnin = + base::Time::Now() - session_start_ > burnin_period_; + if (is_post_burnin) + ++burnin_iteration_counter_; + + const auto it = results_.find(provider->ResultType()); + DCHECK(it != results_.end()); + + for (const auto& result : it->second) { + const std::string result_id = result->id(); + if (ids_to_burnin_iteration_.find(result_id) != + ids_to_burnin_iteration_.end()) { + // Result has been seen before. Set burnin_iteration, since the result + // object has changed since last seen. + result->scoring().burnin_iteration = ids_to_burnin_iteration_[result_id]; + } else { + result->scoring().burnin_iteration = burnin_iteration_counter_; + ids_to_burnin_iteration_[result_id] = burnin_iteration_counter_; + } + } + + // If the burn-in period has not yet elapsed, don't call Publish here. This + // case is covered by a call scheduled from within Start(). + if (is_post_burnin) + Publish(); +} + +void SearchControllerImplNew::SetZeroStateResults( + const SearchProvider* provider) { + Rank(provider->ResultType()); + + if (provider->ShouldBlockZeroState()) + ++returned_zero_state_blockers_; + + if (!on_zero_state_done_) { + // Zero-state has been unblocked, publish immediately. + Publish(); + } else if (returned_zero_state_blockers_ == total_zero_state_blockers_) { + // All zero-state blockers have returned. Publish everything received so + // far, and trigger the on-done callback. + Publish(); + std::move(on_zero_state_done_.value()).Run(); + on_zero_state_done_.reset(); + } +} + +void SearchControllerImplNew::Rank(ash::AppListSearchResultType provider_type) { + DCHECK(ranker_); if (results_.empty()) { // Happens if the burn-in period has elapsed without any results having been // received from providers. Return early. return; } - if (!provider_type.has_value()) { - // Update ranking of all results and categories for all providers which - // have returned results. - for (const auto& type_results : results_) { - // This ordering is important, as result scores may affect category - // scores. - // TODO(crbug.com/1199206): Look into whether UpdateCategoryRanks needs to - // be run more than once. - ranker_->UpdateResultRanks(results_, type_results.first); - ranker_->UpdateCategoryRanks(results_, categories_, type_results.first); - } - } else { - // Update ranking of all results and categories for this provider. This - // ordering is important, as result scores may affect category scores. - ranker_->UpdateResultRanks(results_, *provider_type); - ranker_->UpdateCategoryRanks(results_, categories_, *provider_type); - } + // Update ranking of all results and categories for this provider. This + // ordering is important, as result scores may affect category scores. + ranker_->UpdateResultRanks(results_, provider_type); + ranker_->UpdateCategoryRanks(results_, categories_, provider_type); +} +void SearchControllerImplNew::Publish() { // Sort categories and create a vector of category enums in display order. std::sort(categories_.begin(), categories_.end(), [](const auto& a, const auto& b) { return a.score > b.score; }); @@ -269,6 +341,19 @@ // in |categories_|. NOTREACHED(); return false; + } else if (a->scoring().burnin_iteration != + b->scoring().burnin_iteration) { + // Next, sort by burn-in iteration number. This has no effect on + // results which arrive pre-burn-in. For post-burn-in results + // for a given category, later-arriving results are placed below + // earlier-arriving results. + // This happens before sorting on display_score, as a trade-off + // between ranking accuracy and UX pop-in mitigation. + // + // TODO(crbug.com/1279686): Special case handling for special + // categories such as Best Match. + return a->scoring().burnin_iteration < + b->scoring().burnin_iteration; } else { // Lastly, sort by display score. return a->display_score() > b->display_score();
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.h b/chrome/browser/ui/app_list/search/search_controller_impl_new.h index a14d9c4..8afd37e 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.h
@@ -13,6 +13,7 @@ #include <vector> #include "base/callback.h" +#include "base/containers/flat_map.h" #include "base/observer_list.h" #include "base/timer/timer.h" #include "chrome/browser/ui/app_list/search/mixer.h" @@ -64,8 +65,7 @@ size_t AddGroup(size_t max_results) override; void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider) override; - void SetResults(ash::AppListSearchResultType provider_type, - Results results) override; + void SetResults(const SearchProvider* provider, Results results) override; ChromeSearchResult* FindSearchResult(const std::string& result_id) override; ChromeSearchResult* GetResultByTitleForTest( const std::string& title) override; @@ -90,15 +90,42 @@ } private: - void RankAndPublish( - const absl::optional<ash::AppListSearchResultType> provider_type); + friend class SearchControllerImplNewTest; + + // Rank the results of |provider_type|. + void Rank(ash::AppListSearchResultType provider_type); + + // Publish results to ash. + void Publish(); + + void SetSearchResults(const SearchProvider* provider); + + void SetZeroStateResults(const SearchProvider* provider); + + void OnZeroStateTimedOut(); Profile* profile_; // The query associated with the most recent search. std::u16string last_query_; - // The time when Start was most recently called. + // How many search providers should block zero-state until they return + // results. + int total_zero_state_blockers_ = 0; + + // How many zero-state blocking providers have returned for this search. + int returned_zero_state_blockers_ = 0; + + // A timer to trigger a Publish at the end of the timeout period passed to + // StartZeroState. + base::OneShotTimer zero_state_timeout_; + + // The callback to indicate zero-state should be published. It is reset after + // calling, and has_value is used as a flag for whether zero-state has + // published. + absl::optional<base::OnceClosure> on_zero_state_done_; + + // The time when StartSearch was most recently called. base::Time session_start_; // The ID of the most recently launched app. This is used for app list launch @@ -123,6 +150,29 @@ // updater is delayed until the burn-in period has elapsed. base::OneShotTimer burn_in_timer_; + // Counter for burn-in iterations. Useful for query search only. + // + // Zero signifies pre-burn-in state. After burn-in period has elapsed, counter + // is incremented by one each time SetResults() is called. This information is + // useful because: + // + // (1) It allows post-burn-in results to be ranked by different rules to + // pre-burn-in results, for normal categories as well as special categories + // such as Best Match. + // (2) It allows for sorting stability across multiple post-burn-in result + // updates. + int burnin_iteration_counter_ = 0; + + // Store the ID of each result we encounter in a given query, along with the + // burn-in iteration during which it arrived. This storage is necessary + // because: + // + // Some providers may return more than once, and on each successive return, + // the previous results are swapped for new ones within SetResults(). Result + // meta-information we wish to persist across multiple calls to SetResults + // must therefore be stored separately. + base::flat_map<std::string, int> ids_to_burnin_iteration_; + std::unique_ptr<SearchMetricsObserver> metrics_observer_; using Providers = std::vector<std::unique_ptr<SearchProvider>>; Providers providers_;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc index 498b457..2ee62ce 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc
@@ -10,19 +10,30 @@ #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/test/shell_test_api.h" +#include "base/task/post_task.h" +#include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/ranking/ranker_delegate.h" #include "chrome/browser/ui/app_list/search/search_controller.h" +#include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" #include "chrome/test/base/chrome_ash_test_base.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" namespace app_list { namespace { +// TODO(crbug.com/1258415): Since we have a lot of class fakes now, we should +// generalize them and split them into a test utils directory. + +using testing::ElementsAreArray; +using testing::UnorderedElementsAreArray; using Category = ash::AppListSearchResultCategory; +using Result = ash::AppListSearchResultType; class TestSearchResult : public ChromeSearchResult { public: @@ -45,6 +56,51 @@ void Open(int event_flags) override { NOTIMPLEMENTED(); } }; +class TestSearchProvider : public SearchProvider { + public: + TestSearchProvider(ash::AppListSearchResultType result_type, + bool block_zero_state, + base::TimeDelta delay) + : result_type_(result_type), + block_zero_state_(block_zero_state), + delay_(delay) {} + + ~TestSearchProvider() override = default; + + void SetNextResults( + std::vector<std::unique_ptr<ChromeSearchResult>> results) { + results_ = std::move(results); + } + + bool ShouldBlockZeroState() const override { return block_zero_state_; } + + ash::AppListSearchResultType ResultType() const override { + return result_type_; + } + + void Start(const std::u16string& query) override { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&TestSearchProvider::SetResults, base::Unretained(this)), + delay_); + } + + void StartZeroState() override { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&TestSearchProvider::SetResults, base::Unretained(this)), + delay_); + } + + private: + void SetResults() { SwapResults(&results_); } + + std::vector<std::unique_ptr<ChromeSearchResult>> results_; + ash::AppListSearchResultType result_type_; + bool block_zero_state_; + base::TimeDelta delay_; +}; + // A test ranker delegate that circumvents all result rankings, and hardcodes // category ranking. class TestRankerDelegate : public RankerDelegate { @@ -100,6 +156,15 @@ return results; } +// Returns a pointer to a search provider. Only valid until the next call to +// SimpleProvider. +static std::unique_ptr<SearchProvider> kProvider; +SearchProvider* SimpleProvider(ash::AppListSearchResultType result_type) { + kProvider = std::make_unique<TestSearchProvider>(result_type, false, + base::Seconds(0)); + return kProvider.get(); +} + } // namespace class SearchControllerImplNewTest : public testing::Test { @@ -126,11 +191,28 @@ std::move(ranker_delegate)); } - void ExpectIdOrder(std::vector<std::string> id_order) { - const auto& sorted_results = model_updater_.search_results(); - ASSERT_EQ(sorted_results.size(), id_order.size()); - for (size_t i = 0; i < sorted_results.size(); ++i) - EXPECT_EQ(sorted_results[i]->id(), id_order[i]); + void ExpectIdOrder(std::vector<std::string> expected_ids) { + const auto& actual_results = model_updater_.search_results(); + ASSERT_EQ(actual_results.size(), expected_ids.size()); + std::vector<std::string> actual_ids; + std::transform(actual_results.begin(), actual_results.end(), + std::back_inserter(actual_ids), + [](const ChromeSearchResult* res) -> const std::string& { + return res->id(); + }); + EXPECT_THAT(actual_ids, ElementsAreArray(expected_ids)); + } + + void ExpectIdsToBurnInIterations(std::vector<std::pair<std::string, int>> + expected_ids_to_burnin_iteration) { + const auto& actual_ids_to_burnin_iteration = + std::vector<std::pair<std::string, int>>( + search_controller_->ids_to_burnin_iteration_.begin(), + search_controller_->ids_to_burnin_iteration_.end()); + ASSERT_EQ(actual_ids_to_burnin_iteration.size(), + expected_ids_to_burnin_iteration.size()); + EXPECT_THAT(actual_ids_to_burnin_iteration, + UnorderedElementsAreArray(expected_ids_to_burnin_iteration)); } void Wait() { task_environment_.RunUntilIdle(); } @@ -164,11 +246,11 @@ search_controller_->StartSearch(u"abc"); ElapseBurnInPeriod(); // Simulate several providers returning results. - search_controller_->SetResults(ash::AppListSearchResultType::kOmnibox, + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), std::move(web_results)); - search_controller_->SetResults(ash::AppListSearchResultType::kInstalledApp, + search_controller_->SetResults(SimpleProvider(Result::kInstalledApp), std::move(app_results)); - search_controller_->SetResults(ash::AppListSearchResultType::kFileSearch, + search_controller_->SetResults(SimpleProvider(Result::kFileSearch), std::move(file_results)); ExpectIdOrder({"a", "b", "c", "d", "e"}); @@ -189,26 +271,76 @@ // Simulate a provider returning and containing all of the above results. A // single provider wouldn't return many results like this, but that's // unimportant for the test. - search_controller_->SetResults(ash::AppListSearchResultType::kOmnibox, + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), std::move(results)); ExpectIdOrder({"a", "c", "d", "b"}); } -TEST_F(SearchControllerImplNewTest, SetResultsPreAndPostBurnIn) { +TEST_F(SearchControllerImplNewTest, + BurnInIterationNumbersTrackedInQuerySearch) { + // This test focuses on the book-keeping of burn-in iteration numbers, and + // ignores the effect that these numbers can have on final sorting of the + // results list. + + ranker_delegate_->SetCategoryRanks({{Category::kFiles, 0.1}}); + + // Set up some results from two different providers. + auto file_results = MakeResults({"a"}, {Category::kFiles}, {false}, {0.9}); + auto app_results = MakeResults({"b"}, {Category::kApps}, {false}, {0.1}); + + // Set up results from a third different provider. This provider will first + // return one set of results, then later return an updated set of results. + auto web_results_first_arrival = MakeResults( + {"c", "d"}, {Category::kWeb, Category::kWeb}, {false, false}, {0.2, 0.1}); + auto web_results_second_arrival = MakeResults( + {"c", "d", "e"}, {Category::kWeb, Category::kWeb, Category::kWeb}, + {false, false, false}, {0.2, 0.1, 0.4}); + + // Simulate starting a search. + search_controller_->StartSearch(u"abc"); + + // Simulate providers returning results within the burn-in period. + search_controller_->SetResults(SimpleProvider(Result::kFileSearch), + std::move(file_results)); + ExpectIdsToBurnInIterations({{"a", 0}}); + search_controller_->SetResults(SimpleProvider(Result::kInstalledApp), + std::move(app_results)); + ExpectIdsToBurnInIterations({{"a", 0}, {"b", 0}}); + + // Simulate a provider returning results after the burn-in period. + ElapseBurnInPeriod(); + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), + std::move(web_results_first_arrival)); + ExpectIdsToBurnInIterations({{"a", 0}, {"b", 0}, {"c", 1}, {"d", 1}}); + + // Simulate a provider returning for a second time. The burn-in iteration + // number for previously seen results is preserved, while that of newly seen + // results is incremented. + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), + std::move(web_results_second_arrival)); + ExpectIdsToBurnInIterations( + {{"a", 0}, {"b", 0}, {"c", 1}, {"d", 1}, {"e", 2}}); +} + +TEST_F(SearchControllerImplNewTest, + SetResultsPreAndPostBurnIn_OneProviderReturnPerCategory) { + // When there is only a single provider return per final category, we do not + // expect there to be any effect from sorting by burn-in iteration number. + ranker_delegate_->SetCategoryRanks( {{Category::kFiles, 0.3}, {Category::kWeb, 0.2}, {Category::kApps, 0.1}}); auto file_results = MakeResults({"a"}, {Category::kFiles}, {false}, {0.9}); auto web_results = MakeResults( {"c", "d", "b"}, {Category::kWeb, Category::kWeb, Category::kWeb}, - {false, false, false}, {0.2, 0.1, 0.4}); + {false, false, false}, {0.3, 0.2, 0.4}); auto app_results = MakeResults({"e"}, {Category::kApps}, {false}, {0.1}); // Simulate starting a search. search_controller_->StartSearch(u"abc"); // Simulate a provider returning results within the burn-in period. - search_controller_->SetResults(ash::AppListSearchResultType::kOmnibox, + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), std::move(web_results)); ExpectIdOrder({}); @@ -217,12 +349,210 @@ ExpectIdOrder({"b", "c", "d"}); // Simulate several providers returning results after the burn-in period. - search_controller_->SetResults(ash::AppListSearchResultType::kInstalledApp, + search_controller_->SetResults(SimpleProvider(Result::kInstalledApp), std::move(app_results)); ExpectIdOrder({"b", "c", "d", "e"}); - search_controller_->SetResults(ash::AppListSearchResultType::kFileSearch, + search_controller_->SetResults(SimpleProvider(Result::kFileSearch), std::move(file_results)); ExpectIdOrder({"a", "b", "c", "d", "e"}); } +TEST_F(SearchControllerImplNewTest, + SetResultsPreAndPostBurnIn_SingleProviderReturnsMultipleTimes) { + ranker_delegate_->SetCategoryRanks({{Category::kWeb, 0.2}}); + auto web_results_1 = MakeResults( + {"b", "c", "a"}, {Category::kWeb, Category::kWeb, Category::kWeb}, + {false, false, false}, {0.2, 0.1, 0.3}); + + auto web_results_2 = MakeResults( + {"b", "c", "a", "d"}, + {Category::kWeb, Category::kWeb, Category::kWeb, Category::kWeb}, + {false, false, false}, {0.2, 0.1, 0.3, 0.4}); + + auto web_results_3 = + MakeResults({"b", "c", "a", "d", "e"}, + {Category::kWeb, Category::kWeb, Category::kWeb, + Category::kWeb, Category::kWeb}, + {false, false, false}, {0.2, 0.1, 0.3, 0.4, 0.5}); + + // Simulate starting a search. + search_controller_->StartSearch(u"abc"); + + // Simulate the provider returning results within the burn-in period. + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), + std::move(web_results_1)); + ExpectIdOrder({}); + + // Expect results to appear after burn-in period has elapsed. + ElapseBurnInPeriod(); + ExpectIdOrder({"a", "b", "c"}); + + // When a single provider returns multiple times for a category, sorting by + // burn-in iteration number takes precedence over sorting by result score. + // + // Simulate the provider returning results twice after the burn-in period. + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), + std::move(web_results_2)); + ExpectIdOrder({"a", "b", "c", "d"}); + search_controller_->SetResults(SimpleProvider(Result::kOmnibox), + std::move(web_results_3)); + ExpectIdOrder({"a", "b", "c", "d", "e"}); +} + +TEST_F(SearchControllerImplNewTest, + SetResultsPreAndPostBurnIn_MultipleProvidersReturnToSingleCategory) { + ranker_delegate_->SetCategoryRanks({{Category::kWeb, 0.2}}); + + auto installed_app_results = MakeResults( + {"b", "c", "a"}, {Category::kApps, Category::kApps, Category::kApps}, + {false, false, false}, {0.3, 0.2, 0.4}); + + auto play_store_app_results = + MakeResults({"e", "d"}, {Category::kApps, Category::kApps}, + {false, false}, {0.1, 0.5}); + + auto internal_app_results = + MakeResults({"f"}, {Category::kApps}, {false}, {0.9}); + + // Simulate starting a search. + search_controller_->StartSearch(u"abc"); + + // Simulate a provider returning results within the burn-in period. + search_controller_->SetResults(SimpleProvider(Result::kInstalledApp), + std::move(installed_app_results)); + ExpectIdOrder({}); + + // Expect results to appear after burn-in period has elapsed. + ElapseBurnInPeriod(); + ExpectIdOrder({"a", "b", "c"}); + + // When there are multiple providers returning for a category, sorting by + // burn-in iteration number takes precedence over sorting by result score. + // + // Simulate two other providers returning results after the burn-in period. + search_controller_->SetResults(SimpleProvider(Result::kPlayStoreApp), + std::move(play_store_app_results)); + ExpectIdOrder({"a", "b", "c", "d", "e"}); + search_controller_->SetResults(SimpleProvider(Result::kInternalApp), + std::move(internal_app_results)); + ExpectIdOrder({"a", "b", "c", "d", "e", "f"}); +} + +TEST_F(SearchControllerImplNewTest, FirstSearchResultsNotShownInSecondSearch) { + ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); + + auto provider = std::make_unique<TestSearchProvider>(Result::kInstalledApp, + false, base::Seconds(1)); + auto* provider_ptr = provider.get(); + search_controller_->AddProvider(0, std::move(provider)); + + // Start the first search. + provider_ptr->SetNextResults( + MakeResults({"AAA"}, {Category::kApps}, {false}, {0.1})); + search_controller_->StartSearch(u"A"); + ExpectIdOrder({}); + + // Provider has returned and the A result should be published. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({"AAA"}); + + provider_ptr->SetNextResults({}); + search_controller_->StartZeroState(base::DoNothing(), base::Seconds(1)); + task_environment_.FastForwardBy(base::Seconds(1)); + + // Start the second search. + provider_ptr->SetNextResults( + MakeResults({"BBB"}, {Category::kApps}, {false}, {0.1})); + search_controller_->StartSearch(u"B"); + // The B result is not ready yet, and the A result should *not* have been + // published. + ExpectIdOrder({}); + + // Provider has returned and the B result should be published. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({"BBB"}); +} + +TEST_F(SearchControllerImplNewTest, ZeroStateResultsAreBlocked) { + ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); + + // Set up four providers, two are zero-state blocking. One is slow. The + // particular result types and categories don't matter. + auto provider_a = std::make_unique<TestSearchProvider>( + Result::kInstalledApp, true, base::Seconds(1)); + auto provider_b = std::make_unique<TestSearchProvider>( + Result::kZeroStateFile, true, base::Seconds(2)); + auto provider_c = std::make_unique<TestSearchProvider>( + Result::kOsSettings, false, base::Seconds(1)); + auto provider_d = std::make_unique<TestSearchProvider>( + Result::kOmnibox, false, base::Seconds(4)); + + provider_a->SetNextResults( + MakeResults({"a"}, {Category::kApps}, {false}, {0.3})); + provider_b->SetNextResults( + MakeResults({"b"}, {Category::kApps}, {false}, {0.2})); + provider_c->SetNextResults( + MakeResults({"c"}, {Category::kApps}, {false}, {0.1})); + provider_d->SetNextResults( + MakeResults({"d"}, {Category::kApps}, {false}, {0.4})); + + search_controller_->AddProvider(0, std::move(provider_a)); + search_controller_->AddProvider(0, std::move(provider_b)); + search_controller_->AddProvider(0, std::move(provider_c)); + search_controller_->AddProvider(0, std::move(provider_d)); + + // Start the zero-state session. When on-done is called, we should have + // results from all but the slowest provider. + search_controller_->StartZeroState(base::BindLambdaForTesting([&]() { + ExpectIdOrder({"a", "b", "c"}); + }), + base::Seconds(3)); + + // The fast provider has returned but shouldn't have published. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({}); + + // Additionally, those three results should be returned before the + // StartZeroState timeout. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({"a", "b", "c"}); + + // The latecomer should still be added when it arrives. + task_environment_.FastForwardBy(base::Seconds(2)); + ExpectIdOrder({"d", "a", "b", "c"}); +} + +TEST_F(SearchControllerImplNewTest, ZeroStateResultsGetTimedOut) { + ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); + + auto provider_a = std::make_unique<TestSearchProvider>( + Result::kInstalledApp, true, base::Seconds(1)); + auto provider_b = std::make_unique<TestSearchProvider>( + Result::kZeroStateFile, true, base::Seconds(3)); + + provider_a->SetNextResults( + MakeResults({"a"}, {Category::kApps}, {false}, {0.3})); + provider_b->SetNextResults( + MakeResults({"b"}, {Category::kFiles}, {false}, {0.2})); + + search_controller_->AddProvider(0, std::move(provider_a)); + search_controller_->AddProvider(0, std::move(provider_b)); + + search_controller_->StartZeroState( + base::BindLambdaForTesting([&]() { ExpectIdOrder({"a"}); }), + base::Seconds(2)); + + // The fast provider has returned but shouldn't have published. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({}); + + // The timeout finished, the fast provider's result should be published. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({"a"}); + + // The slow provider should still publish when it returns. + task_environment_.FastForwardBy(base::Seconds(1)); + ExpectIdOrder({"a", "b"}); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_provider.cc b/chrome/browser/ui/app_list/search/search_provider.cc index 4c219e5..8bb54b5 100644 --- a/chrome/browser/ui/app_list/search/search_provider.cc +++ b/chrome/browser/ui/app_list/search/search_provider.cc
@@ -29,7 +29,7 @@ if (app_list_features::IsCategoricalSearchEnabled()) { Results results; results.swap(*new_results); - search_controller_->SetResults(ResultType(), std::move(results)); + search_controller_->SetResults(this, std::move(results)); } else { results_.swap(*new_results); FireResultChanged(); @@ -56,4 +56,8 @@ result_changed_callback_.Run(); } +bool SearchProvider::ShouldBlockZeroState() const { + return false; +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_provider.h b/chrome/browser/ui/app_list/search/search_provider.h index cf8cedc3..1ebee4d 100644 --- a/chrome/browser/ui/app_list/search/search_provider.h +++ b/chrome/browser/ui/app_list/search/search_provider.h
@@ -46,7 +46,12 @@ // provider to eg. warm up a cache of results. virtual void AppListShown() {} // Returns the main result type created by this provider. - virtual ash::AppListSearchResultType ResultType() = 0; + virtual ash::AppListSearchResultType ResultType() const = 0; + + // Returns true if this provider should prevent zero-state results from being + // published until it has returned. If this is true, a provider should only + // return results once per call to StartZeroState. + virtual bool ShouldBlockZeroState() const; void set_controller(SearchController* controller) { search_controller_ = controller;
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc index 73fe2e6d..0971fef 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -203,6 +203,10 @@ search_results_ = results; } +void FakeAppListModelUpdater::ClearSearchResults() { + search_results_.clear(); +} + void FakeAppListModelUpdater::UpdateAppItemFromSyncItem( app_list::AppListSyncableService::SyncItem* sync_item, bool update_name,
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h index dd9cff2..b6cff49d 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -46,6 +46,7 @@ void PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) override; + void ClearSearchResults() override; void ActivateChromeItem(const std::string& id, int event_flags) override; void LoadAppIcon(const std::string& id) override;
diff --git a/chrome/browser/ui/ash/OWNERS b/chrome/browser/ui/ash/OWNERS index cff11b6a..2a45896 100644 --- a/chrome/browser/ui/ash/OWNERS +++ b/chrome/browser/ui/ash/OWNERS
@@ -12,7 +12,7 @@ per-file *wallpaper*=file://ash/wallpaper/OWNERS per-file *capture_mode*=file://ash/capture_mode/OWNERS per-file recording_service_browsertest.cc=file://ash/capture_mode/OWNERS -per-file thumbnail_loader.*=file://chrome/browser/ui/ash/holding_space/OWNERS +per-file thumbnail_loader*=file://chrome/browser/ui/ash/holding_space/OWNERS # Must be updated when a new OS settings section is added. per-file chrome_new_window_client*=file://chrome/browser/resources/settings/chromeos/OWNERS
diff --git a/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc b/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc new file mode 100644 index 0000000..9cfaaa27 --- /dev/null +++ b/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc
@@ -0,0 +1,206 @@ +// 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 <memory> + +#include "ash/app_list/views/apps_grid_view_test_api.h" +#include "ash/constants/ash_features.h" +#include "ash/public/cpp/accelerators.h" +#include "ash/public/cpp/test/app_list_test_api.h" +#include "ash/root_window_controller.h" +#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/test/browser_test.h" +#include "ui/events/test/event_generator.h" + +class BubbleAppsGridDragBrowserTest : public InProcessBrowserTest { + public: + BubbleAppsGridDragBrowserTest() { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kProductivityLauncher); + } + BubbleAppsGridDragBrowserTest(const BubbleAppsGridDragBrowserTest&) = delete; + BubbleAppsGridDragBrowserTest& operator=( + const BubbleAppsGridDragBrowserTest&) = delete; + ~BubbleAppsGridDragBrowserTest() override = default; + + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + // Ensure that there are enough app items for reordering. + test::PopulateDummyAppListItems(5); + event_generator_ = std::make_unique<ui::test::EventGenerator>( + browser()->window()->GetNativeWindow()->GetRootWindow()); + + // Show the bubble launcher. + ash::AcceleratorController::Get()->PerformActionIfEnabled( + ash::TOGGLE_APP_LIST_FULLSCREEN, {}); + + app_list_test_api()->WaitForBubbleWindow( + /*wait_for_opening_animation=*/true); + root_apps_grid_test_api_ = std::make_unique<ash::test::AppsGridViewTestApi>( + app_list_test_api()->GetTopLevelAppsGridView()); + } + + // Starts mouse drag on the specified view. + void StartAppListItemDrag(ash::AppListItemView* dragged_view) { + event_generator_->MoveMouseTo( + dragged_view->GetBoundsInScreen().CenterPoint()); + event_generator_->PressLeftButton(); + dragged_view->FireMouseDragTimerForTest(); + } + + // Returns a position between a pair of adjacent top level items that are + // assumed to be aligned horizontally. `prev_item_index` indicates the least + // index in the item pair. + gfx::Point CalculatePositionBetweenAdjacentTopLevelItems( + int prev_item_index) { + const gfx::Rect prev_item_bounds_in_screen = + root_apps_grid_test_api_ + ->GetViewAtVisualIndex(/*page=*/0, prev_item_index) + ->GetBoundsInScreen(); + + const views::View* next_view = + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, + prev_item_index + 1); + if (!next_view) { + ADD_FAILURE() << "Item at slot 0, " << prev_item_index + 1 + << " not found"; + return gfx::Point(); + } + const gfx::Rect next_item_bounds_in_screen = next_view->GetBoundsInScreen(); + + EXPECT_EQ(prev_item_bounds_in_screen.y(), next_item_bounds_in_screen.y()); + const int offset = (next_item_bounds_in_screen.OffsetFromOrigin() - + prev_item_bounds_in_screen.OffsetFromOrigin()) + .x(); + const gfx::Point prev_item_center = + prev_item_bounds_in_screen.CenterPoint(); + return gfx::Point(prev_item_center.x() + offset / 2, prev_item_center.y()); + } + + ash::AppListTestApi* app_list_test_api() { return &app_list_test_api_; } + + std::unique_ptr<ui::test::EventGenerator> event_generator_; + std::unique_ptr<ash::test::AppsGridViewTestApi> root_apps_grid_test_api_; + + private: + ash::AppListTestApi app_list_test_api_; + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Verifies that reordering app list items by mouse drag works as expected on +// the bubble apps grid. +IN_PROC_BROWSER_TEST_F(BubbleAppsGridDragBrowserTest, ItemReorderByMouseDrag) { + // Get the top level item ids before any operations. + const std::vector<std::string> default_top_level_ids = + app_list_test_api()->GetTopLevelViewIdList(); + + // Start the mouse drag on the first item. + ash::AppListItemView* dragged_view = + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/0); + StartAppListItemDrag(dragged_view); + + // Move the first item to the location between the second one and the third + // one. + event_generator_->MoveMouseTo( + CalculatePositionBetweenAdjacentTopLevelItems(/*prev_item_index=*/1)); + root_apps_grid_test_api_->FireReorderTimerAndWaitForAnimationDone(); + event_generator_->ReleaseLeftButton(); + + // Verify that after drag-and-drop the first app and the second app swap + // locations. + std::vector<std::string> expected_top_level_ids = default_top_level_ids; + std::swap(expected_top_level_ids[0], expected_top_level_ids[1]); + EXPECT_EQ(expected_top_level_ids, + app_list_test_api()->GetTopLevelViewIdList()); +} + +// Verifies that merging two items into a folder and moving an item out of a +// folder work as expected on the bubble apps grid. +IN_PROC_BROWSER_TEST_F(BubbleAppsGridDragBrowserTest, ItemMerge) { + // Record the item count before any operations. + const size_t default_top_level_item_count = + app_list_test_api()->GetTopLevelViewIdList().size(); + + // Merge the first item with the second one. + StartAppListItemDrag( + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/0)); + event_generator_->MoveMouseTo( + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/1) + ->GetBoundsInScreen() + .CenterPoint()); + event_generator_->ReleaseLeftButton(); + root_apps_grid_test_api_->WaitForItemMoveAnimationDone(); + + // Verify that the top level item count decreases by one. + EXPECT_EQ(default_top_level_item_count - 1, + app_list_test_api()->GetTopLevelViewIdList().size()); + + // Verify that the first item on the top level is a folder. + ash::AppListItemView* folder_item = + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/0); + EXPECT_TRUE(folder_item->is_folder()); + + // Click at the folder item and wait until the animation completes. + event_generator_->MoveMouseTo( + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/0) + ->GetBoundsInScreen() + .CenterPoint()); + base::RunLoop run_loop; + app_list_test_api()->SetFolderViewAnimationCallback(run_loop.QuitClosure()); + event_generator_->ClickLeftButton(); + run_loop.Run(); + + // Verify that the folder view animation ends. + EXPECT_FALSE(app_list_test_api()->IsFolderViewAnimating()); + + // Verify that the folder apps grid contains two items. + ash::AppsGridView* folder_apps_grid_view = + app_list_test_api()->GetFolderAppsGridView(); + EXPECT_EQ(2u, folder_apps_grid_view->view_model()->view_size()); + + const std::vector<std::string> top_level_ids_after_merging = + app_list_test_api()->GetTopLevelViewIdList(); + + // Start the mouse drag on an item under the folder. + ash::test::AppsGridViewTestApi folder_apps_grid_test_api( + folder_apps_grid_view); + ash::AppListItemView* dragged_view = + folder_apps_grid_test_api.GetViewAtVisualIndex(/*page=*/0, /*slot=*/1); + const std::string dragged_app_id = dragged_view->item()->id(); + StartAppListItemDrag(dragged_view); + + // Move the dragged item in two steps to ensure that the reordering animation + // in the top level apps grid is triggered: + // Step 1: move the dragged item upon a top level item then fire the + // reparenting timer. + // Step 2: move the dragged item to the right of a top level item. + event_generator_->MoveMouseTo( + root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/1) + ->GetBoundsInScreen() + .CenterPoint()); + folder_apps_grid_test_api.FireFolderItemReparentTimer(); + event_generator_->MoveMouseTo( + CalculatePositionBetweenAdjacentTopLevelItems(/*prev_item_index=*/1)); + root_apps_grid_test_api_->FireReorderTimerAndWaitForAnimationDone(); + event_generator_->ReleaseLeftButton(); + + // Calculate the expected top level item ids after moving `dragged_view` out + // of the parent folder. `dragged_view` should be inserted at the third slot. + std::vector<std::string> expected_top_level_ids = top_level_ids_after_merging; + expected_top_level_ids.insert(expected_top_level_ids.begin() + 2, + dragged_app_id); + + const std::vector<std::string> final_top_level_ids = + app_list_test_api()->GetTopLevelViewIdList(); + EXPECT_EQ(expected_top_level_ids, final_top_level_ids); + + // Verify that after reparenting the top level item count is equal to the + // default value. + EXPECT_EQ(default_top_level_item_count, final_top_level_ids.size()); +}
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc index f139012..ab37be4 100644 --- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc +++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
@@ -16,6 +16,7 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/apps/icon_standardizer.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -33,6 +34,7 @@ #include "components/app_restore/restore_data.h" #include "components/app_restore/window_properties.h" #include "components/favicon/core/favicon_service.h" +#include "components/favicon_base/favicon_util.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/types_util.h" @@ -57,10 +59,6 @@ constexpr char kAppNotAvailableTemplateToastName[] = "AppNotAvailableTemplateToast"; -// The amount of time for which the launch template toasts will remain -// displayed. -constexpr int kLaunchTemplateToastDurationMs = 6 * 1000; - // Returns the TabStripModel that associates with `window` if the given `window` // contains a browser frame, otherwise returns nullptr. TabStripModel* GetTabstripModelForWindowIfAny(aura::Window* window) { @@ -146,12 +144,42 @@ } ash::ToastData toast_data = {/*id=*/kAppNotAvailableTemplateToastName, - /*text=*/ - toast_string, kLaunchTemplateToastDurationMs, - /*dismiss_text=*/absl::nullopt}; + /*text=*/toast_string}; ash::ToastManager::Get()->Show(toast_data); } +// Creates a callback for when a favicon image is retrieved which creates a +// standard icon image and then calls `callback` with the standardized image. +base::OnceCallback<void(const favicon_base::FaviconImageResult&)> +ImageResultToImageSkia( + base::OnceCallback<void(const gfx::ImageSkia&)> callback) { + return base::BindOnce( + [](base::OnceCallback<void(const gfx::ImageSkia&)> image_skia_callback, + const favicon_base::FaviconImageResult& result) { + auto image = result.image.AsImageSkia(); + image.EnsureRepsForSupportedScales(); + std::move(image_skia_callback) + .Run(apps::CreateStandardIconImage(image)); + }, + std::move(callback)); +} + +// Creates a callback for when a app icon image is retrieved which creates a +// standard icon image and then calls `callback` with the standardized image. +base::OnceCallback<void(apps::IconValuePtr icon_value)> +AppIconResultToImageSkia( + base::OnceCallback<void(const gfx::ImageSkia&)> callback) { + return base::BindOnce( + [](base::OnceCallback<void(const gfx::ImageSkia&)> image_skia_callback, + apps::IconValuePtr icon_value) { + auto image = icon_value->uncompressed; + image.EnsureRepsForSupportedScales(); + std::move(image_skia_callback) + .Run(apps::CreateStandardIconImage(image)); + }, + std::move(callback)); +} + } // namespace ChromeDesksTemplatesDelegate::ChromeDesksTemplatesDelegate() = default; @@ -262,41 +290,41 @@ void ChromeDesksTemplatesDelegate::GetFaviconForUrl( const std::string& page_url, - int desired_icon_size, - favicon_base::FaviconRawBitmapCallback callback, + base::OnceCallback<void(const gfx::ImageSkia&)> callback, base::CancelableTaskTracker* tracker) const { favicon::FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( ProfileManager::GetActiveUserProfile(), ServiceAccessType::EXPLICIT_ACCESS); - favicon_service->GetRawFaviconForPageURL( - GURL(page_url), {favicon_base::IconType::kFavicon}, desired_icon_size, - /*fallback_to_host=*/false, std::move(callback), tracker); + favicon_service->GetFaviconImageForPageURL( + GURL(page_url), ImageResultToImageSkia(std::move(callback)), tracker); } void ChromeDesksTemplatesDelegate::GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) const { + base::OnceCallback<void(const gfx::ImageSkia&)> callback) const { auto* app_service_proxy = apps::AppServiceProxyFactory::GetForProfile( ProfileManager::GetActiveUserProfile()); if (!app_service_proxy) { - std::move(callback).Run(std::make_unique<apps::IconValue>()); + std::move(callback).Run(gfx::ImageSkia()); return; } auto app_type = app_service_proxy->AppRegistryCache().GetAppType(app_id); if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { - app_service_proxy->LoadIcon( - apps::ConvertMojomAppTypToAppType(app_type), app_id, - apps::IconType::kStandard, desired_icon_size, - /*allow_placeholder_icon=*/false, std::move(callback)); + app_service_proxy->LoadIcon(apps::ConvertMojomAppTypToAppType(app_type), + app_id, apps::IconType::kStandard, + desired_icon_size, + /*allow_placeholder_icon=*/false, + AppIconResultToImageSkia(std::move(callback))); } else { app_service_proxy->LoadIcon( app_type, app_id, apps::mojom::IconType::kStandard, desired_icon_size, /*allow_placeholder_icon=*/false, - apps::MojomIconValueToIconValueCallback(std::move(callback))); + apps::MojomIconValueToIconValueCallback( + AppIconResultToImageSkia(std::move(callback)))); } }
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h index 052ee698..1082f4b 100644 --- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h +++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h
@@ -9,13 +9,17 @@ #include "ash/public/cpp/desks_templates_delegate.h" #include "base/callback_forward.h" -#include "components/favicon_base/favicon_callback.h" +#include "components/favicon_base/favicon_types.h" #include "components/services/app_service/public/cpp/icon_types.h" namespace base { class CancelableTaskTracker; } // namespace base +namespace gfx { +class ImageSkia; +} // namespace gfx + class ChromeDesksTemplatesDelegate : public ash::DesksTemplatesDelegate { public: ChromeDesksTemplatesDelegate(); @@ -32,14 +36,14 @@ absl::optional<gfx::ImageSkia> MaybeRetrieveIconForSpecialIdentifier( const std::string& identifier, const ui::ColorProvider* color_provider) const override; - void GetFaviconForUrl(const std::string& page_url, - int desired_icon_size, - favicon_base::FaviconRawBitmapCallback callback, - base::CancelableTaskTracker* tracker) const override; - void GetIconForAppId(const std::string& app_id, - int desired_icon_size, - base::OnceCallback<void(apps::IconValuePtr icon_value)> - callback) const override; + void GetFaviconForUrl( + const std::string& page_url, + base::OnceCallback<void(const gfx::ImageSkia&)> callback, + base::CancelableTaskTracker* tracker) const override; + void GetIconForAppId( + const std::string& app_id, + int desired_icon_size, + base::OnceCallback<void(const gfx::ImageSkia&)> callback) const override; void LaunchAppsFromTemplate( std::unique_ptr<ash::DeskTemplate> desk_template) override; bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc index 64c2657..bdd5bb827 100644 --- a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc +++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
@@ -31,7 +31,8 @@ DesksTemplatesClient* g_desks_templates_client_instance = nullptr; -// Histogram names +// TODO(https://crbug.com/1284774): Remove metrics from this file. +// Histogram names. constexpr char kWindowCountHistogramName[] = "Ash.DeskTemplate.WindowCount"; constexpr char kTabCountHistogramName[] = "Ash.DeskTemplate.TabCount"; constexpr char kWindowAndTabCountHistogramName[] =
diff --git a/chrome/browser/ui/ash/media_client_impl.cc b/chrome/browser/ui/ash/media_client_impl.cc index e389d90..ea9448a 100644 --- a/chrome/browser/ui/ash/media_client_impl.cc +++ b/chrome/browser/ui/ash/media_client_impl.cc
@@ -105,10 +105,6 @@ constexpr char kCameraPrivacySwitchOffToastId[] = "ash.media.camera.privacy_switch_off"; -// The amount of time for which the camera privacy switch toasts will remain -// displayed. -constexpr int kCameraPrivacySwitchToastDurationMs = 6 * 1000; - MediaCaptureState& operator|=(MediaCaptureState& lhs, MediaCaptureState rhs) { lhs = static_cast<MediaCaptureState>(static_cast<int>(lhs) | static_cast<int>(rhs)); @@ -402,8 +398,7 @@ ash::ToastData toast( kCameraPrivacySwitchOnToastId, l10n_util::GetStringUTF16(IDS_CAMERA_PRIVACY_SWITCH_ON_TOAST), - kCameraPrivacySwitchToastDurationMs, - /*dismiss_text=*/absl::nullopt, + ash::ToastData::kDefaultToastDurationMs, /*visible_on_lock_screen=*/true); ash::ToastManager::Get()->Show(toast); break; @@ -438,8 +433,7 @@ ash::ToastData toast( kCameraPrivacySwitchOffToastId, l10n_util::GetStringUTF16(IDS_CAMERA_PRIVACY_SWITCH_OFF_TOAST), - kCameraPrivacySwitchToastDurationMs, - /*dismiss_text=*/absl::nullopt, + ash::ToastData::kDefaultToastDurationMs, /*visible_on_lock_screen=*/true); ash::ToastManager::Get()->Show(toast); break;
diff --git a/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc index 44c2a2d4..081ea989 100644 --- a/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc +++ b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc
@@ -102,6 +102,8 @@ } void ProjectorSodaInstallationController::OnSodaError() { + projector_controller_->OnSpeechRecognitionAvailabilityChanged( + ash::SpeechRecognitionAvailability::kSodaInstallationError); app_client_->OnSodaInstallError(); }
diff --git a/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc b/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc index 8822e69..0a990ba 100644 --- a/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc +++ b/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc
@@ -95,6 +95,9 @@ } MockAppClient& app_client() { return *mock_app_client_; } + MockProjectorController& projector_controller() { + return *mock_projector_controller_; + } ProjectorSodaInstallationController* soda_installation_controller() { return soda_installation_controller_.get(); @@ -166,6 +169,10 @@ TEST_F(ProjectorSodaInstallationControllerTest, OnSodaInstallError) { SetLocale(kEnglishLocale); EXPECT_CALL(app_client(), OnSodaInstallError()).Times(1); + EXPECT_CALL(projector_controller(), + OnSpeechRecognitionAvailabilityChanged( + ash::SpeechRecognitionAvailability::kSodaInstallationError)) + .Times(1); speech::SodaInstaller::GetInstance()->NotifySodaErrorForTesting(); }
diff --git a/chrome/browser/ui/ash/thumbnail_loader.cc b/chrome/browser/ui/ash/thumbnail_loader.cc index 1c74be2..1adfd37d 100644 --- a/chrome/browser/ui/ash/thumbnail_loader.cc +++ b/chrome/browser/ui/ash/thumbnail_loader.cc
@@ -26,11 +26,13 @@ #include "extensions/common/api/messaging/serialization_format.h" #include "extensions/common/extension.h" #include "net/base/data_url.h" +#include "net/base/mime_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/data_decoder/public/cpp/data_decoder.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "storage/browser/file_system/file_system_context.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/re2/src/re2/re2.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -45,6 +47,132 @@ // loader extension. constexpr char kNativeMessageHostName[] = "com.google.ash_thumbnail_loader"; +// Returns whether the given `file_path` is supported by the `ThumbnailLoader`. +bool IsSupported(const base::FilePath& file_path) { + constexpr std::array<std::pair<const char*, const char*>, 24> + kFileMatchPatterns = {{ + // Document types ---------------------------------------------------- + { + /*extension=*/"(?i)\\.pdf$", + /*mime_type=*/"(?i)application\\/pdf", + }, + // Image types ------------------------------------------------------- + { + /*extension=*/"(?i)\\.jpe?g$", + /*mime_type=*/"(?i)image\\/jpeg", + }, + { + /*extension=*/"(?i)\\.bmp$", + /*mime_type=*/"(?i)image\\/bmp", + }, + { + /*extension=*/"(?i)\\.gif$", + /*mime_type=*/"(?i)image\\/gif", + }, + { + /*extension=*/"(?i)\\.ico$", + /*mime_type=*/"(?i)image\\/x\\-icon", + }, + { + /*extension=*/"(?i)\\.png$", + /*mime_type=*/"(?i)image\\/png", + }, + { + /*extension=*/"(?i)\\.webp$", + /*mime_type=*/"(?i)image\\/webp", + }, + { + /*extension=*/"(?i)\\.tiff?$", + /*mime_type=*/"(?i)image\\/tiff", + }, + { + /*extension=*/"(?i)\\.svg$", + /*mime_type=*/"(?i)image\\/svg\\+xml", + }, + // Raw types --------------------------------------------------------- + { + /*extension=*/"(?i)\\.arw$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.cr2$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.dng$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.nef$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.nrw$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.orf$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.raf$", + /*mime_type=*/nullptr, + }, + { + /*extension=*/"(?i)\\.rw2$", + /*mime_type=*/nullptr, + }, + // Video types ------------------------------------------------------- + { + /*extension=*/"(?i)\\.3gpp?$", + /*mime_type=*/"(?i)video\\/3gpp", + }, + { + /*extension=*/"(?i)\\.avi$", + /*mime_type=*/"(?i)video\\/x\\-msvideo", + }, + { + /*extension=*/"(?i)\\.mov$", + /*mime_type=*/"(?i)video\\/quicktime", + }, + { + /*extension=*/"\\.mkv$", + /*mime_type=*/"video\\/x\\-matroska", + }, + { + /*extension=*/"(?i)\\.m(p4|4v|pg|peg|pg4|peg4)$", + /*mime_type=*/"(?i)video\\/mp(4|eg)", + }, + { + /*extension=*/"(?i)\\.og(m|v|x)$", + /*mime_type=*/"(?i)(application|video)\\/ogg", + }, + { + /*extension=*/"(?i)\\.webm$", + /*mime_type=*/"(?i)video\\/webm", + }, + }}; + + // First attempt to match based on `mime_type`. + std::string mime_type; + if (net::GetMimeTypeFromFile(file_path, &mime_type)) { + for (const auto& file_match_pattern : kFileMatchPatterns) { + if (file_match_pattern.second && + re2::RE2::FullMatch(mime_type, file_match_pattern.second)) { + return true; + } + } + } + + // Then attempt to match based on `file_path` extension. + for (const auto& file_match_pattern : kFileMatchPatterns) { + if (re2::RE2::FullMatch(file_path.Extension(), file_match_pattern.first)) + return true; + } + + return false; +} + using ThumbnailDataCallback = base::OnceCallback<void(const std::string& data)>; // Handles a parsed message sent from image loader extension in response to a @@ -192,9 +320,9 @@ } ThumbnailLoader::ThumbnailRequest::ThumbnailRequest( - const base::FilePath& item_path, + const base::FilePath& file_path, const gfx::Size& size) - : item_path(item_path), size(size) {} + : file_path(file_path), size(size) {} ThumbnailLoader::ThumbnailRequest::~ThumbnailRequest() = default; @@ -204,14 +332,14 @@ void ThumbnailLoader::Load(const ThumbnailRequest& request, ImageCallback callback) { - // Get the item's last modified time - this will be used for cache lookup in + // Get the file's last modified time - this will be used for cache lookup in // the image loader extension. GURL source_url = extensions::Extension::GetBaseURLFromExtensionId( file_manager::kImageLoaderExtensionId); file_manager::util::GetMetadataForPath( file_manager::util::GetFileSystemContextForSourceURL(profile_, source_url), - request.item_path, + request.file_path, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY | storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED, base::BindOnce(&ThumbnailLoader::LoadForFileWithMetadata, @@ -237,9 +365,15 @@ return; } + // Short-circuit if unsupported. + if (!IsSupported(request.file_path)) { + std::move(callback).Run(/*bitmap=*/nullptr, base::File::FILE_ERROR_ABORT); + return; + } + GURL thumbnail_url; if (!file_manager::util::ConvertAbsoluteFilePathToFileSystemUrl( - profile_, request.item_path, + profile_, request.file_path, extensions::Extension::GetBaseURLFromExtensionId( file_manager::kImageLoaderExtensionId), &thumbnail_url)) {
diff --git a/chrome/browser/ui/ash/thumbnail_loader.h b/chrome/browser/ui/ash/thumbnail_loader.h index 98f13cf..1c03d261 100644 --- a/chrome/browser/ui/ash/thumbnail_loader.h +++ b/chrome/browser/ui/ash/thumbnail_loader.h
@@ -38,11 +38,11 @@ // Thumbnail request data that will be forwarded to the image loader. struct ThumbnailRequest { - ThumbnailRequest(const base::FilePath& item_path, const gfx::Size& size); + ThumbnailRequest(const base::FilePath& file_path, const gfx::Size& size); ~ThumbnailRequest(); - // The absolute item file path. - const base::FilePath item_path; + // The absolute file path. + const base::FilePath file_path; // The desired bitmap size. const gfx::Size size;
diff --git a/chrome/browser/ui/ash/thumbnail_loader_browsertest.cc b/chrome/browser/ui/ash/thumbnail_loader_browsertest.cc index 7677ff6..39c4f5b 100644 --- a/chrome/browser/ui/ash/thumbnail_loader_browsertest.cc +++ b/chrome/browser/ui/ash/thumbnail_loader_browsertest.cc
@@ -29,7 +29,7 @@ // References to paths set up in the test mount point during the browser test // setup. -enum class TestPath { kNonExistent, kEmptyDir, kJpg, kBrokenJpg, kPng }; +enum class TestPath { kNonExistent, kEmptyDir, kJpg, kBrokenJpg, kPng, kBin }; // Copies |bitmap| into |copy| and runs |callback|. void CopyBitmapAndRunClosure(base::OnceClosure callback, @@ -135,6 +135,8 @@ return mount_point()->GetRootPath().AppendASCII("broken.jpg"); case TestPath::kPng: return mount_point()->GetRootPath().AppendASCII("image.png"); + case TestPath::kBin: + return mount_point()->GetRootPath().AppendASCII("random.bin"); } } @@ -151,6 +153,8 @@ GetTestPath(TestPath::kJpg))); ASSERT_TRUE(base::CopyFile(GetTestDataFilePath("broken.jpg"), GetTestPath(TestPath::kBrokenJpg))); + ASSERT_TRUE(base::CopyFile(GetTestDataFilePath("random.bin"), + GetTestPath(TestPath::kBin))); } std::unique_ptr<ScopedExternalMountPoint> test_mount_point_; @@ -158,7 +162,7 @@ std::unique_ptr<ash::ThumbnailLoader> thumbnail_loader_; }; -IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, LoadNonExistentItem) { +IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, LoadNonExistentFile) { ash::ThumbnailLoader* loader = GetThumbnailLoader(); ASSERT_TRUE(loader); @@ -242,6 +246,24 @@ EXPECT_EQ(48, bitmap.height()); } +IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, LoadUnsupportedFiletype) { + ash::ThumbnailLoader* loader = GetThumbnailLoader(); + ASSERT_TRUE(loader); + + ash::ThumbnailLoader::ThumbnailRequest request(GetTestPath(TestPath::kBin), + gfx::Size(48, 48)); + + base::RunLoop run_loop; + loader->Load(request, + base::BindLambdaForTesting( + [&](const SkBitmap* bitmap, base::File::Error error) { + EXPECT_FALSE(bitmap); + EXPECT_EQ(error, base::File::FILE_ERROR_ABORT); + run_loop.Quit(); + })); + run_loop.Run(); +} + IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, RepeatedLoads) { ash::ThumbnailLoader* loader = GetThumbnailLoader(); ASSERT_TRUE(loader); @@ -282,7 +304,7 @@ EXPECT_FALSE(gfx::test::AreBitmapsEqual(bitmap1, bitmap3)); } -IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, ConcurentLoads) { +IN_PROC_BROWSER_TEST_F(ThumbnailLoaderTest, ConcurrentLoads) { ash::ThumbnailLoader* loader = GetThumbnailLoader(); ASSERT_TRUE(loader);
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc index 9e6aa2f..e45beac 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -22,6 +22,7 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/unguessable_token.h" #include "base/values.h" @@ -211,6 +212,34 @@ .Append(kDriveFsWallpaperDirName); } +bool SaveWallpaperToDriveFsIOTaskRunner( + const base::FilePath& origin, + const base::FilePath& destination_directory) { + if (destination_directory.empty()) + return false; + + if (!base::DirectoryExists(destination_directory) && + !base::CreateDirectory(destination_directory)) { + return false; + } + + std::string temp_file_name = + base::UnguessableToken::Create().ToString().append( + kDriveFsTempWallpaperFileName); + base::FilePath temp_destination = + destination_directory.Append(temp_file_name); + if (!base::CopyFile(origin, temp_destination)) { + base::DeleteFile(temp_destination); + return false; + } + + base::FilePath destination = + destination_directory.Append(kDriveFsWallpaperFileName); + bool success = base::ReplaceFile(temp_destination, destination, nullptr); + base::DeleteFile(temp_destination); + return success; +} + } // namespace WallpaperControllerClientImpl::WallpaperControllerClientImpl() { @@ -229,6 +258,10 @@ // SessionManager might not exist in unit tests. if (session_manager) session_observation_.Observe(session_manager); + + io_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); } WallpaperControllerClientImpl::~WallpaperControllerClientImpl() { @@ -480,34 +513,17 @@ return wallpaper_controller_->ShouldShowWallpaperSetting(); } -bool WallpaperControllerClientImpl::SaveWallpaperToDriveFs( +void WallpaperControllerClientImpl::SaveWallpaperToDriveFs( const AccountId& account_id, - const base::FilePath& origin) { + const base::FilePath& origin, + base::OnceCallback<void(bool)> wallpaper_saved_callback) { Profile* profile = ProfileHelper::Get()->GetProfileByAccountId(account_id); base::FilePath destination_directory = GetDriveFsWallpaperDir(profile); - if (destination_directory.empty()) - return false; - - if (!base::DirectoryExists(destination_directory) && - !base::CreateDirectory(destination_directory)) { - return false; - } - - std::string temp_file_name = - base::UnguessableToken::Create().ToString().append( - kDriveFsTempWallpaperFileName); - base::FilePath temp_destination = - destination_directory.Append(temp_file_name); - if (!base::CopyFile(origin, temp_destination)) { - base::DeleteFile(temp_destination); - return false; - } - - base::FilePath destination = - destination_directory.Append(kDriveFsWallpaperFileName); - bool success = base::ReplaceFile(temp_destination, destination, nullptr); - base::DeleteFile(temp_destination); - return success; + io_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&SaveWallpaperToDriveFsIOTaskRunner, origin, + destination_directory), + std::move(wallpaper_saved_callback)); } base::FilePath WallpaperControllerClientImpl::GetWallpaperPathFromDriveFs(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h index b0c4ad7..03117c3 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -72,8 +72,10 @@ void FetchImagesForCollection( const std::string& collection_id, FetchImagesForCollectionCallback callback) override; - bool SaveWallpaperToDriveFs(const AccountId& account_id, - const base::FilePath& origin) override; + void SaveWallpaperToDriveFs( + const AccountId& account_id, + const base::FilePath& origin, + base::OnceCallback<void(bool)> wallpaper_saved_callback) override; base::FilePath GetWallpaperPathFromDriveFs( const AccountId& account_id) override; void GetFilesId(const AccountId& account_id, @@ -208,6 +210,8 @@ session_manager::SessionManagerObserver> session_observation_{this}; + scoped_refptr<base::SequencedTaskRunner> io_task_runner_; + base::WeakPtrFactory<WallpaperControllerClientImpl> weak_factory_{this}; base::WeakPtrFactory<WallpaperControllerClientImpl> storage_weak_factory_{ this};
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index a3066ac..81b1178 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -52,8 +52,6 @@ #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/download/download_core_service.h" #include "chrome/browser/download/download_core_service_factory.h" -#include "chrome/browser/extensions/api/tabs/tabs_event_router.h" -#include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" #include "chrome/browser/extensions/browser_extension_window_controller.h" #include "chrome/browser/extensions/extension_ui_util.h" #include "chrome/browser/extensions/extension_util.h"
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 8c06522f..32186a6 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -706,7 +706,6 @@ // Hosted apps should open a window to their launch page. const extensions::Extension* extension = GetExtensionForBrowser(browser); if (extension && extension->is_hosted_app()) { - DCHECK(!extension->from_bookmark()); const auto app_launch_params = CreateAppLaunchParamsUserContainer( profile, extension, WindowOpenDisposition::NEW_WINDOW, apps::mojom::LaunchSource::kFromKeyboard);
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm index 24ae2bee..1b2e96e8 100644 --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
@@ -427,8 +427,7 @@ // Ignore is_browser: if a window becomes main that does not belong to an // extension or browser, treat it the same as switching to a browser. const Extension* extension = GetExtensionForNSWindow(window); - // Do not install the App menu for bookmark apps (which includes PWAs). - if (extension && !extension->from_bookmark()) + if (extension) [self appBecameMain:extension]; else [self chromeBecameMain];
diff --git a/chrome/browser/ui/commander/window_command_source.cc b/chrome/browser/ui/commander/window_command_source.cc index 29a406d..57f4815 100644 --- a/chrome/browser/ui/commander/window_command_source.cc +++ b/chrome/browser/ui/commander/window_command_source.cc
@@ -99,7 +99,7 @@ results.push_back(std::move(verb)); } score = finder.Find(merge_title, &ranges); - if (score > 0) { + if (score > 0 && !browser->is_type_devtools()) { auto verb = std::make_unique<CommandItem>(merge_title, score, ranges); verb->command = std::make_pair( merge_title, base::BindRepeating(&MergeCommandsForWindowsMatching,
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc index 9468d280..e8a67c4 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
@@ -119,8 +119,7 @@ } void WaitForBubbleToBeShown() { - manager_->DocumentOnLoadCompletedInMainFrame( - web_contents()->GetMainFrame()); + manager_->DocumentOnLoadCompletedInPrimaryMainFrame(); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc index 3ca8bf7..adf73c7 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc
@@ -38,6 +38,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension_builder.h" #include "extensions/common/mojom/run_location.mojom-shared.h" #include "extensions/common/user_script.h" @@ -107,7 +108,7 @@ scoped_refptr<const extensions::Extension> CreateAndAddExtension( const std::string& name, - extensions::ExtensionBuilder::ActionType action_type) { + extensions::ActionInfo::Type action_type) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder(name) .SetAction(action_type) @@ -144,8 +145,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, ExtensionActionWantsToRunAppearance) { const std::string id = - CreateAndAddExtension( - "extension", extensions::ExtensionBuilder::ActionType::PAGE_ACTION) + CreateAndAddExtension("extension", extensions::ActionInfo::TYPE_PAGE) ->id(); AddTab(browser(), GURL("chrome://newtab")); @@ -169,7 +169,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, BrowserActionBlockedActions) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("browser action") - .SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .AddPermission("https://www.google.com/*") .Build(); @@ -217,7 +217,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, PageActionBlockedActions) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("page action") - .SetAction(extensions::ExtensionBuilder::ActionType::PAGE_ACTION) + .SetAction(extensions::ActionInfo::TYPE_PAGE) .SetLocation(ManifestLocation::kInternal) .AddPermission("https://www.google.com/*") .Build(); @@ -313,8 +313,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, ExtensionActionContextMenuVisibility) { std::string id = - CreateAndAddExtension( - "extension", extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + CreateAndAddExtension("extension", extensions::ActionInfo::TYPE_BROWSER) ->id(); // Check that the context menu has the proper string for the action's pinned @@ -529,7 +528,7 @@ ExtensionActionViewControllerGrayscaleTest::CreateExtension( PermissionType permission_type) { extensions::ExtensionBuilder builder("extension"); - builder.SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + builder.SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal); constexpr char kHostGoogle[] = "https://www.google.com/*"; switch (permission_type) { @@ -577,7 +576,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, RuntimeHostsTooltip) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("extension name") - .SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .AddPermission("https://www.google.com/*") .Build(); @@ -697,7 +696,7 @@ GetPageInteractionStatusWithActiveTab) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("active tab") - .SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .AddPermission("activeTab") .Build(); extension_service()->AddExtension(extension.get()); @@ -795,7 +794,7 @@ TEST_F(ExtensionActionViewControllerUnitTest, TestGetIconWithNullWebContents) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("extension name") - .SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .AddPermission("https://example.com/") .Build();
diff --git a/chrome/browser/ui/extensions/extension_install_ui_default.cc b/chrome/browser/ui/extensions/extension_install_ui_default.cc index fedd5a07..93e0e98 100644 --- a/chrome/browser/ui/extensions/extension_install_ui_default.cc +++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc
@@ -61,13 +61,9 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) // Toast id and duration for extension install success. constexpr char kExtensionInstallSuccessToastId[] = "extension_install_success"; -// TODO(crbug.com/1270549): Use value from central location. -constexpr int kToastDurationMs = 2500; void ShowToast(const std::string& id, const std::u16string& text) { - ash::ToastManager::Get()->Show( - ash::ToastData(id, text, kToastDurationMs, - /*dismiss_text=*/absl::nullopt)); + ash::ToastManager::Get()->Show(ash::ToastData(id, text)); } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/extensions/extension_installed_bubble_model_unittest.cc b/chrome/browser/ui/extensions/extension_installed_bubble_model_unittest.cc index 6bc1ed0..7849573 100644 --- a/chrome/browser/ui/extensions/extension_installed_bubble_model_unittest.cc +++ b/chrome/browser/ui/extensions/extension_installed_bubble_model_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/test/base/browser_with_test_window_test.h" #include "content/public/test/browser_task_environment.h" #include "extensions/browser/extension_system.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension_builder.h" #include "extensions/common/manifest_constants.h" #include "testing/gtest/include/gtest/gtest.h" @@ -119,10 +120,9 @@ TEST_F(ExtensionInstalledBubbleModelTest, PageActionExtension) { // An extension with a page action... - auto extension = - extensions::ExtensionBuilder("Foo") - .SetAction(extensions::ExtensionBuilder::ActionType::PAGE_ACTION) - .Build(); + auto extension = extensions::ExtensionBuilder("Foo") + .SetAction(extensions::ActionInfo::TYPE_PAGE) + .Build(); extension_service()->AddExtension(extension.get()); ExtensionInstalledBubbleModel model(browser()->profile(), extension.get(), @@ -142,7 +142,7 @@ TEST_F(ExtensionInstalledBubbleModelTest, ExtensionWithKeyBinding) { // An extension with a browser action and a key binding... auto builder = extensions::ExtensionBuilder("Foo"); - builder.SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION); + builder.SetAction(extensions::ActionInfo::TYPE_BROWSER); AddBrowserActionKeyBinding(&builder, "Alt+Shift+E"); auto extension = builder.Build();
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc index ab201738..37c3c2c 100644 --- a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc +++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -60,9 +60,7 @@ HostedAppBrowserController::HostedAppBrowserController(Browser* browser) : AppBrowserController( browser, - web_app::GetAppIdFromApplicationName(browser->app_name())) { - DCHECK(!GetExtension() || !GetExtension()->from_bookmark()); -} + web_app::GetAppIdFromApplicationName(browser->app_name())) {} HostedAppBrowserController::~HostedAppBrowserController() = default; @@ -218,8 +216,6 @@ AppBrowserController::OnTabInserted(contents); const Extension* extension = GetExtension(); - if (extension && extension->from_bookmark()) - extension = nullptr; extensions::TabHelper::FromWebContents(contents)->SetExtensionApp(extension); web_app::SetAppPrefsForWebContents(contents); }
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index ddd2eeae..fc9e02a 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -239,7 +239,6 @@ ? extensions::Extension::NO_FLAGS : extensions::Extension::FROM_BOOKMARK); ASSERT_TRUE(app); - ASSERT_FALSE(app->from_bookmark()); app_id_ = app->id(); // Launch app in a window. @@ -485,7 +484,6 @@ const Extension* app = ExtensionRegistry::Get(profile())->GetExtensionById( app_id_, ExtensionRegistry::ENABLED); EXPECT_TRUE(app->is_hosted_app()); - EXPECT_FALSE(app->from_bookmark()); } IN_PROC_BROWSER_TEST_P(HostedAppTest, HasReloadButton) {
diff --git a/chrome/browser/ui/global_error/global_error_browsertest.cc b/chrome/browser/ui/global_error/global_error_browsertest.cc index f12fbfa..8c3a4f6 100644 --- a/chrome/browser/ui/global_error/global_error_browsertest.cc +++ b/chrome/browser/ui/global_error/global_error_browsertest.cc
@@ -41,6 +41,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/mock_external_provider.h" #include "extensions/browser/sandboxed_unpacker.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension_builder.h" #include "extensions/common/feature_switch.h" @@ -133,7 +134,7 @@ extensions::ExtensionRegistry::Get(profile); extensions::ExtensionBuilder builder("Browser Action"); - builder.SetAction(extensions::ExtensionBuilder::ActionType::BROWSER_ACTION); + builder.SetAction(extensions::ActionInfo::TYPE_BROWSER); builder.SetLocation(extensions::mojom::ManifestLocation::kInternal); scoped_refptr<const extensions::Extension> test_extension = builder.Build(); extension_service->AddExtension(test_extension.get());
diff --git a/chrome/browser/ui/quick_answers/DEPS b/chrome/browser/ui/quick_answers/DEPS new file mode 100644 index 0000000..50e2308 --- /dev/null +++ b/chrome/browser/ui/quick_answers/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + # //chrome/browser/ui/quick_answers will contain implementation supporting + # both ash and Lacros browser. + "+ash", +]
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.cc b/chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.cc similarity index 97% rename from chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.cc rename to chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.cc index 53fb640..23b9093 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.h" +#include "chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.h" #include "base/logging.h" #include "base/rand_util.h"
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.h b/chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.h similarity index 87% rename from chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.h rename to chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.h index 4214191e..b7c9e29 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.h +++ b/chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_ #include <string> #include <vector> @@ -61,4 +61,4 @@ base::WeakPtrFactory<QuickAnswersAccessTokenFetcher> weak_factory_{this}; }; -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_ACCESS_TOKEN_FETCHER_H_
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.cc b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc similarity index 86% rename from chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.cc rename to chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc index 6534091..13cdcf0 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" #include "ash/public/cpp/new_window_delegate.h" #include "base/metrics/histogram_functions.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" #include "chromeos/strings/grit/chromeos_strings.h" @@ -16,13 +16,13 @@ namespace { -using ::ash::quick_answers::Context; -using ::ash::quick_answers::IntentType; -using ::ash::quick_answers::QuickAnswer; -using ::ash::quick_answers::QuickAnswersClient; -using ::ash::quick_answers::QuickAnswersExitPoint; -using ::ash::quick_answers::QuickAnswersRequest; -using ::ash::quick_answers::ResultType; +using ::quick_answers::Context; +using ::quick_answers::IntentType; +using ::quick_answers::QuickAnswer; +using ::quick_answers::QuickAnswersClient; +using ::quick_answers::QuickAnswersExitPoint; +using ::quick_answers::QuickAnswersRequest; +using ::quick_answers::ResultType; constexpr char kQuickAnswersSettingsUrl[] = "chrome://os-settings/osSearch/search"; @@ -47,30 +47,28 @@ // Returns if the request has already been processed (by the text annotator). bool IsProcessedRequest(const QuickAnswersRequest& request) { return (request.preprocessed_output.intent_info.intent_type != - ash::quick_answers::IntentType::kUnknown); + quick_answers::IntentType::kUnknown); } bool ShouldShowQuickAnswers() { - if (!ash::QuickAnswersState::Get()->is_eligible()) + if (!QuickAnswersState::Get()->is_eligible()) return false; - bool settings_enabled = ash::QuickAnswersState::Get()->settings_enabled(); + bool settings_enabled = QuickAnswersState::Get()->settings_enabled(); // Respect the managed settings. - if (ash::QuickAnswersState::Get()->IsSettingsEnforced()) + if (QuickAnswersState::Get()->IsSettingsEnforced()) return settings_enabled; if (settings_enabled) return true; - bool should_show_consent = ash::QuickAnswersState::Get()->consent_status() == - ash::quick_answers::prefs::ConsentStatus::kUnknown; + bool should_show_consent = QuickAnswersState::Get()->consent_status() == + quick_answers::prefs::ConsentStatus::kUnknown; return should_show_consent; } } // namespace -namespace ash { - QuickAnswersControllerImpl::QuickAnswersControllerImpl() : quick_answers_ui_controller_( std::make_unique<QuickAnswersUiController>(this)), @@ -104,7 +102,7 @@ quick_answer_.reset(); QuickAnswersRequest request = BuildRequest(); - if (ash::QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { + if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { // Send the request for preprocessing. Only shows quick answers view if the // predicted intent is not |kUnknown| at |OnRequestPreprocessFinish|. quick_answers_client_->SendRequestForPreprocessing(request); @@ -206,7 +204,7 @@ void QuickAnswersControllerImpl::OnRequestPreprocessFinished( const QuickAnswersRequest& processed_request) { - if (!ash::QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { + if (!QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { // Ignore preprocessing result if text annotator is not enabled. return; } @@ -234,7 +232,7 @@ void QuickAnswersControllerImpl::OnRetryQuickAnswersRequest() { QuickAnswersRequest request = BuildRequest(); - if (ash::QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { + if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { quick_answers_client_->SendRequestForPreprocessing(request); } else { quick_answers_client_->SendRequest(request); @@ -259,7 +257,7 @@ void QuickAnswersControllerImpl::OnUserConsentResult(bool consented) { quick_answers_ui_controller_->CloseUserConsentView(); - ash::QuickAnswersState::Get()->OnConsentResult( + QuickAnswersState::Get()->OnConsentResult( consented ? ConsentResultType::kAllow : ConsentResultType::kNoThanks); if (consented) { @@ -270,13 +268,14 @@ } void QuickAnswersControllerImpl::OpenQuickAnswersSettings() { - NewWindowDelegate::GetInstance()->OpenUrl(GURL(kQuickAnswersSettingsUrl), - /*from_user_interaction=*/true); + ash::NewWindowDelegate::GetInstance()->OpenUrl( + GURL(kQuickAnswersSettingsUrl), + /*from_user_interaction=*/true); } void QuickAnswersControllerImpl::MaybeDismissQuickAnswersConsent() { if (quick_answers_ui_controller_->is_showing_user_consent_view()) - ash::QuickAnswersState::Get()->OnConsentResult(ConsentResultType::kDismiss); + QuickAnswersState::Get()->OnConsentResult(ConsentResultType::kDismiss); quick_answers_ui_controller_->CloseUserConsentView(); } @@ -297,4 +296,3 @@ request.context = context_; return request; } -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h similarity index 89% rename from chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h rename to chrome/browser/ui/quick_answers/quick_answers_controller_impl.h index 6ba751b..6f1672e 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h
@@ -2,21 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_ #include <memory> #include <string> -#include "chrome/browser/ui/ash/quick_answers/quick_answers_access_token_fetcher.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_access_token_fetcher.h" +#include "chrome/browser/ui/quick_answers/quick_answers_state_controller.h" #include "chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.h" #include "chromeos/components/quick_answers/quick_answers_client.h" #include "chromeos/components/quick_answers/quick_answers_model.h" #include "ui/gfx/geometry/rect.h" -namespace ash { - class QuickAnswersUiController; // Implementation of QuickAnswerController. It fetches quick answers @@ -119,5 +117,4 @@ QuickAnswersVisibility visibility_ = QuickAnswersVisibility::kClosed; }; -} // namespace ash -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_unittest.cc b/chrome/browser/ui/quick_answers/quick_answers_controller_unittest.cc similarity index 94% rename from chrome/browser/ui/ash/quick_answers/quick_answers_controller_unittest.cc rename to chrome/browser/ui/quick_answers/quick_answers_controller_unittest.cc index 8356f841..d43034a 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_controller_unittest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_unittest.cc
@@ -2,20 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" #include "base/memory/scoped_refptr.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" -#include "chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h" -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" -#include "chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/user_consent_view.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" #include "chromeos/components/quick_answers/quick_answers_client.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" -namespace ash { - namespace { constexpr gfx::Rect kDefaultAnchorBoundsInScreen = @@ -225,5 +223,3 @@ const views::View* consent_view = GetConsentView(); EXPECT_EQ(123, consent_view->GetBoundsInScreen().x()); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.cc b/chrome/browser/ui/quick_answers/quick_answers_state_controller.cc similarity index 92% rename from chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.cc rename to chrome/browser/ui/quick_answers/quick_answers_state_controller.cc index 48bc50c..59107a3 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_state_controller.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_state_controller.h" #include "ash/public/cpp/assistant/assistant_state.h" #include "ash/session/session_controller_impl.h" @@ -10,8 +10,6 @@ #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "components/prefs/pref_service.h" -namespace ash { - namespace { using chromeos::assistant::prefs::kAssistantContextEnabled; @@ -56,9 +54,7 @@ void QuickAnswersStateController::OnFirstSessionStarted() { PrefService* prefs = - Shell::Get()->session_controller()->GetPrimaryUserPrefService(); + ash::Shell::Get()->session_controller()->GetPrimaryUserPrefService(); state_.RegisterPrefChanges(prefs); MigrateQuickAnswersConsentStatus(prefs); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h b/chrome/browser/ui/quick_answers/quick_answers_state_controller.h similarity index 66% rename from chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h rename to chrome/browser/ui/quick_answers/quick_answers_state_controller.h index e158589..8a4db0eb7 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h +++ b/chrome/browser/ui/quick_answers/quick_answers_state_controller.h
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_ #include "ash/public/cpp/session/session_observer.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" -namespace ash { - // Provide access of Assistant related prefs and states to the clients. -class QuickAnswersStateController : public SessionObserver { +class QuickAnswersStateController : public ash::SessionObserver { public: QuickAnswersStateController(); @@ -27,9 +25,7 @@ QuickAnswersState state_; - ScopedSessionObserver session_observer_; + ash::ScopedSessionObserver session_observer_; }; -} // namespace ash - -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_STATE_CONTROLLER_H_
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller_unittest.cc b/chrome/browser/ui/quick_answers/quick_answers_state_controller_unittest.cc similarity index 82% rename from chrome/browser/ui/ash/quick_answers/quick_answers_state_controller_unittest.cc rename to chrome/browser/ui/quick_answers/quick_answers_state_controller_unittest.cc index b7400807..f733b1482 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_state_controller_unittest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_state_controller_unittest.cc
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_state_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_state_controller.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h" +#include "chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h" #include "components/language/core/browser/pref_names.h" #include "third_party/icu/source/common/unicode/locid.h" -namespace ash { - class TestQuickAnswersStateObserver : public QuickAnswersStateObserver { public: TestQuickAnswersStateObserver() = default; @@ -46,7 +44,8 @@ void SetUp() override { ChromeQuickAnswersTestBase::SetUp(); - prefs_ = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); + prefs_ = + ash::Shell::Get()->session_controller()->GetPrimaryUserPrefService(); DCHECK(prefs_); observer_ = std::make_unique<TestQuickAnswersStateObserver>(); @@ -66,13 +65,13 @@ }; TEST_F(QuickAnswersStateControllerTest, InitObserver) { - EXPECT_FALSE(ash::QuickAnswersState::Get()->settings_enabled()); + EXPECT_FALSE(QuickAnswersState::Get()->settings_enabled()); prefs()->SetBoolean(quick_answers::prefs::kQuickAnswersEnabled, true); // The observer class should get an instant notification about the current // pref value. QuickAnswersState::Get()->AddObserver(observer()); - EXPECT_TRUE(ash::QuickAnswersState::Get()->settings_enabled()); + EXPECT_TRUE(QuickAnswersState::Get()->settings_enabled()); EXPECT_TRUE(observer()->settings_enabled()); QuickAnswersState::Get()->RemoveObserver(observer()); @@ -81,12 +80,12 @@ TEST_F(QuickAnswersStateControllerTest, NotifySettingsEnabled) { QuickAnswersState::Get()->AddObserver(observer()); - EXPECT_FALSE(ash::QuickAnswersState::Get()->settings_enabled()); + EXPECT_FALSE(QuickAnswersState::Get()->settings_enabled()); EXPECT_FALSE(observer()->settings_enabled()); // The observer class should get an notification when the pref value changes. prefs()->SetBoolean(quick_answers::prefs::kQuickAnswersEnabled, true); - EXPECT_TRUE(ash::QuickAnswersState::Get()->settings_enabled()); + EXPECT_TRUE(QuickAnswersState::Get()->settings_enabled()); EXPECT_TRUE(observer()->settings_enabled()); QuickAnswersState::Get()->RemoveObserver(observer()); @@ -98,7 +97,7 @@ prefs()->SetString(language::prefs::kApplicationLocale, "en"); SimulateSessionStart(); - EXPECT_TRUE(ash::QuickAnswersState::Get()->is_eligible()); + EXPECT_TRUE(QuickAnswersState::Get()->is_eligible()); } TEST_F(QuickAnswersStateControllerTest, LocaleIneligible) { @@ -107,7 +106,5 @@ prefs()->SetString(language::prefs::kApplicationLocale, "zh"); SimulateSessionStart(); - EXPECT_FALSE(ash::QuickAnswersState::Get()->is_eligible()); + EXPECT_FALSE(QuickAnswersState::Get()->is_eligible()); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc similarity index 90% rename from chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc rename to chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc index 8157a8d2..e2755f7 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" #include "ash/public/cpp/new_window_delegate.h" #include "base/bind.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" -#include "chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/user_consent_view.h" #include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "mojo/public/cpp/bindings/remote.h" @@ -19,8 +19,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/widget/widget.h" -namespace ash { - namespace { using quick_answers::QuickAnswer; @@ -63,7 +61,7 @@ // Route dismissal through |controller_| for logging impressions. controller_->DismissQuickAnswers(QuickAnswersExitPoint::kQuickAnswersClick); - NewWindowDelegate::GetPrimary()->OpenUrl( + ash::NewWindowDelegate::GetPrimary()->OpenUrl( GURL(kGoogleSearchUrlPrefix + net::EscapeUrlEncodedData(query_, /*use_plus=*/true)), /*from_user_interaction=*/true); @@ -143,8 +141,8 @@ controller_->DismissQuickAnswers( QuickAnswersExitPoint::kReportQueryButtonClick); - NewWindowDelegate::GetPrimary()->OpenFeedbackPage( - NewWindowDelegate::FeedbackSource::kFeedbackSourceQuickAnswers, + ash::NewWindowDelegate::GetPrimary()->OpenFeedbackPage( + ash::NewWindowDelegate::FeedbackSource::kFeedbackSourceQuickAnswers, base::StringPrintf(kFeedbackDescriptionTemplate, query_.c_str())); } @@ -155,5 +153,3 @@ if (consented && quick_answers_view_) quick_answers_view_->RequestFocus(); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.h similarity index 92% rename from chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h rename to chrome/browser/ui/quick_answers/quick_answers_ui_controller.h index 28eb1bf14..6e71d5ed2 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h +++ b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.h
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_ #include <string> #include "ui/gfx/geometry/rect.h" -namespace ash { - class QuickAnswersView; class QuickAnswersControllerImpl; @@ -104,6 +102,4 @@ std::string query_; }; -} // namespace ash - -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_QUICK_ANSWERS_UI_CONTROLLER_H_
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller_unittest.cc b/chrome/browser/ui/quick_answers/quick_answers_ui_controller_unittest.cc similarity index 85% rename from chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller_unittest.cc rename to chrome/browser/ui/quick_answers/quick_answers_ui_controller_unittest.cc index f875c6c..d55f93a 100644 --- a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller_unittest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_ui_controller_unittest.cc
@@ -2,13 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" -#include "chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h" - -namespace ash { +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h" namespace { @@ -63,5 +61,3 @@ std::u16string(), std::u16string()); EXPECT_TRUE(ui_controller()->is_showing_user_consent_view()); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.cc b/chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.cc similarity index 80% rename from chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.cc rename to chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.cc index 227792a..aef67c9 100644 --- a/chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.cc +++ b/chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h" +#include "chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" #include "ui/base/models/simple_menu_model.h" #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_runner.h" @@ -19,11 +19,10 @@ void ChromeQuickAnswersTestBase::SetUp() { ChromeAshTestBase::SetUp(); - if (!ash::QuickAnswersController::Get()) - quick_answers_controller_ = - std::make_unique<ash::QuickAnswersControllerImpl>(); + if (!QuickAnswersController::Get()) + quick_answers_controller_ = std::make_unique<QuickAnswersControllerImpl>(); - ash::QuickAnswersState::Get()->RegisterPrefChanges( + QuickAnswersState::Get()->RegisterPrefChanges( ash::Shell::Get()->session_controller()->GetPrimaryUserPrefService()); }
diff --git a/chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h b/chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h similarity index 75% rename from chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h rename to chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h index 70169ea0..a557453 100644 --- a/chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h +++ b/chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h
@@ -2,14 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_ #include "chrome/test/base/chrome_ash_test_base.h" -namespace ash { class QuickAnswersController; -} // namespace ash namespace ui { class SimpleMenuModel; @@ -46,7 +44,7 @@ std::unique_ptr<views::MenuRunner> menu_runner_; std::unique_ptr<views::Widget> menu_parent_; - std::unique_ptr<ash::QuickAnswersController> quick_answers_controller_; + std::unique_ptr<QuickAnswersController> quick_answers_controller_; }; -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_TEST_CHROME_QUICK_ANSWERS_TEST_BASE_H_
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.cc similarity index 94% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.cc rename to chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.cc index 5376a07..f943728 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.cc
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h" - -namespace ash { +#include "chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h" QuickAnswersFocusSearch::QuickAnswersFocusSearch( views::View* view, @@ -60,5 +58,3 @@ views::View* QuickAnswersFocusSearch::GetFocusTraversableParentView() { return nullptr; } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h b/chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h similarity index 85% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h rename to chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h index 743e516..7c326f1 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_ #include "base/callback.h" #include "ui/views/focus/focus_manager.h" #include "ui/views/focus/focus_search.h" -namespace ash { - // This class manages the focus traversal order for elements inside // Quick-Answers related views. // TODO(siabhijeet): QuickAnswersView is a menu-companion, so ideally should @@ -47,6 +45,4 @@ const GetFocusableViewsCallback get_focusable_views_callback_; }; -} // namespace ash - -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_FOCUS_SEARCH_H_
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.cc similarity index 96% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.cc rename to chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.cc index 3d9880f..b716051 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h" #include "base/containers/adapters.h" -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" -#include "chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/user_consent_view.h" #include "ui/aura/env.h" #include "ui/views/controls/menu/menu_controller.h" #include "ui/views/controls/menu/menu_item_view.h" @@ -15,8 +15,6 @@ #include "ui/views/widget/tooltip_manager.h" #include "ui/views/widget/widget.h" -namespace ash { - QuickAnswersPreTargetHandler::QuickAnswersPreTargetHandler( QuickAnswersView* view) : view_(view) { @@ -235,5 +233,3 @@ return; } } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h b/chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h similarity index 86% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h rename to chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h index 891edda..0338807c 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ #include "ui/events/event_handler.h" #include "ui/views/view.h" @@ -16,8 +16,6 @@ class ExternalFocusTracker; } // namespace views -namespace ash { - class QuickAnswersView; namespace quick_answers { @@ -63,6 +61,4 @@ std::unique_ptr<views::ExternalFocusTracker> external_focus_tracker_; }; -} // namespace ash - -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc similarity index 98% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.cc rename to chrome/browser/ui/quick_answers/ui/quick_answers_view.cc index 6a25b74..6f290cf 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" #include "base/bind.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h" #include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/vector_icons/vector_icons.h" @@ -38,7 +38,6 @@ #include "ui/views/widget/widget.h" #include "ui/wm/core/coordinate_conversion.h" -namespace ash { namespace { using quick_answers::QuickAnswer; @@ -616,5 +615,3 @@ const GURL& phonetics_audio) { phonetics_audio_web_view_->LoadInitialURL(phonetics_audio); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h similarity index 90% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h rename to chrome/browser/ui/quick_answers/ui/quick_answers_view.h index 9800e47c..6dd2c7d 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_ #include <vector> -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h" #include "ui/events/event_handler.h" #include "ui/views/focus/focus_manager.h" @@ -18,8 +18,6 @@ class WebView; } // namespace views -namespace ash { - class QuickAnswersUiController; class QuickAnswersPreTargetHandler; @@ -98,6 +96,5 @@ std::unique_ptr<QuickAnswersFocusSearch> focus_search_; base::WeakPtrFactory<QuickAnswersView> weak_factory_{this}; }; -} // namespace ash -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_QUICK_ANSWERS_VIEW_H_
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view_unittest.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view_unittest.cc similarity index 92% rename from chrome/browser/ui/ash/quick_answers/ui/quick_answers_view_unittest.cc rename to chrome/browser/ui/quick_answers/ui/quick_answers_view_unittest.cc index 378d6e5..69be7f28 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_view_unittest.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view_unittest.cc
@@ -2,14 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_view.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_view.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_controller_impl.h" -#include "chrome/browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h" +#include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/test/chrome_quick_answers_test_base.h" #include "ui/views/controls/menu/menu_controller.h" -namespace ash { - namespace { constexpr int kMarginDip = 10; @@ -106,5 +104,3 @@ view()->RequestFocus(); EXPECT_TRUE(view()->HasFocus()); } - -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/ui/user_consent_view.cc b/chrome/browser/ui/quick_answers/ui/user_consent_view.cc similarity index 98% rename from chrome/browser/ui/ash/quick_answers/ui/user_consent_view.cc rename to chrome/browser/ui/quick_answers/ui/user_consent_view.cc index 7c14e11..3f710b8 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/user_consent_view.cc +++ b/chrome/browser/ui/quick_answers/ui/user_consent_view.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h" +#include "chrome/browser/ui/quick_answers/ui/user_consent_view.h" #include "base/bind.h" #include "chrome/browser/ash/accessibility/accessibility_manager.h" -#include "chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.h" +#include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/vector_icons/vector_icons.h" #include "ui/aura/window.h" @@ -30,7 +30,6 @@ #include "ui/views/widget/widget.h" #include "ui/wm/core/coordinate_conversion.h" -namespace ash { namespace quick_answers { using ::ash::AccessibilityManager; @@ -359,4 +358,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h b/chrome/browser/ui/quick_answers/ui/user_consent_view.h similarity index 83% rename from chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h rename to chrome/browser/ui/quick_answers/ui/user_consent_view.h index 3d17b412..05641cc 100644 --- a/chrome/browser/ui/ash/quick_answers/ui/user_consent_view.h +++ b/chrome/browser/ui/quick_answers/ui/user_consent_view.h
@@ -2,21 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_ -#define CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_ +#ifndef CHROME_BROWSER_UI_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_ +#define CHROME_BROWSER_UI_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_ #include <memory> -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_focus_search.h" -#include "chrome/browser/ui/ash/quick_answers/ui/quick_answers_pre_target_handler.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_focus_search.h" +#include "chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h" #include "ui/views/view.h" namespace views { class LabelButton; } // namespace views -namespace ash { - class QuickAnswersUiController; namespace quick_answers { @@ -74,6 +72,5 @@ }; } // namespace quick_answers -} // namespace ash -#endif // CHROME_BROWSER_UI_ASH_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_ +#endif // CHROME_BROWSER_UI_QUICK_ANSWERS_UI_USER_CONSENT_VIEW_H_
diff --git a/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc b/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc index 39db3c5..84d8fa34 100644 --- a/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc +++ b/chrome/browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/fenced_frame_test_util.h" +#include "content/public/test/prerender_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "url/gurl.h" @@ -134,6 +135,59 @@ EXPECT_EQ(chrome::kChromeUINewTabPageThirdPartyURL, NavigateToNewTabPage()); } +class NewTabPageNavigationThrottlePrerenderTest + : public NewTabPageNavigationThrottleTest { + public: + NewTabPageNavigationThrottlePrerenderTest() + : prerender_test_helper_(base::BindRepeating( + &NewTabPageNavigationThrottlePrerenderTest::web_contents, + base::Unretained(this))) {} + ~NewTabPageNavigationThrottlePrerenderTest() override = default; + NewTabPageNavigationThrottlePrerenderTest( + const NewTabPageNavigationThrottlePrerenderTest&) = delete; + + NewTabPageNavigationThrottlePrerenderTest& operator=( + const NewTabPageNavigationThrottlePrerenderTest&) = delete; + + void SetUp() override { + prerender_test_helper_.SetUp(https_test_server()); + NewTabPageNavigationThrottleTest::SetUp(); + } + + content::test::PrerenderTestHelper& prerender_test_helper() { + return prerender_test_helper_; + } + + private: + content::test::PrerenderTestHelper prerender_test_helper_; +}; + +IN_PROC_BROWSER_TEST_F(NewTabPageNavigationThrottlePrerenderTest, + PrerenderingShouldNotAffectTitle) { + ASSERT_TRUE(https_test_server()->Start()); + GURL ntp_url = https_test_server()->GetURL("/instant_extended.html"); + + GURL title_url = https_test_server()->GetURL("/title2.html"); + EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), title_url)); + EXPECT_EQ(u"Title Of Awesomeness", web_contents()->GetTitle()); + + // Load a page in the prerendering. + const int host_id = prerender_test_helper().AddPrerender(ntp_url); + content::test::PrerenderHostObserver host_observer(*web_contents(), host_id); + EXPECT_FALSE(host_observer.was_activated()); + + // Prerendering should not change the title of the web contents. + EXPECT_EQ(u"Title Of Awesomeness", web_contents()->GetTitle()); + + // Activate the prerender page. + SetNewTabPage(ntp_url.spec()); + prerender_test_helper().NavigatePrimaryPage(ntp_url); + EXPECT_TRUE(host_observer.was_activated()); + + // The title should be changed after activating. + EXPECT_NE(u"Title Of Awesomeness", web_contents()->GetTitle()); +} + class NewTabPageNavigationThrottleFencedFrameTest : public NewTabPageNavigationThrottleTest { public:
diff --git a/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc b/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc index ca80691..fdc22016 100644 --- a/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc +++ b/chrome/browser/ui/signin_reauth_view_controller_browsertest.cc
@@ -482,7 +482,8 @@ browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_NE(new_contents, original_contents); EXPECT_NE(new_contents, dialog_contents); - EXPECT_EQ(new_contents->GetURL(), https_server()->GetURL("/title1.html")); + EXPECT_EQ(new_contents->GetLastCommittedURL(), + https_server()->GetURL("/title1.html")); } // Tests that the authentication flow that goes outside of the reauth host is @@ -516,7 +517,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_NE(target_contents, original_contents); EXPECT_EQ(target_contents, signin_reauth_view_controller()->GetWebContents()); - EXPECT_EQ(target_contents->GetURL(), target_url); + EXPECT_EQ(target_contents->GetLastCommittedURL(), target_url); ASSERT_TRUE(content::ExecuteScript( target_contents, "document.getElementsByTagName('a')[0].click();")); @@ -543,7 +544,8 @@ tab_added_waiter.Wait(); auto* tab_strip_model = browser()->tab_strip_model(); - EXPECT_EQ(tab_strip_model->GetActiveWebContents()->GetURL(), target_url); + EXPECT_EQ(tab_strip_model->GetActiveWebContents()->GetLastCommittedURL(), + target_url); tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), TabStripModel::CLOSE_USER_GESTURE); EXPECT_EQ(WaitForReauthResult(), signin::ReauthResult::kDismissedByUser);
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 5f5000b..d202ae2 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -333,6 +333,13 @@ return false; } #endif // defined(OS_WIN) + + // Don't show the picker if Chrome should be launched without window. This + // will also cause a profile to be loaded which Chrome needs for performing + // background activity. + if (StartupBrowserCreator::ShouldLoadProfileWithoutWindow(command_line)) + return false; + return ProfilePicker::ShouldShowAtLaunch(); #endif // !BUILDFLAG(IS_CHROMEOS_ASH) } @@ -781,6 +788,30 @@ } #endif // defined(OS_MAC) +// static +bool StartupBrowserCreator::ShouldLoadProfileWithoutWindow( + const base::CommandLine& command_line) { + // Don't open any browser windows if starting up in "background mode". + if (command_line.HasSwitch(switches::kNoStartupWindow)) + return true; + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Don't open any browser windows if Ash requested that Lacros not do so. + // The implicit assumption is that some other code is responsible for + // keeping Lacros running in the background. + // Temporarily remove this logic to deal with https://crbug.com/1278549. +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // If Lacros is the primary web browser, do not open the browser window + // on Chrome OS session login. + if (crosapi::browser_util::IsLacrosPrimaryBrowser()) + return true; +#endif + + return false; +} + bool StartupBrowserCreator::ProcessCmdLineImpl( const base::CommandLine& command_line, const base::FilePath& cur_dir,
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h index f147c87..ae94f38 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.h +++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -177,6 +177,11 @@ base::OnceClosure on_urls_unhandled_cb); #endif + // Returns true if Chrome is intended to load a profile and launch without any + // window. + static bool ShouldLoadProfileWithoutWindow( + const base::CommandLine& command_line); + private: friend class CloudPrintProxyPolicyTest; friend class CloudPrintProxyPolicyStartupTest;
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 59a2b95..16c28d9 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -3960,6 +3960,11 @@ ~StartupBrowserCreatorPickerTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { + StartupBrowserCreatorPickerTestBase::SetUpCommandLine(command_line); + + if (content::IsPreTest()) + return; // Don't apply the test parameters to the PRE test. + if (GetParam().url_arg) { command_line->AppendArg(GetParam().url_arg->spec()); } else if (GetParam().switch_value_ascii) { @@ -4001,13 +4006,30 @@ GetParam().shutdown_type == ProfilePickerSetup::ShutdownType::kRestart); } +// Checks that either the ProfilePicker or a browser window is open at startup. +// Except with switches::kNoStartupWindow, for which neither the picker nor a +// browser is open. IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorPickerTest, TestSetup) { - if (GetParam().expected_to_show) { - // Opens the picker and thus does not open any new browser window for the - // main profile. + ProfilePickerSetup setup_param = GetParam(); + + // Check the ProfilePicker. + if (setup_param.expected_to_show) { + if (!ProfilePicker::IsOpen()) { + base::RunLoop run_loop; + ProfilePicker::AddOnProfilePickerOpenedCallbackForTesting( + run_loop.QuitClosure()); + run_loop.Run(); + } + EXPECT_TRUE(ProfilePicker::IsOpen()); + } else { + EXPECT_FALSE(ProfilePicker::IsOpen()); + } + + // Check the browser window. + if (setup_param.expected_to_show || + setup_param.switch_name == switches::kNoStartupWindow) { EXPECT_EQ(0u, chrome::GetTotalBrowserCount()); } else { - // The picker is skipped which means a browser window is opened on startup. EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); } } @@ -4029,6 +4051,8 @@ /*switch_name=*/switches::kApp}, ProfilePickerSetup{/*expected_to_show=*/false, /*switch_name=*/switches::kAppId}, + ProfilePickerSetup{/*expected_to_show=*/false, + /*switch_name=*/switches::kNoStartupWindow}, // Skip the picker when a specific profile is requested (used e.g. by // profile specific desktop shortcuts on Win). ProfilePickerSetup{/*expected_to_show=*/false,
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index fb8a2f6..e03a03ad 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -85,10 +85,6 @@ #include "components/app_restore/full_restore_utils.h" #endif -#if BUILDFLAG(IS_CHROMEOS_LACROS) -#include "chromeos/lacros/lacros_service.h" -#endif - namespace { // Utility functions ---------------------------------------------------------- @@ -309,7 +305,7 @@ StartupBrowserCreatorImpl::LaunchResult StartupBrowserCreatorImpl::DetermineURLsAndLaunch( chrome::startup::IsProcessStartup process_startup) { - if (!ShouldLaunch(command_line_)) + if (StartupBrowserCreator::ShouldLoadProfileWithoutWindow(command_line_)) return LaunchResult::kNormally; const bool is_incognito_or_guest = profile_->IsOffTheRecord(); @@ -648,30 +644,6 @@ } // static -bool StartupBrowserCreatorImpl::ShouldLaunch( - const base::CommandLine& command_line) { - // Don't open any browser windows if starting up in "background mode". - if (command_line.HasSwitch(switches::kNoStartupWindow)) - return false; - -#if BUILDFLAG(IS_CHROMEOS_LACROS) - // Don't open any browser windows if Ash requested that Lacros not do so. - // The implicit assumption is that some other code is responsible for - // keeping Lacros running in the background. - // Temporarily remove this logic to deal with https://crbug.com/1278549. -#endif - -#if BUILDFLAG(IS_CHROMEOS_ASH) - // If Lacros is the primary web browser, do not open the browser window - // on Chrome OS session login. - if (crosapi::browser_util::IsLacrosPrimaryBrowser()) - return false; -#endif - - return true; -} - -// static bool StartupBrowserCreatorImpl::IsKioskModeEnabled() { return base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kKioskMode);
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.h b/chrome/browser/ui/startup/startup_browser_creator_impl.h index 99195f4..bd741f62 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.h +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.h
@@ -98,7 +98,6 @@ DetermineBrowserOpenBehavior_NotStartup); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest, DetermineStartupTabs_NewFeaturesPage); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest, ShouldLaunch); enum class LaunchResult { kNormally, @@ -199,9 +198,6 @@ bool has_create_browser_switch, bool was_mac_login_or_resume); - // Returns whether or not a browser window should be created/restored. - static bool ShouldLaunch(const base::CommandLine& command_line); - // Returns whether `switches::kKioskMode` is set on the command line of // the current process. This is a static method to avoid accidentally reading // it from `command_line_`.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc index 70dbe0c..543e2e6 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc
@@ -13,10 +13,6 @@ #include "chrome/common/url_constants.h" #include "testing/gtest/include/gtest/gtest.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/ash/crosapi/browser_util.h" -#endif - using Creator = StartupBrowserCreatorImpl; namespace { @@ -537,29 +533,3 @@ output = Creator::DetermineBrowserOpenBehavior(pref_urls, 0); EXPECT_EQ(Creator::BrowserOpenBehavior::NEW, output); } - -TEST(StartupBrowserCreatorImplTest, ShouldLaunch) { -#if BUILDFLAG(IS_CHROMEOS_ASH) - // Forcibly set ash-chrome as the primary browser. - // This is the current default behavior. - crosapi::browser_util::SetLacrosPrimaryBrowserForTest(false); -#endif - - EXPECT_TRUE(StartupBrowserCreatorImpl::ShouldLaunch( - base::CommandLine(base::CommandLine::NO_PROGRAM))); - { - base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - command_line.AppendSwitch(switches::kNoStartupWindow); - EXPECT_FALSE(StartupBrowserCreatorImpl::ShouldLaunch(command_line)); - } - -#if BUILDFLAG(IS_CHROMEOS_ASH) - // Check what happens if lacros-chrome becomes the primary browser. - crosapi::browser_util::SetLacrosPrimaryBrowserForTest(true); - EXPECT_FALSE(StartupBrowserCreatorImpl::ShouldLaunch( - base::CommandLine(base::CommandLine::NO_PROGRAM))); - - // Restore the global testing set up. - crosapi::browser_util::SetLacrosPrimaryBrowserForTest(absl::nullopt); -#endif -}
diff --git a/chrome/browser/ui/startup/startup_browser_creator_unittest.cc b/chrome/browser/ui/startup/startup_browser_creator_unittest.cc new file mode 100644 index 0000000..50b2c27 --- /dev/null +++ b/chrome/browser/ui/startup/startup_browser_creator_unittest.cc
@@ -0,0 +1,42 @@ +// Copyright 2022 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/startup/startup_browser_creator.h" + +#include "base/command_line.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/common/chrome_switches.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/crosapi/browser_util.h" +#endif + +TEST(StartupBrowserCreatorTest, ShouldLoadProfileWithoutWindow) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Forcibly set ash-chrome as the primary browser. + // This is the current default behavior. + crosapi::browser_util::SetLacrosPrimaryBrowserForTest(false); +#endif + + EXPECT_FALSE(StartupBrowserCreator::ShouldLoadProfileWithoutWindow( + base::CommandLine(base::CommandLine::NO_PROGRAM))); + { + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitch(switches::kNoStartupWindow); + EXPECT_TRUE( + StartupBrowserCreator::ShouldLoadProfileWithoutWindow(command_line)); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Check what happens if lacros-chrome becomes the primary browser. + crosapi::browser_util::SetLacrosPrimaryBrowserForTest(true); + EXPECT_TRUE(StartupBrowserCreator::ShouldLoadProfileWithoutWindow( + base::CommandLine(base::CommandLine::NO_PROGRAM))); + + // Restore the global testing set up. + crosapi::browser_util::SetLacrosPrimaryBrowserForTest(absl::nullopt); +#endif +}
diff --git a/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.cc b/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.cc index d493948..1011752f 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.cc
@@ -63,8 +63,7 @@ UpdateReadiness(Readiness::kReadyForInitialCapture); } -void ThumbnailReadinessTracker::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void ThumbnailReadinessTracker::DocumentOnLoadCompletedInPrimaryMainFrame() { UpdateReadiness(Readiness::kReadyForFinalCapture); }
diff --git a/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.h b/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.h index c0e7e99..73f5fa2 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.h +++ b/chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.h
@@ -30,8 +30,7 @@ content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void WebContentsDestroyed() override; private:
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc index d625b3e9..fb54358 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc
@@ -53,7 +53,6 @@ namespace { using extensions::mojom::ManifestLocation; -using ActionType = extensions::ExtensionBuilder::ActionType; // A simple observer that tracks the number of times certain events occur. class ToolbarActionsModelTestObserver : public ToolbarActionsModel::Observer { @@ -254,12 +253,13 @@ } testing::AssertionResult ToolbarActionsModelUnitTest::AddActionExtensions() { - browser_action_extension_ = extensions::ExtensionBuilder("browser_action") - .SetAction(ActionType::BROWSER_ACTION) - .SetLocation(ManifestLocation::kInternal) - .Build(); + browser_action_extension_ = + extensions::ExtensionBuilder("browser_action") + .SetAction(extensions::ActionInfo::TYPE_BROWSER) + .SetLocation(ManifestLocation::kInternal) + .Build(); page_action_extension_ = extensions::ExtensionBuilder("page_action") - .SetAction(ActionType::PAGE_ACTION) + .SetAction(extensions::ActionInfo::TYPE_PAGE) .SetLocation(ManifestLocation::kInternal) .Build(); no_action_extension_ = extensions::ExtensionBuilder("no_action") @@ -277,15 +277,15 @@ testing::AssertionResult ToolbarActionsModelUnitTest::AddBrowserActionExtensions() { browser_action_a_ = extensions::ExtensionBuilder("browser_actionA") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); browser_action_b_ = extensions::ExtensionBuilder("browser_actionB") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); browser_action_c_ = extensions::ExtensionBuilder("browser_actionC") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); @@ -329,7 +329,7 @@ // Load an extension with a browser action. scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("browser_action") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); ASSERT_TRUE(AddExtension(extension)); @@ -356,17 +356,17 @@ // Three extensions with actions. scoped_refptr<const extensions::Extension> extension_a = extensions::ExtensionBuilder("a") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); scoped_refptr<const extensions::Extension> extension_b = extensions::ExtensionBuilder("b") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); scoped_refptr<const extensions::Extension> extension_c = extensions::ExtensionBuilder("c") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); @@ -967,7 +967,7 @@ scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("extension") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .Build(); @@ -1017,7 +1017,7 @@ scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("test") - .SetAction(ActionType::BROWSER_ACTION) + .SetAction(extensions::ActionInfo::TYPE_BROWSER) .SetLocation(ManifestLocation::kInternal) .SetID(extension_id) .Build();
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 181532e..29616fa 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -227,7 +227,7 @@ #if !defined(ANDROID) const base::Feature kWebUIBrandingUpdate{"WebUIBrandingUpdate", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #endif // Enables the WebUI Download Shelf instead of the Views framework Download
diff --git a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc index 71c91c3..db43d8c 100644 --- a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc
@@ -283,8 +283,6 @@ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_REPORT_ABUSE)); report_abuse_checkbox->SetMultiLine(true); report_abuse_checkbox_ = AddChildView(std::move(report_abuse_checkbox)); - } else if (extension->from_bookmark()) { - InitializeCheckbox(extensions::AppLaunchInfo::GetFullLaunchURL(extension)); } }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc index d35c2c0..aac66601 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
@@ -24,10 +24,7 @@ } AppInfoPanel::AppInfoPanel(Profile* profile, const extensions::Extension* app) - : profile_(profile), app_(app) { - // Bookmark Apps have been replaced by Web Apps. - DCHECK(!app_->from_bookmark()); -} + : profile_(profile), app_(app) {} AppInfoPanel::~AppInfoPanel() { }
diff --git a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc index 658ff0f..0ba2e3a 100644 --- a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc +++ b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
@@ -87,8 +87,7 @@ gfx::Size CalculatePreferredSize() const override; gfx::Size GetMinimumSize() const override; gfx::Size GetMaximumSize() const override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; private: base::WeakPtr<content::WebContents> initiator_web_contents_; @@ -483,8 +482,7 @@ return !max_size().IsEmpty() ? max_size() : WebView::GetMaximumSize(); } -void ConstrainedDialogWebView::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void ConstrainedDialogWebView::DocumentOnLoadCompletedInPrimaryMainFrame() { if (!max_size().IsEmpty() && initiator_web_contents_) { content::WebContents* top_level_web_contents = constrained_window::GetTopLevelWebContents(
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view_browsertest.cc index 7d56d863..dafc3f7 100644 --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/extensions/extension_install_ui_default.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "content/public/test/browser_test.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension_builder.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" @@ -34,10 +35,9 @@ extensions::ExtensionBuilder builder(type); if (type == "BrowserAction") { - builder.SetAction( - extensions::ExtensionBuilder::ActionType::BROWSER_ACTION); + builder.SetAction(extensions::ActionInfo::TYPE_BROWSER); } else if (type == "PageAction") { - builder.SetAction(extensions::ExtensionBuilder::ActionType::PAGE_ACTION); + builder.SetAction(extensions::ActionInfo::TYPE_PAGE); } if (type == "SignInPromo" || type == "NoAction") {
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc index 98f01dd7..50805c8 100644 --- a/chrome/browser/ui/views/extensions/extension_popup.cc +++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -170,8 +170,7 @@ } } -void ExtensionPopup::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void ExtensionPopup::DocumentOnLoadCompletedInPrimaryMainFrame() { // Show when the content finishes loading and its width is computed. ShowBubble(); Observe(nullptr);
diff --git a/chrome/browser/ui/views/extensions/extension_popup.h b/chrome/browser/ui/views/extensions/extension_popup.h index 8378430..9b69a00 100644 --- a/chrome/browser/ui/views/extensions/extension_popup.h +++ b/chrome/browser/ui/views/extensions/extension_popup.h
@@ -106,8 +106,7 @@ extensions::UnloadedExtensionReason reason) override; // content::WebContentsObserver: - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; // TabStripModelObserver: void OnTabStripModelChanged(
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc index 2f177341..9cbb3920 100644 --- a/chrome/browser/ui/views/find_bar_host.cc +++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -147,7 +147,7 @@ case ui::VKEY_END: if (key_event.IsControlDown()) break; - FALLTHROUGH; + [[fallthrough]]; default: return false; }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc index c5188f3..c48a4a0 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/tablet_state.h" #include "chromeos/ui/base/window_properties.h" @@ -268,16 +269,17 @@ SkColor fallback_color = chromeos::kDefaultFrameColor; + if (chromeos::features::IsDarkLightModeEnabled() && GetWidget()) { #if BUILDFLAG(IS_CHROMEOS_ASH) - // TODO(crbug.com/1278862): make these features available in Lacros. - if (ash::features::IsDarkLightModeEnabled() && GetWidget()) { + bool use_debug_colors = base::FeatureList::IsEnabled( + ash::features::kSemanticColorsDebugOverride); +#else + bool use_debug_colors = false; +#endif fallback_color = cros_styles::ResolveColor( cros_styles::ColorName::kBgColor, - GetNativeTheme()->ShouldUseDarkColors(), - base::FeatureList::IsEnabled( - ash::features::kSemanticColorsDebugOverride)); + GetNativeTheme()->ShouldUseDarkColors(), use_debug_colors); } -#endif return color.value_or(fallback_color); }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 583cb40..aeb6825 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -619,9 +619,15 @@ void OnAXModeAdded(ui::AXMode mode) override { // This will have the effect of turning tablet mode off if a screen reader // is enabled while Chrome is already open. It will not return the browser - // to tablet mode if the user kills their screen reader. - if (mode.has_mode(ui::AXMode::kScreenReader)) - browser_view_->MaybeInitializeWebUITabStrip(); + // to tablet mode if the user kills their screen reader. This has to happen + // asynchronously since AXMode changes can happen while AXTree updates or + // notifications are in progress, and |MaybeInitializeWebUITabStrip| can + // destroy things synchronously. + if (mode.has_mode(ui::AXMode::kScreenReader)) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&BrowserView::MaybeInitializeWebUITabStrip, + browser_view_->GetAsWeakPtr())); + } } const raw_ptr<BrowserView> browser_view_;
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc b/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc index 553f702..48e3fdd 100644 --- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc +++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc
@@ -54,6 +54,14 @@ params.remove_standard_frame = UseCustomFrame(); params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; + if ((browser.is_type_app() || browser.is_type_app_popup()) && + browser.profile()) { + params.wayland_app_id = shell_integration_linux::GetXdgAppIdForWebApp( + browser.app_name(), browser.profile()->GetPath()); + } else { + params.wayland_app_id = params.wm_class_name; + } + return params; }
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc index 972f475..0749800f 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -496,17 +496,16 @@ void IntentPickerBubbleView::UpdateCheckboxState() { if (!remember_selection_checkbox_) return; - // TODO(crbug.com/826982): allow PWAs to have their decision persisted when - // there is a central Chrome OS apps registry to store persistence. - // TODO(crbug.com/1000037): allow to persist remote devices too. - bool should_enable = false; - if (base::FeatureList::IsEnabled(features::kIntentPickerPWAPersistence)) { - should_enable = true; - } else { - auto selected_app_type = app_info_[selected_app_tag_].type; - should_enable = selected_app_type != apps::PickerEntryType::kWeb && - selected_app_type != apps::PickerEntryType::kDevice; + auto selected_app_type = app_info_[selected_app_tag_].type; + bool should_enable = true; + if (selected_app_type == apps::PickerEntryType::kDevice) { + // TODO(crbug.com/1000037): Allow persisting remote devices. + should_enable = false; + } else if (selected_app_type == apps::PickerEntryType::kWeb) { + should_enable = + base::FeatureList::IsEnabled(features::kIntentPickerPWAPersistence); } + // Reset the checkbox state to the default unchecked if becomes disabled. if (!should_enable) remember_selection_checkbox_->SetChecked(false);
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.h b/chrome/browser/ui/views/intent_picker_bubble_view.h index 017d8e2..cb708bcd 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.h +++ b/chrome/browser/ui/views/intent_picker_bubble_view.h
@@ -121,6 +121,7 @@ FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, WebContentsTiedToBubble); FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, WindowTitle); FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, ButtonLabels); + FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, RememberCheckbox); FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTest, DoubleClickOpensApp); FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_unittest.cc b/chrome/browser/ui/views/intent_picker_bubble_view_unittest.cc index 11498d0..0c0c66a 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view_unittest.cc
@@ -9,12 +9,14 @@ #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/intent_helper/apps_navigation_types.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/test_with_browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/views/chrome_views_test_base.h" #include "content/public/browser/web_contents.h" @@ -27,6 +29,7 @@ #include "ui/strings/grit/ui_strings.h" #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/resources/grit/views_resources.h" #include "url/gurl.h" @@ -124,6 +127,14 @@ views::BubbleDialogDelegateView::CreateBubble(std::move(bubble)); } + // Add an app to the bubble opened by CreateBubbleView. Manually added apps + // will appear before automatic placeholder apps. + void AddApp(apps::PickerEntryType app_type, + const std::string& launch_name, + const std::string& title) { + app_info_.emplace_back(app_type, ui::ImageModel(), launch_name, title); + } + void FillAppListWithDummyIcons() { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); ui::ImageModel dummy_icon_model = @@ -314,3 +325,31 @@ const int children_with_same_origin = bubble_->children().size(); EXPECT_EQ(children_without_origin, children_with_same_origin); } + +TEST_F(IntentPickerBubbleViewTest, RememberCheckbox) { + AddApp(apps::PickerEntryType::kDevice, "device_id", "Android Phone"); + AddApp(apps::PickerEntryType::kWeb, "web_app_id", "Web App"); + AddApp(apps::PickerEntryType::kArc, "arc_app_id", "Arc App"); + + CreateBubbleView(/*use_icons=*/false, /*show_stay_in_chrome=*/false, + PageActionIconType::kIntentPicker, + /*initiating_origin=*/absl::nullopt); + + const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), 0, 0); + + // kDevice entries should not allow persistence. + bubble_->PressButtonForTesting(0, event); + ASSERT_FALSE(bubble_->remember_selection_checkbox_->GetEnabled()); + + // kWeb entries should allow persistence when kIntentPickerPWAPersistence is + // enabled. + bubble_->PressButtonForTesting(1, event); + ASSERT_EQ( + bubble_->remember_selection_checkbox_->GetEnabled(), + base::FeatureList::IsEnabled(features::kIntentPickerPWAPersistence)); + + // Other app types can be persisted. + bubble_->PressButtonForTesting(2, event); + ASSERT_TRUE(bubble_->remember_selection_checkbox_->GetEnabled()); +}
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 9635ae9..d575bf7 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -1024,6 +1024,15 @@ views::Widget::OnNativeBlur(); } +void OverlayWindowViews::OnNativeWidgetDestroying() { + views::Widget::OnNativeWidgetDestroying(); + if (has_registered_frame_sink_hierarchy_) { + DCHECK(GetCurrentFrameSinkId()); + GetCompositor()->RemoveChildFrameSink(*GetCurrentFrameSinkId()); + has_registered_frame_sink_hierarchy_ = false; + } +} + void OverlayWindowViews::OnNativeWidgetDestroyed() { views::Widget::OnNativeWidgetDestroyed(); controller_->OnWindowDestroyed( @@ -1072,6 +1081,26 @@ // does not trigger this function. http://crbug.com/819673 } +// When the PiP window is moved to different displays on Chrome OS, we need to +// re-parent the frame sink since the compositor will change. After +// OnNativeWidgetRemovingFromCompositor() is called, the window layer containing +// the compositor will be removed in Window::RemoveChildImpl(), and +// OnNativeWidgetAddedToCompositor() is called once another compositor is added. +void OverlayWindowViews::OnNativeWidgetAddedToCompositor() { + if (!has_registered_frame_sink_hierarchy_ && GetCurrentFrameSinkId()) { + GetCompositor()->AddChildFrameSink(*GetCurrentFrameSinkId()); + has_registered_frame_sink_hierarchy_ = true; + } +} + +void OverlayWindowViews::OnNativeWidgetRemovingFromCompositor() { + if (has_registered_frame_sink_hierarchy_) { + DCHECK(GetCurrentFrameSinkId()); + GetCompositor()->RemoveChildFrameSink(*GetCurrentFrameSinkId()); + has_registered_frame_sink_hierarchy_ = false; + } +} + void OverlayWindowViews::OnKeyEvent(ui::KeyEvent* event) { // Every time a user uses a keyboard to interact on the window, restart the // timer to automatically hide the controls.
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h index 2e67353dd..229b618 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.h +++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -69,12 +69,15 @@ bool IsVisible() const override; void OnNativeFocus() override; void OnNativeBlur() override; + void OnNativeWidgetDestroying() override; void OnNativeWidgetDestroyed() override; gfx::Size GetMinimumSize() const override; gfx::Size GetMaximumSize() const override; void OnNativeWidgetMove() override; void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override; void OnNativeWidgetWorkspaceChanged() override; + void OnNativeWidgetAddedToCompositor() override; + void OnNativeWidgetRemovingFromCompositor() override; void OnKeyEvent(ui::KeyEvent* event) override; void OnMouseEvent(ui::MouseEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc index 29718178..5ae200d 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc
@@ -137,7 +137,7 @@ switch (result) { case autofill::AutofillClient::PaymentsRpcResult::kNone: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case autofill::AutofillClient::PaymentsRpcResult::kSuccess: // In the success case, don't show any error and don't hide the spinner // because the dialog is about to close when the merchant completes the
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index 508ee1e..75693bf 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -34,7 +34,6 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -349,8 +348,6 @@ return; } - DCHECK(FrameSupportsPayments(navigation_handle->GetRenderFrameHost())); - if (first_navigation_complete_callback_) { std::move(first_navigation_complete_callback_) .Run(true, web_contents()->GetMainFrame()->GetProcess()->GetID(), @@ -372,13 +369,6 @@ UpdateHeaderView(); } -bool PaymentHandlerWebFlowViewController::FrameSupportsPayments( - content::RenderFrameHost* rfh) const { - return rfh && rfh->IsActive() && - rfh->IsFeatureEnabled( - blink::mojom::PermissionsPolicyFeature::kPayment); -} - void PaymentHandlerWebFlowViewController::AbortPayment() { if (web_contents()) web_contents()->Close();
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h index 1f3cb61..f221cfd 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
@@ -21,7 +21,6 @@ namespace content { class Page; -class RenderFrameHost; } // namespace content namespace views { @@ -96,8 +95,6 @@ void LoadProgressChanged(double progress) override; void TitleWasSet(content::NavigationEntry* entry) override; - bool FrameSupportsPayments(content::RenderFrameHost* rfh) const; - void AbortPayment(); DeveloperConsoleLogger log_;
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc index 88da9cc..abfb94d 100644 --- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -1040,13 +1040,17 @@ https_server()->GetURL("a.com", "/payment_request_main.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - // The iframe calls show() immediately. content::WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); GURL iframe_url = https_server()->GetURL("b.com", "/payment_request_iframe.html"); - ResetEventWaiterForDialogOpened(); EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url)); + + content::RenderFrameHost* iframe = content::FrameMatchingPredicate( + tab->GetPrimaryPage(), + base::BindRepeating(&content::FrameHasSourceUrl, iframe_url)); + ResetEventWaiterForDialogOpened(); + EXPECT_TRUE(content::ExecJs(iframe, "triggerPaymentRequest()")); WaitForObservedEvent(); // Simulate that the user cancels the PR.
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc index ce34085..ae2568e38 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc
@@ -130,13 +130,8 @@ void SendTabToSelfBubbleViewImpl::Init() { auto* provider = ChromeLayoutProvider::Get(); - const bool create_hint_text_label = - base::FeatureList::IsEnabled(send_tab_to_self::kSendTabToSelfV2) || - share::AreUpcomingSharingFeaturesEnabled(); const int top_margin = provider->GetDistanceMetric( - create_hint_text_label - ? views::DISTANCE_DIALOG_CONTENT_MARGIN_TOP_TEXT - : views::DISTANCE_DIALOG_CONTENT_MARGIN_TOP_CONTROL); + views::DISTANCE_DIALOG_CONTENT_MARGIN_TOP_TEXT); const bool create_manage_devices_link = base::FeatureList::IsEnabled( send_tab_to_self::kSendTabToSelfManageDevicesLink); const int bottom_margin = @@ -149,9 +144,7 @@ SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - if (create_hint_text_label) - CreateHintTextLabel(); - + CreateHintTextLabel(); CreateDevicesScrollView(); if (create_manage_devices_link) {
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc index 5511604..8709b67 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "components/send_tab_to_self/features.h" #include "components/send_tab_to_self/target_device_info.h" #include "components/signin/public/identity_manager/account_info.h" #include "content/public/test/browser_test.h" @@ -54,13 +53,9 @@ } // namespace -class SendTabToSelfBubbleTest : public DialogBrowserTest, - public testing::WithParamInterface<bool> { +class SendTabToSelfBubbleTest : public DialogBrowserTest { public: - SendTabToSelfBubbleTest() { - scoped_feature_list_.InitWithFeatureState( - send_tab_to_self::kSendTabToSelfV2, GetParam()); - } + SendTabToSelfBubbleTest() = default; SendTabToSelfBubbleTest(const SendTabToSelfBubbleTest&) = delete; SendTabToSelfBubbleTest& operator=(const SendTabToSelfBubbleTest&) = delete; @@ -77,9 +72,6 @@ BrowserView::GetBrowserViewForBrowser(browser())->ShowSendTabToSelfBubble( web_contents, controller, true); } - - private: - base::test::ScopedFeatureList scoped_feature_list_; }; // crbug.com/1272360 @@ -88,12 +80,8 @@ #else #define MAYBE_InvokeUi_default InvokeUi_default #endif -IN_PROC_BROWSER_TEST_P(SendTabToSelfBubbleTest, MAYBE_InvokeUi_default) { +IN_PROC_BROWSER_TEST_F(SendTabToSelfBubbleTest, MAYBE_InvokeUi_default) { ShowAndVerifyUi(); } -INSTANTIATE_TEST_SUITE_P(All, - SendTabToSelfBubbleTest, - ::testing::Values(false, true)); - } // namespace send_tab_to_self
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_util.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_util.cc index 01afd0f..0e05fbc 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_util.cc +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_util.cc
@@ -43,7 +43,7 @@ views::Builder<views::ImageButton>( views::CreateVectorImageButtonWithNativeTheme( std::move(back_callback), vector_icons::kBackArrowIcon)) - .SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK)) + .SetTooltipText(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK)) .SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK)) .CustomConfigure(base::BindOnce([](views::ImageButton* view) { view->SizeToPreferredSize();
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc index edf8b70..0949e45 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
@@ -455,11 +455,6 @@ const bool can_show_side_panel_for_page = tab_contents_helper->CanShowSidePanelForCommittedNavigation(); - if (can_show_side_panel_for_page && - tab_contents_helper->returned_to_previous_srp()) { - browser_view_->feature_promo_controller()->MaybeShowPromo( - feature_engagement::kIPHSideSearchFeature); - } const bool will_show_side_panel = can_show_side_panel_for_page && GetSidePanelToggledOpen(); @@ -484,6 +479,13 @@ : SideSearchAvailabilityChangeType::kBecomeUnavailable); } + // Once the anchor element is visible, maybe show promo. + if (can_show_side_panel_for_page && + tab_contents_helper->returned_to_previous_srp()) { + browser_view_->feature_promo_controller()->MaybeShowPromo( + feature_engagement::kIPHSideSearchFeature); + } + browser_view_->InvalidateLayout(); }
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 57fe65b..a3f3655 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -751,7 +751,7 @@ case TabAlertState::PIP_PLAYING: if (color_utils::IsDark(foreground_color_)) return gfx::kGoogleBlue600; - FALLTHROUGH; + [[fallthrough]]; case TabAlertState::AUDIO_PLAYING: case TabAlertState::AUDIO_MUTING: case TabAlertState::BLUETOOTH_CONNECTED:
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index ee5ab23..7da521c7 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -961,7 +961,7 @@ // Convert back to full bounds. It's OK that the outer corners of the curves // around the separator may not be snapped to the pixel grid as a result. - aligned_bounds.Inset(-layout_insets.Scale(scale)); + aligned_bounds.Inset(-gfx::ScaleInsets(layout_insets, scale)); return aligned_bounds; }
diff --git a/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc b/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc index cfc7566e..58ee6c4 100644 --- a/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/app_menu_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/callback_helpers.h" #include "base/files/file_path.h" +#include "build/chromeos_buildflags.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/sessions/tab_restore_service_load_waiter.h" #include "chrome/browser/ui/browser.h" @@ -38,7 +39,13 @@ // properly (this was triggering a crash in AppMenu where it was trying to make // use of RecentTabsMenuModelDelegate before created). See // https://crbug.com/1249741 for more. -IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, ShowWithRecentlyClosedWindow) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) +// TODO(crbug.com/1284776): Re-enable once flakiness is fixed. +#define MAYBE_ShowWithRecentlyClosedWindow DISABLED_ShowWithRecentlyClosedWindow +#else +#define MAYBE_ShowWithRecentlyClosedWindow ShowWithRecentlyClosedWindow +#endif +IN_PROC_BROWSER_TEST_F(AppMenuBrowserTest, MAYBE_ShowWithRecentlyClosedWindow) { // Create an additional browser, close it, and ensure it is added to the // TabRestoreService. sessions::TabRestoreService* tab_restore_service =
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index f0709d5..fb50065e 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -272,9 +272,7 @@ std::unique_ptr<send_tab_to_self::SendTabToSelfToolbarIconView> send_tab_to_self_button; - if ((base::FeatureList::IsEnabled(send_tab_to_self::kSendTabToSelfV2) || - share::AreUpcomingSharingFeaturesEnabled()) && - !browser_->profile()->IsOffTheRecord()) { + if (!browser_->profile()->IsOffTheRecord()) { send_tab_to_self_button = std::make_unique<send_tab_to_self::SendTabToSelfToolbarIconView>( browser_view_);
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 248a9c9..7c927e8 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -1377,19 +1377,12 @@ bool WebAppIntegrationTestDriver::AreNoAppWindowsOpen(Profile* profile, const AppId& app_id) { - auto* provider = GetProviderForProfile(profile); - const GURL& app_scope = provider->registrar().GetAppScope(app_id); auto* browser_list = BrowserList::GetInstance(); for (Browser* browser : *browser_list) { - if (browser->IsAttemptingToCloseBrowser()) { + if (browser->IsAttemptingToCloseBrowser()) continue; - } - const GURL& browser_url = - browser->tab_strip_model()->GetActiveWebContents()->GetURL(); - if (AppBrowserController::IsWebApp(browser) && - IsInScope(browser_url, app_scope)) { + if (AppBrowserController::IsForWebApp(browser, app_id)) return false; - } } return true; }
diff --git a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc index a570686d..90afc8d 100644 --- a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
@@ -194,7 +194,8 @@ // Expect manifest background color prior to page loading. { - ASSERT_FALSE(app.web_contents->IsDocumentOnLoadCompletedInMainFrame()); + ASSERT_FALSE( + app.web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); EXPECT_EQ(app.browser->app_controller()->GetBackgroundColor().value(), kAppBackgroundColor); EXPECT_EQ(GetTabColor(app.browser_view), kAppBackgroundColor);
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc index 68db7a40..817cc7c 100644 --- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc
@@ -176,15 +176,16 @@ } void WebAppUninstallDialogDelegateView::ClearWebAppSiteData() { - content::ClearSiteData( - base::BindRepeating( - [](content::BrowserContext* browser_context) { - return browser_context; - }, - base::Unretained(profile_)), - url::Origin::Create(app_start_url_), /*clear_cookies=*/true, - /*clear_storage=*/true, /*clear_cache=*/true, - /*avoid_closing_connections=*/false, base::DoNothing()); + content::ClearSiteData(base::BindRepeating( + [](content::BrowserContext* browser_context) { + return browser_context; + }, + base::Unretained(profile_)), + url::Origin::Create(app_start_url_), + /*clear_cookies=*/true, + /*clear_storage=*/true, /*clear_cache=*/true, + /*avoid_closing_connections=*/false, + net::CookiePartitionKey::Todo(), base::DoNothing()); } void WebAppUninstallDialogDelegateView::ProcessAutoConfirmValue() {
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index b62561e..c9e1c42 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -304,6 +304,14 @@ EXPECT_EQ(provider->registrar().GetAppBackgroundColor(app_id), SK_ColorBLUE); } +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, ShortcutBackgroundColor) { + const GURL app_url = https_server()->GetURL("/banners/background-color.html"); + const AppId app_id = InstallWebAppFromPage(browser(), app_url); + auto* provider = WebAppProvider::GetForTest(profile()); + + EXPECT_EQ(provider->registrar().GetAppBackgroundColor(app_id), SK_ColorBLUE); +} + // Base class for background color change browser tests parameterized by whether // to use a SWA or a non-SWA. class WebAppBackgroundColorChangeBrowserTest
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc index 7074c1964..80ffba6d 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -219,8 +219,7 @@ extensions::ExtensionRegistry::Get(browser->profile()) ->GetExtensionById(app_id, extensions::ExtensionRegistry::EVERYTHING); - if (extension && extension->is_hosted_app() && - !extension->from_bookmark()) { + if (extension && extension->is_hosted_app()) { controller = std::make_unique<extensions::HostedAppBrowserController>(browser); }
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 8bf7668..c72d362 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -207,7 +207,7 @@ #include "chrome/browser/ash/web_applications/chrome_file_manager_ui_delegate.h" #include "chrome/browser/ash/web_applications/help_app/help_app_ui_delegate.h" #include "chrome/browser/ash/web_applications/media_app/chrome_media_app_ui_delegate.h" -#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.h" +#include "chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_wallpaper_provider.h" #include "chrome/browser/feedback/feedback_dialog_utils.h" #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h" #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h" @@ -961,7 +961,7 @@ if (url.host_piece() == ash::kChromeUIPersonalizationAppHost && chromeos::features::IsWallpaperWebUIEnabled()) { return &NewComponentUI<ash::PersonalizationAppUI, - ChromePersonalizationAppUiDelegate>; + ChromePersonalizationAppWallpaperProvider>; } if (url.host_piece() == ash::kChromeUISystemExtensionsInternalsHost && base::FeatureList::IsEnabled(ash::features::kSystemExtensions)) {
diff --git a/chrome/browser/ui/webui/chromeos/shimless_rma_dialog.cc b/chrome/browser/ui/webui/chromeos/shimless_rma_dialog.cc index 3b422d9..e0c8338f 100644 --- a/chrome/browser/ui/webui/chromeos/shimless_rma_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/shimless_rma_dialog.cc
@@ -38,6 +38,8 @@ void ShimlessRmaDialog::AdjustWidgetInitParams( views::Widget::InitParams* params) { + // This overrides the class name so TAST tests can find the root node. + params->name = "ShimlessRmaDialogView"; params->type = views::Widget::InitParams::Type::TYPE_WINDOW_FRAMELESS; params->visible_on_all_workspaces = true; params->corner_radius = 0;
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc index cfde53d..6f4118cd 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
@@ -109,6 +109,12 @@ web_contents->Resize(gfx::Rect(0, 0, 400, 400)); } +void ExtensionSettingsUIBrowserTest:: + SetSilenceDeprecatedManifestVersionWarnings(bool silence) { + Extension::set_silence_deprecated_manifest_version_warnings_for_testing( + silence); +} + const Extension* ExtensionSettingsUIBrowserTest::InstallExtension( const base::FilePath& path) { extensions::ChromeTestExtensionLoader loader(browser()->profile());
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h index 1ea13027..5c1dc450 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h
@@ -60,6 +60,9 @@ // Shrinks the web contents view in order to ensure vertical overflow. void ShrinkWebContentsView(); + // Sets whether to ignore errors for deprecated manifest versions. + void SetSilenceDeprecatedManifestVersionWarnings(bool silence); + const base::FilePath& test_data_dir() { return test_data_dir_; } private:
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 32f9805..1c3a3b2 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -59,8 +59,7 @@ constexpr char kInDevModeKey[] = "inDevMode"; constexpr char kShowActivityLogKey[] = "showActivityLog"; constexpr char kLoadTimeClassesKey[] = "loadTimeClasses"; -constexpr char kExtensionsMenuAccessControlEnabled[] = - "extensionsMenuAccessControlEnabled"; +constexpr char kEnableEnhancedSiteControls[] = "enableEnhancedSiteControls"; std::string GetLoadTimeClasses(bool in_dev_mode) { return in_dev_mode ? "in-dev-mode" : std::string(); @@ -242,6 +241,8 @@ {"packDialogKeyFile", IDS_EXTENSIONS_PACK_DIALOG_KEY_FILE_LABEL}, {"packDialogContent", IDS_EXTENSION_PACK_DIALOG_HEADING}, {"packDialogConfirm", IDS_EXTENSIONS_PACK_DIALOG_CONFIRM_BUTTON}, + {"sitePermissions", IDS_EXTENSIONS_SITE_PERMISSIONS}, + {"sitePermissionsPageTitle", IDS_EXTENSIONS_SITE_PERMISSIONS_PAGE_TITLE}, {"editShortcut", IDS_EXTENSIONS_EDIT_SHORTCUT}, {"shortcutNotSet", IDS_EXTENSIONS_SHORTCUT_NOT_SET}, {"shortcutScopeGlobal", IDS_EXTENSIONS_SHORTCUT_SCOPE_GLOBAL}, @@ -335,7 +336,7 @@ source->AddString(kLoadTimeClassesKey, GetLoadTimeClasses(in_dev_mode)); source->AddBoolean( - kExtensionsMenuAccessControlEnabled, + kEnableEnhancedSiteControls, base::FeatureList::IsEnabled(features::kExtensionsMenuAccessControl)); return source;
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index cfe3a3e7..03e99b9 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -128,23 +128,26 @@ bool strict_enforcement = false; base::Time time_triggered_ = base::Time::NowFromSystemTime(); std::string url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "url", + &url_param)) { if (GURL(url_param).is_valid()) { request_url = GURL(url_param); } } std::string overridable_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "overridable", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "overridable", &overridable_param)) { overridable = overridable_param == "1"; } std::string strict_enforcement_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "strict_enforcement", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), + "strict_enforcement", &strict_enforcement_param)) { strict_enforcement = strict_enforcement_param == "1"; } std::string type_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "type", + &type_param)) { if (type_param == "hpkp_failure") { cert_error = net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; } else if (type_param == "ct_failure") { @@ -175,7 +178,7 @@ bool is_enterprise_managed = false; std::string is_enterprise_managed_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "enterprise", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "enterprise", &is_enterprise_managed_param)) { is_enterprise_managed = is_enterprise_managed_param == "1"; } @@ -208,7 +211,8 @@ int cert_error = net::ERR_CERT_DATE_INVALID; GURL request_url("https://example.com"); std::string url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param) && + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "url", + &url_param) && GURL(url_param).is_valid()) { request_url = GURL(url_param); } @@ -216,7 +220,8 @@ // Determine whether to change the clock to be ahead or behind. std::string clock_manipulation_param; ssl_errors::ClockState clock_state = ssl_errors::CLOCK_STATE_PAST; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "clock_manipulation", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), + "clock_manipulation", &clock_manipulation_param)) { int time_offset; if (base::StringToInt(clock_manipulation_param, &time_offset)) { @@ -239,7 +244,7 @@ GURL request_url("https://example.net"); GURL safe_url("https://example.com"); std::string url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "no-safe-url", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "no-safe-url", &url_param)) { safe_url = GURL(); } @@ -274,7 +279,8 @@ safe_browsing::SB_THREAT_TYPE_URL_MALWARE; GURL request_url("http://example.com"); std::string url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "url", + &url_param)) { if (GURL(url_param).is_valid()) { request_url = GURL(url_param); } @@ -283,7 +289,8 @@ // TODO(mattm): add flag to change main_frame_url or add dedicated flag to // test subresource interstitials. std::string type_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "type", + &type_param)) { if (type_param == "malware") { threat_type = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; } else if (type_param == "phishing") { @@ -331,14 +338,16 @@ safe_browsing::SB_THREAT_TYPE_URL_MALWARE; GURL request_url("http://example.com"); std::string url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "url", + &url_param)) { if (GURL(url_param).is_valid()) request_url = GURL(url_param); } GURL main_frame_url(request_url); std::string type_param; bool is_giant_webview = false; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "type", + &type_param)) { if (type_param == "malware") { threat_type = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; } else if (type_param == "phishing") { @@ -389,24 +398,24 @@ std::string wifi_ssid; std::string request_url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "url", &request_url_param)) { if (GURL(request_url_param).is_valid()) request_url = GURL(request_url_param); } std::string landing_url_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "landing_page", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "landing_page", &landing_url_param)) { if (GURL(landing_url_param).is_valid()) landing_url = GURL(landing_url_param); } std::string wifi_connection_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "is_wifi", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "is_wifi", &wifi_connection_param)) { is_wifi_connection = wifi_connection_param == "1"; } std::string wifi_ssid_param; - if (net::GetValueForKeyInQuery(web_contents->GetURL(), "wifi_name", + if (net::GetValueForKeyInQuery(web_contents->GetVisibleURL(), "wifi_name", &wifi_ssid_param)) { wifi_ssid = wifi_ssid_param; }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index 83bddc5..8956cc8 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -1043,8 +1043,7 @@ } } })"); - auto url_loader_factory = profile_->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess(); + auto url_loader_factory = profile_->GetURLLoaderFactory(); auto request = std::make_unique<network::ResourceRequest>(); request->url = url; auto loader =
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc index 71117bd9..c536c36 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_refptr.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "chrome/browser/new_tab_page/promos/promo_data.h" @@ -14,6 +15,7 @@ #include "chrome/browser/search/background/ntp_background_data.h" #include "chrome/browser/search/background/ntp_custom_background_service.h" #include "chrome/browser/search/background/ntp_custom_background_service_observer.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/themes/theme_helper.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" @@ -32,6 +34,8 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.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" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -41,7 +45,10 @@ namespace { +using testing::_; using testing::DoAll; +using testing::Optional; +using testing::SaveArg; class MockPage : public new_tab_page::mojom::Page { public: @@ -111,7 +118,8 @@ MOCK_METHOD(void, Refresh, (), (override)); }; -std::unique_ptr<TestingProfile> MakeTestingProfile() { +std::unique_ptr<TestingProfile> MakeTestingProfile( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { TestingProfile::Builder profile_builder; profile_builder.AddTestingFactory( PromoServiceFactory::GetInstance(), @@ -119,7 +127,12 @@ -> std::unique_ptr<KeyedService> { return std::make_unique<testing::NiceMock<MockPromoService>>(); })); - return profile_builder.Build(); + profile_builder.SetSharedURLLoaderFactory(url_loader_factory); + auto profile = profile_builder.Build(); + TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( + profile.get(), + base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)); + return profile; } } // namespace @@ -127,7 +140,9 @@ class NewTabPageHandlerTest : public testing::Test { public: NewTabPageHandlerTest() - : profile_(MakeTestingProfile()), + : profile_(MakeTestingProfile( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_))), mock_ntp_custom_background_service_(profile_.get()), mock_promo_service_(*static_cast<MockPromoService*>( PromoServiceFactory::GetForProfile(profile_.get()))), @@ -196,6 +211,7 @@ testing::NiceMock<MockPage> mock_page_; // NOTE: The initialization order of these members matters. content::BrowserTaskEnvironment task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; std::unique_ptr<TestingProfile> profile_; testing::NiceMock<MockNtpCustomBackgroundService> mock_ntp_custom_background_service_; @@ -542,3 +558,56 @@ EXPECT_EQ("green", text->color); EXPECT_EQ("blub", text->text); } + +TEST_F(NewTabPageHandlerTest, OnDoodleImageClicked) { + handler_->OnDoodleImageClicked( + /*type=*/new_tab_page::mojom::DoodleImageType::kCta, + /*log_url=*/GURL("https://doodle.com/log")); + + histogram_tester_.ExpectTotalCount("NewTabPage.LogoClick", 1); + EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest( + "https://doodle.com/log", "")); +} + +TEST_F(NewTabPageHandlerTest, OnDoodleImageRendered) { + base::MockCallback<NewTabPageHandler::OnDoodleImageRenderedCallback> callback; + absl::optional<std::string> image_click_params; + absl::optional<GURL> interaction_log_url; + absl::optional<std::string> shared_id; + EXPECT_CALL(callback, Run(_, _, _)) + .Times(1) + .WillOnce(DoAll(SaveArg<0>(&image_click_params), + SaveArg<1>(&interaction_log_url), + SaveArg<2>(&shared_id))); + + handler_->OnDoodleImageRendered( + /*type=*/new_tab_page::mojom::DoodleImageType::kStatic, + /*time=*/0, + /*log_url=*/GURL("https://doodle.com/log"), callback.Get()); + + EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest( + "https://doodle.com/log", R"()]}' + { + "ddllog": { + "target_url_params": "foo params", + "interaction_log_url": "/bar_log", + "encoded_ei": "baz ei" + } + })")); + EXPECT_THAT(image_click_params, Optional(std::string("foo params"))); + EXPECT_THAT(interaction_log_url, + Optional(GURL("https://www.google.com/bar_log"))); + EXPECT_THAT(shared_id, Optional(std::string("baz ei"))); + histogram_tester_.ExpectTotalCount("NewTabPage.LogoShown", 1); + histogram_tester_.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1); + histogram_tester_.ExpectTotalCount("NewTabPage.LogoShownTime2", 1); +} + +TEST_F(NewTabPageHandlerTest, OnDoodleShared) { + handler_->OnDoodleShared(new_tab_page::mojom::DoodleShareChannel::kEmail, + "food_id", "bar_id"); + + EXPECT_TRUE(test_url_loader_factory_.IsPending( + "https://www.google.com/" + "gen_204?atype=i&ct=doodle&ntp=2&cad=sh,5,ct:food_id&ei=bar_id")); +}
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 339ce63..1e2fb6f 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -137,15 +137,6 @@ const char kRunOnOsLoginModeWindowed[] = "run_on_os_login_mode_windowed"; // The Youtube app is incorrectly harded to be a 'bookmark app'. However, it is -// a platform app. This helper method special cases that, and should be used -// instead of extension->from_bookmark(). -// TODO(crbug.com/1065748): Remove this hack once the youtube app is fixed. -bool FromBookmark(const extensions::Extension* extension) { - return extension->from_bookmark() && - extension->id() != extension_misc::kYoutubeAppId; -} - -// The Youtube app is incorrectly harded to be a 'bookmark app'. However, it is // a platform app. // TODO(crbug.com/1065748): Remove this hack once the youtube app is fixed. bool IsYoutubeExtension(const std::string& extension_id) { @@ -302,7 +293,6 @@ void AppLauncherHandler::CreateExtensionInfo(const Extension* extension, base::DictionaryValue* value) { - DCHECK(!FromBookmark(extension)); // The items which are to be written into |value| are also described in // chrome/browser/resources/ntp4/page_list_view.js in @typedef for AppInfo. // Please update it whenever you add or remove any keys here. @@ -519,8 +509,6 @@ const Extension* extension) { if (!ShouldShow(extension)) return; - if (FromBookmark(extension)) - return; std::unique_ptr<base::DictionaryValue> app_info(GetExtensionInfo(extension)); if (!app_info.get()) @@ -535,9 +523,6 @@ content::BrowserContext* browser_context, const Extension* extension, extensions::UnloadedExtensionReason reason) { - // Exclude events from bookmarks apps if BMO is turned on. - if (extension->from_bookmark()) - return; ExtensionRemoved(extension, /*is_uninstall=*/false); } @@ -545,9 +530,6 @@ content::BrowserContext* browser_context, const Extension* extension, extensions::UninstallReason reason) { - // Exclude events from bookmarks apps if BMO is turned on. - if (FromBookmark(extension)) - return; ExtensionRemoved(extension, /*is_uninstall=*/true); } @@ -644,7 +626,6 @@ const Extension* extension = registry->GetInstalledExtension(*it); if (extension && extensions::ui_util::ShouldDisplayInNewTabPage(extension, profile)) { - DCHECK(!FromBookmark(extension)); installed_extensions->Append(GetExtensionInfo(extension)); } } @@ -698,24 +679,18 @@ const ExtensionSet& enabled_set = registry->enabled_extensions(); for (extensions::ExtensionSet::const_iterator it = enabled_set.begin(); it != enabled_set.end(); ++it) { - if (FromBookmark(it->get())) - continue; visible_apps_.insert((*it)->id()); } const ExtensionSet& disabled_set = registry->disabled_extensions(); for (ExtensionSet::const_iterator it = disabled_set.begin(); it != disabled_set.end(); ++it) { - if (FromBookmark(it->get())) - continue; visible_apps_.insert((*it)->id()); } const ExtensionSet& terminated_set = registry->terminated_extensions(); for (ExtensionSet::const_iterator it = terminated_set.begin(); it != terminated_set.end(); ++it) { - if (FromBookmark(it->get())) - continue; visible_apps_.insert((*it)->id()); } } @@ -791,7 +766,6 @@ PromptToEnableApp(extension_id); return; } - DCHECK(!FromBookmark(extension)); type = extension->GetType(); full_launch_url = extensions::AppLaunchInfo::GetFullLaunchURL(extension); launch_container = @@ -897,7 +871,6 @@ extensions::ExtensionRegistry::TERMINATED); if (!extension) return; - DCHECK(!FromBookmark(extension)); // Don't update the page; it already knows about the launch type change. base::AutoReset<bool> auto_reset(&ignore_changes_, true); @@ -952,7 +925,6 @@ ->GetInstalledExtension(extension_id); if (!extension) return; - DCHECK(!FromBookmark(extension)); if (!extensions::ExtensionSystem::Get(extension_service_->profile()) ->management_policy() @@ -1007,7 +979,6 @@ extensions::ExtensionRegistry::TERMINATED); if (!extension) return; - DCHECK(!FromBookmark(extension)); Browser* browser = chrome::FindBrowserWithWebContents( web_ui()->GetWebContents()); @@ -1050,7 +1021,6 @@ extensions::ExtensionRegistry::TERMINATED); if (!extension) return; - DCHECK(!FromBookmark(extension)); ShowAppInfoInNativeDialog(web_ui()->GetWebContents(), Profile::FromWebUI(web_ui()), extension, @@ -1100,13 +1070,17 @@ void AppLauncherHandler::HandleSaveAppPageName(const base::ListValue* args) { const std::string& name = args->GetList()[0].GetString(); - double page_index = args->GetList()[1].GetDouble(); + size_t page_index = static_cast<size_t>(args->GetList()[1].GetDouble()); base::AutoReset<bool> auto_reset(&ignore_changes_, true); PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); ListPrefUpdate update(prefs, prefs::kNtpAppPageNames); base::ListValue* list = update.Get(); - list->GetList()[static_cast<size_t>(page_index)] = base::Value(name); + if (page_index < list->GetList().size()) { + list->GetList()[page_index] = base::Value(name); + } else { + list->Append(name); + } } void AppLauncherHandler::HandleGenerateAppForLink(const base::ListValue* args) { @@ -1319,7 +1293,6 @@ void AppLauncherHandler::ExtensionRemoved(const Extension* extension, bool is_uninstall) { - DCHECK(!FromBookmark(extension)); if (!ShouldShow(extension)) return;
diff --git a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc index 5f7a721c..f2e0052 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
@@ -369,25 +369,23 @@ // Check that the file contains a valid dictionary. EXPECT_TRUE(value_ptr.get()); - base::DictionaryValue* actual_policies = nullptr; - EXPECT_TRUE(value_ptr->GetAsDictionary(&actual_policies)); + EXPECT_TRUE(value_ptr->is_dict()); // Since Chrome Metadata has a lot of variations based on platform, OS, // architecture and version, it is difficult to test for exact values. Test // instead that the same keys exist in the meta data and also that the type of // all the keys is a string. The incoming |expected| value should already be // filled with the expected keys. - base::Value* chrome_metadata = actual_policies->FindKeyOfType( - "chromeMetadata", base::Value::Type::DICTIONARY); + base::Value* chrome_metadata = + value_ptr->FindKeyOfType("chromeMetadata", base::Value::Type::DICTIONARY); EXPECT_NE(chrome_metadata, nullptr); - base::DictionaryValue* chrome_metadata_dict = nullptr; - EXPECT_TRUE(chrome_metadata->GetAsDictionary(&chrome_metadata_dict)); + EXPECT_TRUE(chrome_metadata->is_dict()); // The |chrome_metadata| we compare against will have the actual values so // those will be cleared to empty values so that the equals comparison below // will just compare key existence and value types. - for (auto key_value : chrome_metadata_dict->DictItems()) + for (auto key_value : chrome_metadata->DictItems()) key_value.second = base::Value(key_value.second.type()); // Since policy management status can have variable information based on the @@ -397,12 +395,12 @@ // |expected| value should already have a "status" key with an empty // dictionary value. base::Value* status = - actual_policies->FindKeyOfType("status", base::Value::Type::DICTIONARY); + value_ptr->FindKeyOfType("status", base::Value::Type::DICTIONARY); EXPECT_NE(status, nullptr); status->DictClear(); // Check that this dictionary is the same as expected. - EXPECT_EQ(expected, *actual_policies); + EXPECT_EQ(expected, *value_ptr); } IN_PROC_BROWSER_TEST_F(PolicyUITest, WritePoliciesToJSONFile) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc index 424c7824..9038f83 100644 --- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -43,7 +43,6 @@ namespace { constexpr char kFamilyLink[] = "Family Link"; -constexpr int kToastDurationMs = 2500; constexpr char kAccountRemovedToastId[] = "settings_account_manager_account_removed"; @@ -88,8 +87,7 @@ } void ShowToast(const std::string& id, const std::u16string& message) { - ash::ToastManager::Get()->Show(ash::ToastData( - id, message, kToastDurationMs, /*dismiss_text=*/absl::nullopt)); + ash::ToastManager::Get()->Show(ash::ToastData(id, message)); } class AccountBuilder {
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc index 7342f440..b46f265 100644 --- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -191,6 +191,10 @@ IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_FORGET}, {"bluetoothDeviceDetailForgetA11yLabel", IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_FORGET_A11Y_LABEL}, + {"bluetoothDeviceDetailHIDMessageConnected", + IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED}, + {"bluetoothDeviceDetailHIDMessageDisconnected", + IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED}, {"bluetoothDeviceDetailName", IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_NAME}, {"bluetoothDeviceDetailChangeNameDialogNewName", IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_NEW_NAME},
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc index 4553035..2531eec3 100644 --- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -303,8 +303,7 @@ html_source->AddString( "translateTargetLabel", l10n_util::GetStringUTF16( - ash::QuickAnswersState::Get() && - ash::QuickAnswersState::Get()->is_eligible() + QuickAnswersState::Get() && QuickAnswersState::Get()->is_eligible() ? IDS_OS_SETTINGS_LANGUAGES_TRANSLATE_TARGET_LABEL_WITH_QUICK_ANSWERS : IDS_OS_SETTINGS_LANGUAGES_TRANSLATE_TARGET_LABEL)); html_source->AddString(
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc index c2f27d5b..ebcfed6 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -145,6 +145,14 @@ "cancelNotificationSetup", base::BindRepeating(&MultideviceHandler::HandleCancelNotificationSetup, base::Unretained(this))); + web_ui()->RegisterDeprecatedMessageCallback( + "attemptAppsSetup", + base::BindRepeating(&MultideviceHandler::HandleAttemptAppsSetup, + base::Unretained(this))); + web_ui()->RegisterDeprecatedMessageCallback( + "cancelAppsSetup", + base::BindRepeating(&MultideviceHandler::HandleCancelAppsSetup, + base::Unretained(this))); } void MultideviceHandler::OnJavascriptAllowed() { @@ -220,6 +228,7 @@ DCHECK(apps_access_manager_observation_.IsObservingSource( apps_access_manager_)); apps_access_manager_observation_.Reset(); + apps_access_operation_.reset(); } if (camera_roll_manager_) { @@ -466,6 +475,34 @@ notification_access_operation_.reset(); } +void MultideviceHandler::HandleAttemptAppsSetup(const base::ListValue* args) { + DCHECK(features::IsEcheSWAEnabled()); + DCHECK(features::IsEchePhoneHubPermissionsOnboarding()); + DCHECK(!apps_access_operation_); + + ash::eche_app::AppsAccessManager::AccessStatus apps_access_status = + apps_access_manager_->GetAccessStatus(); + + if (apps_access_status != + ash::eche_app::AppsAccessManager::AccessStatus::kAvailableButNotGranted) { + PA_LOG(WARNING) << "Cannot request apps access setup flow; current " + << "status: " << apps_access_status; + return; + } + + apps_access_operation_ = + apps_access_manager_->AttemptAppsAccessSetup(/*delegate=*/this); + DCHECK(apps_access_operation_); +} + +void MultideviceHandler::HandleCancelAppsSetup(const base::ListValue* args) { + DCHECK(features::IsEcheSWAEnabled()); + DCHECK(features::IsEchePhoneHubPermissionsOnboarding()); + DCHECK(apps_access_operation_); + + apps_access_operation_.reset(); +} + void MultideviceHandler::OnStatusChange( phonehub::NotificationAccessSetupOperation::Status new_status) { FireWebUIListener("settings.onNotificationAccessSetupStatusChanged", @@ -475,6 +512,15 @@ notification_access_operation_.reset(); } +void MultideviceHandler::OnAppsStatusChange( + ash::eche_app::AppsAccessSetupOperation::Status new_status) { + FireWebUIListener("settings.onAppsAccessSetupStatusChanged", + base::Value(static_cast<int32_t>(new_status))); + + if (ash::eche_app::AppsAccessSetupOperation::IsFinalStatus(new_status)) + apps_access_operation_.reset(); +} + void MultideviceHandler::OnSetFeatureStateEnabledResult( const std::string& js_callback_id, bool success) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h index 2b828424..8187dacf 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
@@ -37,6 +37,7 @@ public phonehub::NotificationAccessManager::Observer, public phonehub::NotificationAccessSetupOperation::Delegate, public ash::eche_app::AppsAccessManager::Observer, + public ash::eche_app::AppsAccessSetupOperation::Delegate, public ash::phonehub::CameraRollManager::Observer { public: MultideviceHandler( @@ -75,6 +76,10 @@ void OnStatusChange( phonehub::NotificationAccessSetupOperation::Status new_status) override; + // ash::eche_app::AppsAccessSetupOperation::Delegate: + void OnAppsStatusChange( + ash::eche_app::AppsAccessSetupOperation::Status new_status) override; + // phonehub::NotificationAccessManager::Observer: void OnNotificationAccessChanged() override; @@ -109,6 +114,8 @@ void HandleGetAndroidSmsInfo(const base::ListValue* args); void HandleAttemptNotificationSetup(const base::ListValue* args); void HandleCancelNotificationSetup(const base::ListValue* args); + void HandleAttemptAppsSetup(const base::ListValue* args); + void HandleCancelAppsSetup(const base::ListValue* args); void OnSetFeatureStateEnabledResult(const std::string& js_callback_id, bool success); @@ -151,6 +158,8 @@ android_sms::AndroidSmsAppManager* android_sms_app_manager_; ash::eche_app::AppsAccessManager* apps_access_manager_; + std::unique_ptr<ash::eche_app::AppsAccessSetupOperation> + apps_access_operation_; ash::phonehub::CameraRollManager* camera_roll_manager_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc index 71e7b05..9253cac 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
@@ -325,6 +325,21 @@ &empty_args); } + void CallAttemptAppsSetup(bool has_access_been_granted) { + fake_apps_access_manager()->SetAccessStatusInternal( + has_access_been_granted + ? ash::eche_app::AppsAccessManager::AccessStatus::kAccessGranted + : ash::eche_app::AppsAccessManager::AccessStatus:: + kAvailableButNotGranted); + base::ListValue empty_args; + test_web_ui()->HandleReceivedMessage("attemptAppsSetup", &empty_args); + } + + void CallCancelAppsSetup() { + base::ListValue empty_args; + test_web_ui()->HandleReceivedMessage("cancelAppsSetup", &empty_args); + } + void SimulateHostStatusUpdate( multidevice_setup::mojom::HostStatus host_status, const absl::optional<multidevice::RemoteDeviceRef>& host_device) { @@ -559,6 +574,32 @@ return fake_notification_access_manager()->IsSetupOperationInProgress(); } + void SimulateAppsOptInStatusChange( + ash::eche_app::AppsAccessSetupOperation::Status status) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + fake_apps_access_manager()->SetAppsSetupOperationStatus(status); + + bool completed_successfully = + status == + ash::eche_app::AppsAccessSetupOperation::Status::kCompletedSuccessfully; + if (completed_successfully) + call_data_count_before_call++; + + EXPECT_EQ(call_data_count_before_call + 1u, + test_web_ui()->call_data().size()); + const content::TestWebUI::CallData& call_data = + CallDataAtIndex(call_data_count_before_call); + EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); + EXPECT_EQ("settings.onAppsAccessSetupStatusChanged", + call_data.arg1()->GetString()); + EXPECT_EQ(call_data.arg2()->GetInt(), static_cast<int32_t>(status)); + } + + bool IsAppsAccessSetupOperationInProgress() { + return fake_apps_access_manager()->IsSetupOperationInProgress(); + } + const multidevice::RemoteDeviceRef test_device_; bool expected_is_nearby_share_disallowed_by_policy_ = false; @@ -653,6 +694,55 @@ EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); } +TEST_F(MultideviceHandlerTest, AppsSetupFlow) { + using Status = ash::eche_app::AppsAccessSetupOperation::Status; + + // Simulate success flow. + CallAttemptAppsSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange( + Status::kSentMessageToPhoneAndWaitingForResponse); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kCompletedSuccessfully); + EXPECT_FALSE(IsAppsAccessSetupOperationInProgress()); + + // Simulate cancel flow. + CallAttemptAppsSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + CallCancelAppsSetup(); + EXPECT_FALSE(IsAppsAccessSetupOperationInProgress()); + + // Simulate failure via time-out flow. + CallAttemptAppsSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kTimedOutConnecting); + EXPECT_FALSE(IsAppsAccessSetupOperationInProgress()); + + // Simulate failure via connected then disconnected flow. + CallAttemptAppsSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsAppsAccessSetupOperationInProgress()); + + SimulateAppsOptInStatusChange(Status::kConnectionDisconnected); + EXPECT_FALSE(IsAppsAccessSetupOperationInProgress()); + + // If access has already been granted, a setup operation should not occur. + CallAttemptAppsSetup(/*has_access_been_granted=*/true); + EXPECT_FALSE(IsAppsAccessSetupOperationInProgress()); +} + TEST_F(MultideviceHandlerTest, PageContentData) { CallGetPageContentData(); CallGetPageContentData();
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.cc b/chrome/browser/ui/webui/settings/chromeos/search_section.cc index 13a9e6a..60150addd 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
@@ -37,8 +37,7 @@ namespace { bool ShouldShowQuickAnswersSettings() { - return ash::QuickAnswersState::Get() && - ash::QuickAnswersState::Get()->is_eligible(); + return QuickAnswersState::Get() && QuickAnswersState::Get()->is_eligible(); } const std::vector<SearchConcept>& GetSearchPageSearchConcepts() { @@ -282,7 +281,7 @@ } if (ShouldShowQuickAnswersSettings()) { - ash::QuickAnswersState::Get()->AddObserver(this); + QuickAnswersState::Get()->AddObserver(this); UpdateQuickAnswersSearchTags(); } } @@ -442,13 +441,13 @@ } void SearchSection::UpdateQuickAnswersSearchTags() { - DCHECK(ash::QuickAnswersState::Get()); + DCHECK(QuickAnswersState::Get()); SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); updater.RemoveSearchTags(GetQuickAnswersOnSearchConcepts()); if (chromeos::features::IsQuickAnswersV2SettingsSubToggleEnabled() && - ash::QuickAnswersState::Get()->settings_enabled()) { + QuickAnswersState::Get()->settings_enabled()) { updater.AddSearchTags(GetQuickAnswersOnSearchConcepts()); } }
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.h b/chrome/browser/ui/webui/settings/chromeos/search_section.h index b42ec8b..5f09fcf 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search_section.h +++ b/chrome/browser/ui/webui/settings/chromeos/search_section.h
@@ -24,7 +24,7 @@ // feature and relevant flags are enabled/disabled. class SearchSection : public OsSettingsSection, public ash::AssistantStateObserver, - public ash::QuickAnswersStateObserver { + public QuickAnswersStateObserver { public: SearchSection(Profile* profile, SearchTagRegistry* search_tag_registry); ~SearchSection() override; @@ -46,7 +46,7 @@ void OnAssistantSettingsEnabled(bool enabled) override; void OnAssistantHotwordEnabled(bool enabled) override; - // ash::QuickAnswersStateObserver: + // QuickAnswersStateObserver: void OnSettingsEnabled(bool enabled) override; bool IsAssistantAllowed() const;
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc index 91f9ccb..d60e6e9 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -78,7 +78,7 @@ content::StoragePartition* partition = signin::GetSigninPartition(contents->GetBrowserContext()); if (partition) { - const GURL& current_url = web_ui()->GetWebContents()->GetURL(); + const GURL& current_url = web_ui()->GetWebContents()->GetLastCommittedURL(); // If the kSignInPromoQueryKeyForceKeepData param is missing, or if it is // present and its value is zero, this means we don't want to keep the @@ -109,7 +109,7 @@ params.SetString("gaiaUrl", gaiaUrls->gaia_url().spec()); params.SetInteger("authMode", InlineLoginHandler::kDesktopAuthMode); - const GURL& current_url = web_ui()->GetWebContents()->GetURL(); + const GURL& current_url = web_ui()->GetWebContents()->GetLastCommittedURL(); signin_metrics::AccessPoint access_point = signin::GetAccessPointForEmbeddedPromoURL(current_url); signin_metrics::Reason reason = @@ -213,7 +213,7 @@ CHECK(args->GetList()[0].is_string()); Profile* profile = Profile::FromWebUI(web_ui()); - GURL main_frame_url(web_ui()->GetWebContents()->GetURL()); + GURL main_frame_url(web_ui()->GetWebContents()->GetLastCommittedURL()); // Adds extra parameters to the signin URL so that Chrome will close the tab // and show the account management view of the avatar menu upon completion.
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc index 9237abe..60a1feb82 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -14,6 +14,8 @@ #include "base/logging.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" +#include "chrome/browser/ash/account_manager/account_apps_availability.h" +#include "chrome/browser/ash/account_manager/account_apps_availability_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/profiles/profile.h" @@ -89,6 +91,7 @@ account_manager::AccountManager* account_manager, crosapi::AccountManagerMojoService* account_manager_mojo_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + std::unique_ptr<SigninHelper::ArcHelper> arc_helper, const std::string& gaia_id, const std::string& email, const std::string& auth_code, @@ -101,6 +104,7 @@ // dialog. Therefore, passing a void callback. base::DoNothing(), url_loader_factory, + std::move(arc_helper), gaia_id, email, auth_code, @@ -246,13 +250,22 @@ identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) .email; + std::unique_ptr<SigninHelper::ArcHelper> arc_helper; + if (ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) { + // TODO(crbug.com/1260909): Set `is_available_in_arc` to the value chosen by + // the user. + arc_helper = std::make_unique<SigninHelper::ArcHelper>( + /*is_available_in_arc=*/true, + ash::AccountAppsAvailabilityFactory::GetForProfile(profile)); + } + // Child user added a secondary account. if (profile->IsChild() && !gaia::AreEmailsSame(primary_account_email, params.email)) { new EduCoexistenceChildSigninHelper( account_manager, account_manager_mojo_service, - profile->GetURLLoaderFactory(), params.gaia_id, params.email, - params.auth_code, + profile->GetURLLoaderFactory(), std::move(arc_helper), params.gaia_id, + params.email, params.auth_code, GetAccountDeviceId(GetSigninScopedDeviceIdForProfile(profile), params.gaia_id), profile->GetPrefs(), web_ui()); @@ -263,8 +276,8 @@ // SigninHelper deletes itself after its work is done. new SigninHelper( account_manager, account_manager_mojo_service, close_dialog_closure_, - profile->GetURLLoaderFactory(), params.gaia_id, params.email, - params.auth_code, + profile->GetURLLoaderFactory(), std::move(arc_helper), params.gaia_id, + params.email, params.auth_code, GetAccountDeviceId(GetSigninScopedDeviceIdForProfile(profile), params.gaia_id)); }
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 8523ac1..e231cb04 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -518,7 +518,7 @@ params.SetBoolean("dontResizeNonEmbeddedPages", true); content::WebContents* contents = web_ui()->GetWebContents(); - const GURL& current_url = contents->GetURL(); + const GURL& current_url = contents->GetLastCommittedURL(); HandlerSigninReason reason = GetHandlerSigninReason(current_url); const GURL& url = GaiaUrls::GetInstance()->embedded_signin_url(); @@ -601,7 +601,7 @@ void InlineLoginHandlerImpl::CompleteLogin(const CompleteLoginParams& params) { content::WebContents* contents = web_ui()->GetWebContents(); - const GURL& current_url = contents->GetURL(); + const GURL& current_url = contents->GetLastCommittedURL(); if (params.skip_for_now) { SyncSetupFailed(); @@ -794,7 +794,7 @@ void InlineLoginHandlerImpl::HandleLoginError(const SigninUIError& error) { content::WebContents* contents = web_ui()->GetWebContents(); - const GURL& current_url = contents->GetURL(); + const GURL& current_url = contents->GetLastCommittedURL(); HandlerSigninReason reason = GetHandlerSigninReason(current_url); if (reason == HandlerSigninReason::kFetchLstOnly) {
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc index 497d78d..3a25f52 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -36,6 +36,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "chrome/browser/ash/account_manager/account_apps_availability.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/ui/chrome_pages.h" @@ -175,6 +176,9 @@ source->AddLocalizedStrings(kLocalizedStrings); #if BUILDFLAG(IS_CHROMEOS_ASH) + source->AddBoolean( + "isArcAccountRestrictionsEnabled", + ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()); source->AddBoolean("shouldSkipWelcomePage", profile->GetPrefs()->GetBoolean( chromeos::prefs::kShouldSkipInlineLoginWelcomePage));
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc index bcf819c..f88fcf27 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -251,7 +251,9 @@ profile_picker_handler_ = handler.get(); web_ui->AddMessageHandler(std::move(handler)); - if (web_ui->GetWebContents()->GetURL().query() == + // GetVisibleURL is used here because a WebUIController is created before the + // navigation commits. + if (web_ui->GetWebContents()->GetVisibleURL().query() == chrome::kChromeUIProfilePickerStartupQuery) { profile_picker_handler_->EnableStartupMetrics(); }
diff --git a/chrome/browser/ui/webui/signin/signin_error_handler_unittest.cc b/chrome/browser/ui/webui/signin/signin_error_handler_unittest.cc index 3b849737..5929e4a8 100644 --- a/chrome/browser/ui/webui/signin/signin_error_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/signin_error_handler_unittest.cc
@@ -123,7 +123,7 @@ TabStripModel* tab_strip_model = browser()->tab_strip_model(); EXPECT_EQ(1, tab_strip_model->count()); EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), - tab_strip_model->GetActiveWebContents()->GetURL()); + tab_strip_model->GetActiveWebContents()->GetVisibleURL()); // Open learn more CreateHandlerInBrowser(); @@ -136,7 +136,7 @@ // Verify that the learn more URL was opened. EXPECT_EQ(2, tab_strip_model->count()); EXPECT_EQ(GURL(kSigninErrorLearnMoreUrl), - tab_strip_model->GetActiveWebContents()->GetURL()); + tab_strip_model->GetActiveWebContents()->GetVisibleURL()); } TEST_F(SigninErrorHandlerTest, InBrowserHandleLearnMoreAfterBrowserRemoved) { @@ -144,7 +144,7 @@ TabStripModel* tab_strip_model = browser()->tab_strip_model(); EXPECT_EQ(1, tab_strip_model->count()); EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), - tab_strip_model->GetActiveWebContents()->GetURL()); + tab_strip_model->GetActiveWebContents()->GetVisibleURL()); // Inform the handler that the browser was removed; CreateHandlerInBrowser(); @@ -160,7 +160,7 @@ // Verify that the learn more URL was not opened as the browser was removed. EXPECT_EQ(1, tab_strip_model->count()); EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), - tab_strip_model->GetActiveWebContents()->GetURL()); + tab_strip_model->GetActiveWebContents()->GetVisibleURL()); } TEST_F(SigninErrorHandlerTest, InBrowserTestConfirm) {
diff --git a/chrome/browser/ui/webui/signin/signin_helper_chromeos.cc b/chrome/browser/ui/webui/signin/signin_helper_chromeos.cc index 6670b49..9d8a570 100644 --- a/chrome/browser/ui/webui/signin/signin_helper_chromeos.cc +++ b/chrome/browser/ui/webui/signin/signin_helper_chromeos.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/signin/signin_helper_chromeos.h" +#include "chrome/browser/ash/account_manager/account_apps_availability.h" #include "components/account_manager_core/account.h" #include "components/account_manager_core/account_addition_result.h" #include "components/account_manager_core/chromeos/account_manager.h" @@ -12,23 +13,45 @@ namespace chromeos { +SigninHelper::ArcHelper::ArcHelper( + bool is_available_in_arc, + ash::AccountAppsAvailability* account_apps_availability) + : is_available_in_arc_(is_available_in_arc), + account_apps_availability_(account_apps_availability) {} + +SigninHelper::ArcHelper::~ArcHelper() = default; + +void SigninHelper::ArcHelper::OnAccountAdded( + const account_manager::Account& account) { + // TODO(crbug.com/1260909): Call SetIsAccountAvailableInArc only for account + // addition. + account_apps_availability_->SetIsAccountAvailableInArc(account, + is_available_in_arc_); +} + SigninHelper::SigninHelper( account_manager::AccountManager* account_manager, crosapi::AccountManagerMojoService* account_manager_mojo_service, const base::RepeatingClosure& close_dialog_closure, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + std::unique_ptr<ArcHelper> arc_helper, const std::string& gaia_id, const std::string& email, const std::string& auth_code, const std::string& signin_scoped_device_id) : account_manager_(account_manager), account_manager_mojo_service_(account_manager_mojo_service), + arc_helper_(std::move(arc_helper)), close_dialog_closure_(close_dialog_closure), account_key_(gaia_id, account_manager::AccountType::kGaia), email_(email), url_loader_factory_(std::move(url_loader_factory)), gaia_auth_fetcher_(this, gaia::GaiaSource::kChrome, url_loader_factory_) { DCHECK(!signin_scoped_device_id.empty()); + + if (ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) + DCHECK(arc_helper_); + gaia_auth_fetcher_.StartAuthCodeForOAuth2TokenExchangeWithDeviceId( auth_code, signin_scoped_device_id); } @@ -67,6 +90,10 @@ void SigninHelper::UpsertAccount(const std::string& refresh_token) { account_manager_->UpsertAccount(account_key_, email_, refresh_token); + auto new_account = account_manager::Account{account_key_, email_}; + if (ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) { + arc_helper_->OnAccountAdded(new_account); + } // Notify `AccountManagerMojoService` about successful account addition and // send the account. account_manager_mojo_service_->OnAccountAdditionFinished(
diff --git a/chrome/browser/ui/webui/signin/signin_helper_chromeos.h b/chrome/browser/ui/webui/signin/signin_helper_chromeos.h index 1146aec..bb7fc159 100644 --- a/chrome/browser/ui/webui/signin/signin_helper_chromeos.h +++ b/chrome/browser/ui/webui/signin/signin_helper_chromeos.h
@@ -14,6 +14,7 @@ namespace ash { class AccountManager; +class AccountAppsAvailability; } namespace chromeos { @@ -26,11 +27,33 @@ // itself after its work is complete. class SigninHelper : public GaiaAuthConsumer { public: + // A helper class that is responsible for setting the ARC availability + // after account addition depending on the flags passed in the constructor. + class ArcHelper { + public: + ArcHelper(bool is_available_in_arc, + ash::AccountAppsAvailability* account_apps_availability); + ArcHelper(const ArcHelper&) = delete; + ArcHelper& operator=(const ArcHelper&) = delete; + virtual ~ArcHelper(); + + // Sets the availability for the `account` in ARC. + // Should be called only once after the account is added. + void OnAccountAdded(const account_manager::Account& account); + + private: + bool is_available_in_arc_ = false; + // A non-owning pointer to AccountAppsAvailability which is a KeyedService + // and should outlive this class. + ash::AccountAppsAvailability* account_apps_availability_ = nullptr; + }; + SigninHelper( account_manager::AccountManager* account_manager, crosapi::AccountManagerMojoService* account_manager_mojo_service, const base::RepeatingClosure& close_dialog_closure, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + std::unique_ptr<ArcHelper> arc_helper, const std::string& gaia_id, const std::string& email, const std::string& auth_code, @@ -65,6 +88,9 @@ account_manager::AccountManager* const account_manager_; // A non-owning pointer to AccountManagerMojoService. crosapi::AccountManagerMojoService* const account_manager_mojo_service_; + // Sets the ARC availability + // after account addition. Owned by this class. + std::unique_ptr<ArcHelper> arc_helper_; // A closure to close the hosting dialog window. base::RepeatingClosure close_dialog_closure_; // The user's AccountKey for which |this| object has been created.
diff --git a/chrome/browser/ui/webui/signin/signin_helper_chromeos_browsertest.cc b/chrome/browser/ui/webui/signin/signin_helper_chromeos_browsertest.cc new file mode 100644 index 0000000..b58105d --- /dev/null +++ b/chrome/browser/ui/webui/signin/signin_helper_chromeos_browsertest.cc
@@ -0,0 +1,343 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/signin/signin_helper_chromeos.h" + +#include "ash/components/account_manager/account_manager_factory.h" +#include "ash/constants/ash_features.h" +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/account_manager/account_apps_availability.h" +#include "chrome/browser/ash/account_manager/account_apps_availability_factory.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/account_manager_core/account.h" +#include "components/account_manager_core/chromeos/account_manager.h" +#include "components/account_manager_core/chromeos/account_manager_mojo_service.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/browser_test.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +namespace chromeos { + +class SigninHelperChromeOSTest; + +namespace { + +const char kFakeGaiaId[] = "fake_gaia_id"; +const char kFakeEmail[] = "fake_email@gmail.com"; +const char kFakeAuthCode[] = "fake_auth_code"; +const char kFakeDeviceId[] = "fake_device_id"; +const char kFakeRefreshToken[] = "fake_refresh_token"; + +class TestSigninHelper : public SigninHelper { + public: + TestSigninHelper( + SigninHelperChromeOSTest* test_fixture, + account_manager::AccountManager* account_manager, + crosapi::AccountManagerMojoService* account_manager_mojo_service, + const base::RepeatingClosure& close_dialog_closure, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + std::unique_ptr<ArcHelper> arc_helper, + const std::string& gaia_id, + const std::string& email, + const std::string& auth_code, + const std::string& signin_scoped_device_id) + : SigninHelper(account_manager, + account_manager_mojo_service, + close_dialog_closure, + url_loader_factory, + std::move(arc_helper), + gaia_id, + email, + auth_code, + signin_scoped_device_id) { + test_fixture_ = test_fixture; + } + + ~TestSigninHelper() override; + + void OnClientOAuthSuccess(const ClientOAuthResult& result) override { + SigninHelper::OnClientOAuthSuccess(result); + } + + void OnClientOAuthFailure(const GoogleServiceAuthError& error) override { + SigninHelper::OnClientOAuthFailure(error); + } + + private: + SigninHelperChromeOSTest* test_fixture_; +}; + +} // namespace + +class SigninHelperChromeOSTest + : public InProcessBrowserTest, + public account_manager::AccountManager::Observer { + public: + SigninHelperChromeOSTest() = default; + + ~SigninHelperChromeOSTest() override { + DCHECK_EQ(signin_helper_created_count_, signin_helper_deleted_count_); + } + + void SetUpOnMainThread() override { + auto* profile = browser()->profile(); + auto* factory = + g_browser_process->platform_part()->GetAccountManagerFactory(); + account_manager_ = factory->GetAccountManager(profile->GetPath().value()); + account_manager_mojo_service_ = + factory->GetAccountManagerMojoService(profile->GetPath().value()); + account_manager_->SetUrlLoaderFactoryForTests(shared_url_loader_factory()); + account_manager_->AddObserver(this); + } + + void TearDownOnMainThread() override { + account_manager_->RemoveObserver(this); + on_token_upserted_account_ = absl::nullopt; + } + + TestSigninHelper* CreateSigninHelper( + const base::RepeatingClosure& close_dialog_closure) { + OnSigninHelperCreated(); + return new TestSigninHelper( + this, account_manager(), account_manager_mojo_service(), + close_dialog_closure, shared_url_loader_factory(), + /*arc_helper=*/nullptr, kFakeGaiaId, kFakeEmail, kFakeAuthCode, + kFakeDeviceId); + } + + GaiaAuthConsumer::ClientOAuthResult GetFakeOAuthResult() { + return GaiaAuthConsumer::ClientOAuthResult(kFakeRefreshToken, "", 0, false, + false); + } + + void OnSigninHelperCreated() { ++signin_helper_created_count_; } + void OnSigninHelperDeleted() { ++signin_helper_deleted_count_; } + + int on_token_upserted_call_count() { return on_token_upserted_call_count_; } + + absl::optional<account_manager::Account> on_token_upserted_account() { + return on_token_upserted_account_; + } + + scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() { + return browser() + ->profile() + ->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess(); + } + + account_manager::AccountManager* account_manager() { + return account_manager_; + } + + crosapi::AccountManagerMojoService* account_manager_mojo_service() { + return account_manager_mojo_service_; + } + + private: + // account_manager::AccountManager::Observer overrides: + void OnTokenUpserted(const account_manager::Account& account) override { + ++on_token_upserted_call_count_; + on_token_upserted_account_ = account; + } + + void OnAccountRemoved(const account_manager::Account& account) override {} + + account_manager::AccountManager* account_manager_ = nullptr; + crosapi::AccountManagerMojoService* account_manager_mojo_service_ = nullptr; + int signin_helper_created_count_ = 0; + int signin_helper_deleted_count_ = 0; + int on_token_upserted_call_count_ = 0; + absl::optional<account_manager::Account> on_token_upserted_account_; +}; + +TestSigninHelper::~TestSigninHelper() { + test_fixture_->OnSigninHelperDeleted(); +} + +IN_PROC_BROWSER_TEST_F(SigninHelperChromeOSTest, + NoAccountAddedWhenAuthTokenFetchFails) { + base::RunLoop close_dialog_closure_run_loop; + auto* helper = CreateSigninHelper( + base::BindLambdaForTesting([&close_dialog_closure_run_loop]() { + close_dialog_closure_run_loop.Quit(); + })); + // Auth token fetch fails. + helper->OnClientOAuthFailure( + GoogleServiceAuthError(GoogleServiceAuthError::State::CONNECTION_FAILED)); + // Make sure the close_dialog_closure was called. + close_dialog_closure_run_loop.Run(); + // Wait until SigninHelper finishes and deletes itself. + base::RunLoop().RunUntilIdle(); + // No account should be added. + EXPECT_EQ(on_token_upserted_call_count(), 0); +} + +IN_PROC_BROWSER_TEST_F(SigninHelperChromeOSTest, + AccountAddedWhenAuthTokenFetchSucceeds) { + base::RunLoop close_dialog_closure_run_loop; + auto* helper = + CreateSigninHelper(close_dialog_closure_run_loop.QuitClosure()); + // Auth token fetch succeeds. + helper->OnClientOAuthSuccess(GetFakeOAuthResult()); + // Make sure the close_dialog_closure was called. + close_dialog_closure_run_loop.Run(); + // Wait until SigninHelper finishes and deletes itself. + base::RunLoop().RunUntilIdle(); + // 1 account should be added. + EXPECT_EQ(on_token_upserted_call_count(), 1); + auto account = on_token_upserted_account(); + ASSERT_TRUE(account.has_value()); + EXPECT_EQ(account.value().raw_email, kFakeEmail); +} + +class SigninHelperChromeOSTestWithArcAccountRestrictions + : public SigninHelperChromeOSTest, + public ::ash::AccountAppsAvailability::Observer { + public: + SigninHelperChromeOSTestWithArcAccountRestrictions() { + feature_list_.InitWithFeatures( + /*enabled_features=*/{chromeos::features::kArcAccountRestrictions, + chromeos::features::kLacrosSupport}, + /*disabled_features=*/{}); + } + + ~SigninHelperChromeOSTestWithArcAccountRestrictions() override = default; + + void SetUpOnMainThread() override { + SigninHelperChromeOSTest::SetUpOnMainThread(); + account_apps_availability_ = + ash::AccountAppsAvailabilityFactory::GetForProfile( + browser()->profile()); + account_apps_availability()->AddObserver(this); + } + + void TearDownOnMainThread() override { + account_apps_availability()->RemoveObserver(this); + on_account_available_in_arc_call_count_ = 0; + on_account_unavailable_in_arc_call_count_ = 0; + on_account_available_in_arc_account_ = absl::nullopt; + on_account_unavailable_in_arc_account_ = absl::nullopt; + SigninHelperChromeOSTest::TearDownOnMainThread(); + } + + TestSigninHelper* CreateSigninHelper( + std::unique_ptr<SigninHelper::ArcHelper> arc_helper, + const base::RepeatingClosure& close_dialog_closure) { + OnSigninHelperCreated(); + return new TestSigninHelper( + this, account_manager(), account_manager_mojo_service(), + close_dialog_closure, shared_url_loader_factory(), + std::move(arc_helper), kFakeGaiaId, kFakeEmail, kFakeAuthCode, + kFakeDeviceId); + } + + ash::AccountAppsAvailability* account_apps_availability() { + return account_apps_availability_; + } + + int on_account_available_in_arc_call_count() { + return on_account_available_in_arc_call_count_; + } + + int on_account_unavailable_in_arc_call_count() { + return on_account_unavailable_in_arc_call_count_; + } + + absl::optional<account_manager::Account> + on_account_available_in_arc_account() { + return on_account_available_in_arc_account_; + } + + absl::optional<account_manager::Account> + on_account_unavailable_in_arc_account() { + return on_account_unavailable_in_arc_account_; + } + + private: + void OnAccountAvailableInArc( + const account_manager::Account& account) override { + ++on_account_available_in_arc_call_count_; + on_account_available_in_arc_account_ = account; + } + + void OnAccountUnavailableInArc( + const account_manager::Account& account) override { + ++on_account_unavailable_in_arc_call_count_; + on_account_unavailable_in_arc_account_ = account; + } + + int on_account_available_in_arc_call_count_ = 0; + int on_account_unavailable_in_arc_call_count_ = 0; + absl::optional<account_manager::Account> on_account_available_in_arc_account_; + absl::optional<account_manager::Account> + on_account_unavailable_in_arc_account_; + ash::AccountAppsAvailability* account_apps_availability_; + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(SigninHelperChromeOSTestWithArcAccountRestrictions, + AccountIsAvailableInArcAfterAddition) { + std::unique_ptr<SigninHelper::ArcHelper> arc_helper = + std::make_unique<SigninHelper::ArcHelper>( + /*is_available_in_arc=*/true, account_apps_availability()); + base::RunLoop close_dialog_closure_run_loop; + auto* helper = CreateSigninHelper( + std::move(arc_helper), close_dialog_closure_run_loop.QuitClosure()); + // Auth token fetch succeeds. + helper->OnClientOAuthSuccess(GetFakeOAuthResult()); + // Make sure the close_dialog_closure was called. + close_dialog_closure_run_loop.Run(); + // Wait until SigninHelper finishes and deletes itself. + base::RunLoop().RunUntilIdle(); + // 1 account should be added. + EXPECT_EQ(on_token_upserted_call_count(), 1); + auto account = on_token_upserted_account(); + ASSERT_TRUE(account.has_value()); + EXPECT_EQ(account.value().raw_email, kFakeEmail); + // 1 account should be available in ARC. + EXPECT_EQ(on_account_unavailable_in_arc_call_count(), 0); + EXPECT_EQ(on_account_available_in_arc_call_count(), 1); + auto arc_account = on_account_available_in_arc_account(); + ASSERT_TRUE(arc_account.has_value()); + EXPECT_EQ(arc_account.value().raw_email, kFakeEmail); +} + +IN_PROC_BROWSER_TEST_F(SigninHelperChromeOSTestWithArcAccountRestrictions, + AccountIsNotAvailableInArcAfterAddition) { + std::unique_ptr<SigninHelper::ArcHelper> arc_helper = + std::make_unique<SigninHelper::ArcHelper>( + /*is_available_in_arc=*/false, account_apps_availability()); + base::RunLoop close_dialog_closure_run_loop; + auto* helper = CreateSigninHelper( + std::move(arc_helper), + base::BindLambdaForTesting([&close_dialog_closure_run_loop]() { + close_dialog_closure_run_loop.Quit(); + })); + // Auth token fetch succeeds. + helper->OnClientOAuthSuccess(GetFakeOAuthResult()); + // Make sure the close_dialog_closure was called. + close_dialog_closure_run_loop.Run(); + // Wait until SigninHelper finishes and deletes itself. + base::RunLoop().RunUntilIdle(); + // 1 account should be added. + EXPECT_EQ(on_token_upserted_call_count(), 1); + auto account = on_token_upserted_account(); + ASSERT_TRUE(account.has_value()); + EXPECT_EQ(account.value().raw_email, kFakeEmail); + // 1 account should be added as "not available in ARC". + EXPECT_EQ(on_account_available_in_arc_call_count(), 0); + EXPECT_EQ(on_account_unavailable_in_arc_call_count(), 1); + auto arc_account = on_account_unavailable_in_arc_account(); + ASSERT_TRUE(arc_account.has_value()); + EXPECT_EQ(arc_account.value().raw_email, kFakeEmail); +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/webui_load_timer.cc b/chrome/browser/ui/webui/webui_load_timer.cc index 8945fb13..2974205 100644 --- a/chrome/browser/ui/webui/webui_load_timer.cc +++ b/chrome/browser/ui/webui/webui_load_timer.cc
@@ -48,14 +48,13 @@ void WebuiLoadTimer::DOMContentLoaded( content::RenderFrameHost* render_frame_host) { - // See comment in DocumentOnLoadCompletedInMainFrame. + // See comment in DocumentOnLoadCompletedInPrimaryMainFrame. if (!timer_ || render_frame_host != web_contents()->GetMainFrame()) return; CallUmaHistogramTimes(document_initial_load_uma_id_, timer_->Elapsed()); } -void WebuiLoadTimer::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void WebuiLoadTimer::DocumentOnLoadCompletedInPrimaryMainFrame() { // The WebContents could have been created for a child RenderFrameHost so it // would never receive a DidStartNavigation with the main frame, however it // will receive this callback.
diff --git a/chrome/browser/ui/webui/webui_load_timer.h b/chrome/browser/ui/webui/webui_load_timer.h index dccd4e8d..a13fb52 100644 --- a/chrome/browser/ui/webui/webui_load_timer.h +++ b/chrome/browser/ui/webui/webui_load_timer.h
@@ -21,7 +21,7 @@ // must not be empty. // * |document_initial_load_uma_id| - corresponds to DOMContentLoaded // * |document_load_completed_uma_id| - corresponds to - // DocumentOnLoadCompletedInMainFrame + // DocumentOnLoadCompletedInPrimaryMainFrame WebuiLoadTimer(content::WebContents* web_contents, const std::string& document_initial_load_uma_id, const std::string& document_load_completed_uma_id); @@ -35,8 +35,7 @@ void DidStartNavigation( content::NavigationHandle* navigation_handle) override; void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; private: std::string document_initial_load_uma_id_;
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index abdbb21b..588692df 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -558,7 +558,8 @@ }, base::Unretained(profile())), origin, kClearCookies, kClearStorage, kClearCache, - kAvoidClosingConnections, base::DoNothing()); + kAvoidClosingConnections, + net::CookiePartitionKey::Todo(), base::DoNothing()); } apps::mojom::IconKeyPtr WebAppPublisherHelper::MakeIconKey( @@ -1186,7 +1187,7 @@ } absl::optional<AppId> app_id = - FindInstalledAppWithUrlInScope(profile(), web_contents->GetURL(), + FindInstalledAppWithUrlInScope(profile(), web_contents->GetVisibleURL(), /*window_only=*/false); if (!app_id.has_value()) { return;
diff --git a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc index 7f02dae..8d58c75 100644 --- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc +++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
@@ -20,20 +20,17 @@ #include "chrome/browser/extensions/extension_ui_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/web_applications/os_integration_manager.h" #include "chrome/browser/web_applications/web_app_id.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" -#include "components/services/app_service/public/cpp/file_handler.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/image_loader.h" #include "extensions/common/extension.h" -#include "extensions/common/manifest_handlers/file_handler_info.h" #include "extensions/common/manifest_handlers/icons_handler.h" #include "ui/gfx/image/image_skia.h" @@ -215,20 +212,6 @@ profile->GetPrefs()->GetString(prefs::kProfileName); shortcut_info->version_for_display = app->GetVersionForDisplay(); - // File Handlers should only be included in bookmark apps. - if (app->from_bookmark()) { - shortcut_info->is_multi_profile = true; - OsIntegrationManager& os_integration_manager = - WebAppProvider::GetForWebApps(profile)->os_integration_manager(); - if (const auto* file_handlers = - os_integration_manager.GetEnabledFileHandlers(app->id())) { - shortcut_info->file_handler_extensions = - apps::GetFileExtensionsFromFileHandlers(*file_handlers); - shortcut_info->file_handler_mime_types = - apps::GetMimeTypesFromFileHandlers(*file_handlers); - } - } - return shortcut_info; }
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc index b4cb850..1a667f7 100644 --- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc +++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -41,7 +41,6 @@ #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_file_handler_registration.h" #include "chrome/browser/web_applications/web_app_helpers.h" -#include "chrome/browser/web_applications/web_app_icon_generator.h" #include "chrome/browser/web_applications/web_app_install_finalizer.h" #include "chrome/browser/web_applications/web_app_install_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -67,10 +66,6 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/color_utils.h" -#if defined(OS_MAC) -#include "base/mac/mac_util.h" -#endif - #if defined(OS_WIN) || defined(OS_MAC) || \ (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)) #include "base/command_line.h" @@ -86,19 +81,8 @@ namespace { -// Note: When adding new tests and any bitmap resources they may require, please -// make sure the filename reflects the actual pixel size of the bitmap and that -// it includes a reference to the color of the bitmap. Avoid multi-color -// images unless they are necessary to test something. For example, if you need -// to add a blue square image with edge size 4096, the filename should be -// something like 4096x4096-blue.png and the RGB value of the blue color used -// should match SK_ColorBLUE. This ensures that the test can be validated just -// by reading the code and avoids looking up pixel colors in image editors or -// in defined constants with non-descriptive names. - constexpr char kUpdateHistogramName[] = "Webapp.Update.ManifestUpdateResult"; -// DEPRECATED: Do not use in new tests (see note above). constexpr char kInstallableIconList[] = R"( [ { @@ -110,8 +94,8 @@ )"; constexpr SkColor kInstallableIconTopLeftColor = SkColorSetRGB(0x15, 0x96, 0xE0); +constexpr SkColor kBasicIconTopLeftColor = SkColorSetRGB(0x55, 0x55, 0x55); -// DEPRECATED: Do not use in new tests (see note above). constexpr char kAnotherInstallableIconList[] = R"( [ { @@ -121,8 +105,6 @@ } ] )"; -constexpr SkColor kAnotherInstallableIconTopLeftColor = - SkColorSetRGB(0x5C, 0x5C, 0x5C); constexpr char kAnotherShortcutsItemName[] = "Timeline"; constexpr char16_t kAnotherShortcutsItemName16[] = u"Timeline"; @@ -181,26 +163,8 @@ ] )"; -// Two 'unimportant' icon sizes, smaller than the smallest generated icon on all -// platforms. This simplifies creating test expectations as it avoids having -// unimportant icons affecting generated icons, which inherit their bits from -// the next size up when left unspecified by the manifest. -constexpr int kUnimportantIconSize = 2; -constexpr int kUnimportantIconSize2 = 4; - -// An icon size guaranteed to meet the installability requirements, and on all -// platforms is larger than both the install icon and launcher icon. -constexpr int kInstallabilityIconSize = 512; -// The minimum icon size to meet the installability criteria. -constexpr int kInstallMinSize = 192; - -// Platform definitions for evaluating rules of which size to look for in a -// shortcut. -constexpr int kAll = 0; -constexpr int kWin = 1; // Windows-only rule. -constexpr int kMac = 2; // Mac-only rule. -constexpr int kNotWin = 3; // All platforms except Windows. -constexpr int kNotMac = 4; // All platforms except Mac. +constexpr SkColor kAnotherInstallableIconTopLeftColor = + SkColorSetRGB(0x5C, 0x5C, 0x5C); ManifestUpdateManager& GetManifestUpdateManager(Browser* browser) { return WebAppProvider::GetForTest(browser->profile()) @@ -288,75 +252,20 @@ } void OnShortcutInfoRetrieved(std::unique_ptr<ShortcutInfo> shortcut_info) { - updated_colors_ = {}; if (shortcut_info) { - gfx::ImageFamily::const_iterator it; - // Loop through each size in the ImgFamily and add it to the color map. - for (it = shortcut_info->favicon.begin(); - it != shortcut_info->favicon.end(); ++it) { - updated_colors_.emplace_back(it->Size().width(), - it->AsBitmap().getColor(0, 0)); - } + updated_shortcut_top_left_color_ = + shortcut_info->favicon.begin()->AsBitmap().getColor(0, 0); } shortcut_run_loop_->Quit(); } - bool RuleAppliesToThisOS(int os, int size) { -#if defined(OS_WIN) - return os == kWin || os == kNotMac || os == kAll; -#elif defined(OS_MAC) - // Older MAC OS versions than 11.0 don't seem to write size 48 to the - // shortcut. Instead of complicating all the call sites with OS-specific - // information, just make size 48 optional on MAC OS versions older than - // 11.0. - if (!base::mac::IsAtLeastOS11() && size == web_app::icon_size::k48) - return false; - return os == kMac || os == kNotWin || os == kAll; -#else - return os == kNotWin || os == kNotMac || os == kAll; -#endif - } - - // Confirms that the platform shortcut for this app (with id `app_id`) - // contains an icon family that matches exactly the color specified in - // `expectations`. The latter is a vector mapping (size, os) to an SK_Color - // value. - void ConfirmShortcutColors( - const AppId& app_id, - const std::vector<std::pair<std::pair<int, int>, SkColor>>& - expectations) { + void CheckShortcutInfoUpdated(const AppId& app_id, SkColor top_left_color) { GetProvider().os_integration_manager().GetShortcutInfoForApp( app_id, base::BindOnce( &ManifestUpdateManagerBrowserTest::OnShortcutInfoRetrieved, base::Unretained(this))); shortcut_run_loop_->Run(); - - std::vector<std::pair<int /* size */, SkColor>>::const_iterator - actual_size_to_color_it = updated_colors_.begin(); - for (auto expected_size_to_color_it : expectations) { - int expected_size = expected_size_to_color_it.first.first; - int platform = expected_size_to_color_it.first.second; - SkColor expected_color = expected_size_to_color_it.second; - - if (!RuleAppliesToThisOS(platform, expected_size)) { - SCOPED_TRACE(::testing::Message() << "Skipping size " << expected_size - << " (wrong os: " << platform << ")"); - continue; - } - - int actual_size = actual_size_to_color_it->first; - SkColor actual_color = actual_size_to_color_it->second; - EXPECT_EQ(expected_size, actual_size); - EXPECT_EQ(expected_color, actual_color) - << "Size " << expected_size << ": Expecting ARGB " << std::hex - << expected_color << " but found " << std::hex << actual_color; - ++actual_size_to_color_it; - } - - ASSERT_EQ(updated_colors_.end(), actual_size_to_color_it) - << "Unexpected size found in shortcut: " - << actual_size_to_color_it->first << ": ARGB " << std::hex - << actual_size_to_color_it->second; + EXPECT_EQ(updated_shortcut_top_left_color_, top_left_color); } std::unique_ptr<net::test_server::HttpResponse> RequestHandlerOverride( @@ -540,10 +449,7 @@ private: base::test::ScopedFeatureList scoped_feature_list_; absl::optional<base::RunLoop> shortcut_run_loop_; - // A vector mapping image sizes to shortcut colors. Note that the top left - // pixel color for each size is used as the representation color for that - // size, even if the image is multi-colored. - std::vector<std::pair<int, SkColor>> updated_colors_; + absl::optional<SkColor> updated_shortcut_top_left_color_; OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; }; @@ -923,12 +829,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); // Updated theme_color loses any transparency. EXPECT_EQ(GetProvider().registrar().GetAppThemeColor(app_id), @@ -1024,12 +925,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppThemeColor(app_id), SK_ColorRED); // The app name must not change without user confirmation. EXPECT_EQ(GetProvider().registrar().GetAppShortName(app_id), "App name 1"); @@ -1054,12 +950,7 @@ ManifestUpdateResult::kAppUpToDate); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 0); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); } IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest, @@ -1081,14 +972,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kAnotherInstallableIconTopLeftColor); } IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest, @@ -1113,12 +997,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); // Policy installed apps should continue to be not uninstallable by the user // after updating. @@ -1145,12 +1024,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppScope(app_id), http_server_.GetURL("/")); } @@ -1176,26 +1050,10 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - // The icon should be updated only if product icon updates are allowed. - if (IsUpdateDialogEnabled()) { - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); - } else { - ConfirmShortcutColors(app_id, - {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); - } + CheckShortcutInfoUpdated(app_id, IsUpdateDialogEnabled() + ? kAnotherInstallableIconTopLeftColor + : kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppScope(app_id), http_server_.GetURL("/")); } @@ -1222,14 +1080,7 @@ histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); // The icon should have updated. - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kAnotherInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppScope(app_id), http_server_.GetURL("/")); } @@ -1273,27 +1124,14 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kAnotherInstallableIconTopLeftColor); } else { // The icon should not have updated. EXPECT_EQ(GetResultAfterPageLoad(GetAppURL()), ManifestUpdateResult::kAppUpToDate); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 0); - ConfirmShortcutColors(app_id, - {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); } } @@ -1358,12 +1196,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppDisplayMode(app_id), DisplayMode::kStandalone); } @@ -1423,12 +1256,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); std::vector<DisplayMode> app_display_mode_override = GetProvider().registrar().GetAppDisplayModeOverride(app_id); @@ -1463,12 +1291,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); std::vector<DisplayMode> app_display_mode_override = GetProvider().registrar().GetAppDisplayModeOverride(app_id); @@ -1503,12 +1326,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); std::vector<DisplayMode> app_display_mode_override = GetProvider().registrar().GetAppDisplayModeOverride(app_id); @@ -1543,12 +1361,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); std::vector<DisplayMode> app_display_mode_override = GetProvider().registrar().GetAppDisplayModeOverride(app_id); @@ -1620,7 +1433,7 @@ "display": "standalone", "icons": [ { - "src": "/banners/192x192-green.png?ignore", + "src": "/web_apps/basic-192.png?ignore", "sizes": "192x192", "type": "image/png" } @@ -1630,15 +1443,15 @@ OverrideManifest(kManifest, {}); AppId app_id = InstallWebApp(); - // Replace the contents of 192x192-green.png with 192x192-red.png without - // changing the URL. + // Replace the contents of basic-192.png with blue-192.png without changing + // the URL. content::URLLoaderInterceptor url_interceptor(base::BindLambdaForTesting( [this](content::URLLoaderInterceptor::RequestParams* params) -> bool /*intercepted*/ { if (params->url_request.url == - http_server_.GetURL("/banners/192x192-green.png?ignore")) { + http_server_.GetURL("/web_apps/basic-192.png?ignore")) { content::URLLoaderInterceptor::WriteResponse( - "chrome/test/data/banners/192x192-red.png", params->client.get()); + "chrome/test/data/web_apps/blue-192.png", params->client.get()); return true; } return false; @@ -1648,15 +1461,9 @@ ManifestUpdateResult::kAppUpToDate); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 0); + CheckShortcutInfoUpdated(app_id, kBasicIconTopLeftColor); - ConfirmShortcutColors(app_id, {{{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, - {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, - {{256, kAll}, SK_ColorGREEN}}); - - EXPECT_EQ(ReadAppIconPixel(app_id, /*size=*/192), SK_ColorGREEN); + EXPECT_EQ(ReadAppIconPixel(app_id, /*size=*/192), SK_ColorBLACK); } IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest, @@ -1681,7 +1488,7 @@ } IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerBrowserTest_UpdateDialog, - CheckUpdateOfGeneratedIcons_SyncFailure) { + CheckDoesNotUpdateGeneratedIcons_SyncFailure) { // The first "name" character is used to generate icons. Make it like a space // to probe the background color at the center. Spaces are trimmed by the // parser. @@ -1741,44 +1548,23 @@ ManifestUpdateResult update_result = GetResultAfterPageLoad(GetAppURL()); + EXPECT_EQ(update_result, ManifestUpdateResult::kAppUpToDate); + + histogram_tester_.ExpectBucketCount(kUpdateHistogramName, + ManifestUpdateResult::kAppUpdated, 0); + ASSERT_EQ(web_app, GetProvider().registrar().GetAppById(app_id)); - - if (IsUpdateDialogEnabled()) { - EXPECT_EQ(update_result, ManifestUpdateResult::kAppUpdated); - - histogram_tester_.ExpectBucketCount(kUpdateHistogramName, - ManifestUpdateResult::kAppUpdated, 1); - - // An actual icon was downloaded, so icon should not be autogenerated. - EXPECT_FALSE(web_app->is_generated_icon()); - // A non-generated icon was added, so expect 7 instead of 6. - EXPECT_EQ(7u, web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); - // Icon should have turned blue. - for (SquareSizePx size_px : - web_app->downloaded_icon_sizes(IconPurpose::ANY)) { - SCOPED_TRACE(size_px); - EXPECT_EQ(color_utils::SkColorToRgbaString(ReadAppIconPixel( - app_id, size_px, /*x=*/size_px / 2, /*y=*/size_px / 2)), - color_utils::SkColorToRgbaString(SK_ColorBLUE)); - } - } else { - EXPECT_EQ(update_result, ManifestUpdateResult::kAppUpToDate); - - histogram_tester_.ExpectBucketCount(kUpdateHistogramName, - ManifestUpdateResult::kAppUpdated, 0); - - // Still autogenerated icons, no change. - EXPECT_TRUE(web_app->is_generated_icon()); - // Not 7u, no non-generated icon added. - EXPECT_EQ(6u, web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); - // Not SK_ColorBLUE for blue-192.png. - for (SquareSizePx size_px : - web_app->downloaded_icon_sizes(IconPurpose::ANY)) { - SCOPED_TRACE(size_px); - EXPECT_EQ(color_utils::SkColorToRgbaString(ReadAppIconPixel( - app_id, size_px, /*x=*/size_px / 2, /*y=*/size_px / 2)), - color_utils::SkColorToRgbaString(SK_ColorDKGRAY)); - } + // Still autogenerated icons, no change. + EXPECT_TRUE(web_app->is_generated_icon()); + // Not 7u, no non-generated icon added. + EXPECT_EQ(6u, web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); + // Not SK_ColorBLUE for blue-192.png. + for (SquareSizePx size_px : + web_app->downloaded_icon_sizes(IconPurpose::ANY)) { + SCOPED_TRACE(size_px); + EXPECT_EQ(color_utils::SkColorToRgbaString(ReadAppIconPixel( + app_id, size_px, /*x=*/size_px / 2, /*y=*/size_px / 2)), + color_utils::SkColorToRgbaString(SK_ColorDKGRAY)); } } @@ -1817,12 +1603,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppCaptureLinks(app_id), blink::mojom::CaptureLinks::kNewClient); } @@ -1858,12 +1639,7 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kInstallableIconTopLeftColor); EXPECT_EQ(GetProvider().registrar().GetAppById(app_id)->launch_handler(), (LaunchHandler{LaunchHandler::RouteTo::kExistingClient, LaunchHandler::NavigateExistingClient::kNever})); @@ -2705,24 +2481,9 @@ EXPECT_EQ(GetResultAfterPageLoad(GetAppURL()), ManifestUpdateResult::kAppUpdated); // The icon should be updated only if product icon updates are allowed. - if (IsUpdateDialogEnabled()) { - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); - } else { - ConfirmShortcutColors(app_id, - {{{32, kAll}, kInstallableIconTopLeftColor}, - {{48, kAll}, kInstallableIconTopLeftColor}, - {{64, kWin}, kInstallableIconTopLeftColor}, - {{96, kWin}, kInstallableIconTopLeftColor}, - {{128, kAll}, kInstallableIconTopLeftColor}, - {{256, kAll}, kInstallableIconTopLeftColor}}); - } + CheckShortcutInfoUpdated(app_id, IsUpdateDialogEnabled() + ? kAnotherInstallableIconTopLeftColor + : kInstallableIconTopLeftColor); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); } @@ -2890,12 +2651,7 @@ ManifestUpdateResult::kAppUpdated, 1); // The icon should have changed, as the file has been updated (but the url // is the same). - ConfirmShortcutColors(app_id, {{{32, kAll}, SK_ColorRED}, - {{48, kAll}, SK_ColorRED}, - {{64, kWin}, SK_ColorRED}, - {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, - {{256, kAll}, SK_ColorRED}}); + CheckShortcutInfoUpdated(app_id, SK_ColorRED); EXPECT_EQ(ReadAppIconPixel(app_id, /*size=*/256), SK_ColorRED); } else { @@ -2903,12 +2659,7 @@ ManifestUpdateResult::kAppUpToDate); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 0); - ConfirmShortcutColors(app_id, {{{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, - {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, - {{256, kAll}, SK_ColorGREEN}}); + CheckShortcutInfoUpdated(app_id, SK_ColorGREEN); EXPECT_EQ(ReadAppIconPixel(app_id, /*size=*/256), SK_ColorGREEN); } @@ -2933,15 +2684,16 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); + + histogram_tester_.ExpectBucketCount("WebApp.Icon.DownloadedResultOnUpdate", + IconsDownloadedResult::kCompleted, 1); + + histogram_tester_.ExpectBucketCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnUpdate", + net::HttpStatusCode::HTTP_OK, 1); + // The icon should have changed. - ConfirmShortcutColors( - app_id, {{{32, kAll}, kAnotherInstallableIconTopLeftColor}, - {{48, kAll}, kAnotherInstallableIconTopLeftColor}, - {{64, kWin}, kAnotherInstallableIconTopLeftColor}, - {{96, kWin}, kAnotherInstallableIconTopLeftColor}, - {{128, kAll}, kAnotherInstallableIconTopLeftColor}, - {{256, kAll}, kAnotherInstallableIconTopLeftColor}, - {{512, kNotWin}, kAnotherInstallableIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kAnotherInstallableIconTopLeftColor); } IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerIconUpdatingBrowserTest, @@ -2969,6 +2721,13 @@ OverrideManifest(kManifest, {}); AppId app_id = InstallWebApp(); + histogram_tester_.ExpectBucketCount("WebApp.Icon.DownloadedResultOnCreate", + IconsDownloadedResult::kCompleted, 1); + + histogram_tester_.ExpectBucketCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnCreate", + net::HttpStatusCode::HTTP_OK, 1); + // Make basic-48.png fail to download. // Replace the contents of basic-192.png with blue-192.png without changing // the URL. @@ -2995,6 +2754,12 @@ histogram_tester_.ExpectBucketCount( kUpdateHistogramName, ManifestUpdateResult::kIconDownloadFailed, 1); + // The `url_interceptor` above can't simulate net::HttpStatusCode error + // properly, WebApp.Icon.DownloadedHttpStatusCodeOnUpdate left untested here. + histogram_tester_.ExpectBucketCount( + "WebApp.Icon.DownloadedResultOnUpdate", + IconsDownloadedResult::kAbortedDueToFailure, 1); + // Since one request failed, none of the icons should be updated. So the '192' // size here is not updated to blue. EXPECT_EQ(ReadAppIconPixel(app_id, /*size=*/48), SK_ColorBLACK); @@ -3715,12 +3480,7 @@ GetProvider().registrar().GetAppShortName(app_id)); constexpr SkColor kUpdatedIconTopLeftColor = SkColorSetRGB(0xFF, 0x00, 0x00); - ConfirmShortcutColors(app_id, {{{32, kAll}, kUpdatedIconTopLeftColor}, - {{48, kAll}, kUpdatedIconTopLeftColor}, - {{64, kWin}, kUpdatedIconTopLeftColor}, - {{96, kWin}, kUpdatedIconTopLeftColor}, - {{128, kAll}, kUpdatedIconTopLeftColor}, - {{256, kAll}, kUpdatedIconTopLeftColor}}); + CheckShortcutInfoUpdated(app_id, kUpdatedIconTopLeftColor); } // This test exercises the upgrade path for benign (non-App Identity) manifest @@ -3830,16 +3590,12 @@ kWithFlagPolicyAppIdentity = 1 << 5, kWithFlagAppIdDialog = 1 << 6, kActionUpdateTitle = 1 << 7, - kActionUpdateTitleAndLauncherIcon = 1 << 8, - kActionUpdateLauncherIcon = 1 << 9, - kActionUpdateInstallIcon = 1 << 10, - kActionUpdateLauncherAndInstallIcon = 1 << 11, - kActionUpdateUnimportantIcon = 1 << 12, - kActionRemoveLauncherIcon = 1 << 13, - kActionRemoveInstallIcon = 1 << 14, - kActionRemoveUnimportantIcon = 1 << 15, - kActionSwitchFromLauncher = 1 << 16, - kActionSwitchToLauncher = 1 << 17, + kActionUpdateSingleIcon = 1 << 8, + kActionUpdateTitleAndSingleIcon = 1 << 9, + kActionAddSingleIcon = 1 << 10, + kActionUpdateMultiIcons = 1 << 11, + kActionRemoveSingleIcon = 1 << 12, + kActionSwitchIconSize = 1 << 13, }; class ManifestUpdateManagerBrowserTest_AppIdentityParameterized @@ -3883,66 +3639,38 @@ return std::get<2>(GetParam()) & AppIdTestParam::kWithFlagPolicyAppIdentity; } - bool TitleUpdate() const { + bool TitleUpdateRequested() const { return std::get<0>(GetParam()) & AppIdTestParam::kActionUpdateTitle || std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateTitleAndLauncherIcon; + AppIdTestParam::kActionUpdateTitleAndSingleIcon; } - bool AnyIconUpdate() const { - return LauncherIconUpdate() || LauncherIconRemove() || - InstallIconUpdate() || InstallIconRemove() || - UnimportantIconUpdate() || UnimportantIconRemove() || - IconSwitchFromLauncher() || IconSwitchToLauncher(); + bool AnyIconUpdateRequested() const { + return SingleIconAddRequested() || SingleIconRemoveRequested() || + SingleIconUpdateRequested() || MultiIconUpdateRequested() || + IconSwitchUpdateRequested(); } - - bool LauncherIconUpdate() const { - return std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateLauncherIcon || + bool SingleIconAddRequested() const { + return std::get<0>(GetParam()) & AppIdTestParam::kActionAddSingleIcon; + } + bool SingleIconRemoveRequested() const { + return std::get<0>(GetParam()) & AppIdTestParam::kActionRemoveSingleIcon; + } + bool SingleIconUpdateRequested() const { + return std::get<0>(GetParam()) & AppIdTestParam::kActionUpdateSingleIcon || std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateTitleAndLauncherIcon || - std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateLauncherAndInstallIcon; + AppIdTestParam::kActionUpdateTitleAndSingleIcon; + } + bool MultiIconUpdateRequested() const { + return std::get<0>(GetParam()) & AppIdTestParam::kActionUpdateMultiIcons; + } + bool IconSwitchUpdateRequested() const { + return std::get<0>(GetParam()) & AppIdTestParam::kActionSwitchIconSize; } - bool InstallIconUpdate() const { - return std::get<0>(GetParam()) & AppIdTestParam::kActionUpdateInstallIcon || - std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateLauncherAndInstallIcon; - } - - bool UnimportantIconUpdate() const { - return std::get<0>(GetParam()) & - AppIdTestParam::kActionUpdateUnimportantIcon; - } - - bool LauncherIconRemove() const { - return std::get<0>(GetParam()) & AppIdTestParam::kActionRemoveLauncherIcon; - } - - bool InstallIconRemove() const { - return std::get<0>(GetParam()) & AppIdTestParam::kActionRemoveInstallIcon; - } - - bool UnimportantIconRemove() const { - return std::get<0>(GetParam()) & - AppIdTestParam::kActionRemoveUnimportantIcon; - } - - bool IconSwitchFromLauncher() const { - return std::get<0>(GetParam()) & AppIdTestParam::kActionSwitchFromLauncher; - } - - bool IconSwitchToLauncher() const { - return std::get<0>(GetParam()) & AppIdTestParam::kActionSwitchToLauncher; - } - - // This function describes in which scenarios the test should expect the title - // of an app to change. It should mirror exactly the expectations we have of - // the implementation and be simple to read for easy verification. bool ExpectTitleUpdate() const { - if (!TitleUpdate()) - return false; // Titles should not update without a request to update. + if (!TitleUpdateRequested()) + return false; if (IsDefaultApp()) return true; @@ -3951,26 +3679,29 @@ return IsAppIdentityUpdateDialogEnabled(); } - // This function describes in which scenarios the test should expect the icons - // of an app to change. It should mirror exactly the expectations we have of - // the implementation and be simple to read for easy verification. bool ExpectIconUpdate() const { - if (!AnyIconUpdate()) - return false; // Icons should not update without a request to update. + // Ideally, this should just check AnyIconUpdateRequested(), but adding and + // removing of icons results in kAppNotEligible when updating, even for + // Default apps. Therefore, only the supported upgrade paths must be + // enumerated here. + if (!SingleIconUpdateRequested() && !MultiIconUpdateRequested() && + !IconSwitchUpdateRequested()) + return false; if (IsDefaultApp()) return true; if (IsPolicyApp() && IsPolicyAppIdentityOverrideEnabled()) return true; - // Changes to the install/launcher icon should be accepted if the app - // identity dialog is shown and accepted (auto-accepted in the case of the - // tests). Changes to unimportant icons should in the future not need the - // app identity dialog, but are included here now so that it is possible to - // get back to the current state by turning off the feature flag. - if (AnyIconUpdate() && !IsAppIdentityUpdateDialogEnabled()) - return false; + if (SingleIconUpdateRequested() && IsAppIdentityUpdateDialogEnabled()) + return true; - return true; + return false; + } + + ManifestUpdateResult ExpectedResultWhenNoUpdate() const { + if (SingleIconAddRequested() || SingleIconRemoveRequested()) + return ManifestUpdateResult::kAppNotEligible; + return ManifestUpdateResult::kAppUpToDate; } static std::string ParamToString( @@ -3982,26 +3713,18 @@ AppIdTestParam action = std::get<0>(param_info.param); if (action & AppIdTestParam::kActionUpdateTitle) result += "UpdateTitle_"; - if (action & AppIdTestParam::kActionUpdateTitleAndLauncherIcon) - result += "UpdateTitleAndLauncherIcon_"; - if (action & AppIdTestParam::kActionUpdateLauncherIcon) - result += "UpdateLauncherIcon_"; - if (action & AppIdTestParam::kActionUpdateInstallIcon) - result += "UpdateInstallIcon_"; - if (action & AppIdTestParam::kActionUpdateLauncherAndInstallIcon) - result += "UpdateLauncherAndInstallIcon_"; - if (action & AppIdTestParam::kActionUpdateUnimportantIcon) - result += "UpdateUnimportantIcon_"; - if (action & AppIdTestParam::kActionRemoveLauncherIcon) - result += "RemoveLauncherIcon_"; - if (action & AppIdTestParam::kActionRemoveInstallIcon) - result += "RemoveInstallIcon_"; - if (action & AppIdTestParam::kActionRemoveUnimportantIcon) - result += "RemoveUnimportantIcon_"; - if (action & AppIdTestParam::kActionSwitchFromLauncher) - result += "SwitchFromLauncher_"; - if (action & AppIdTestParam::kActionSwitchToLauncher) - result += "SwitchToLauncher_"; + if (action & AppIdTestParam::kActionUpdateSingleIcon) + result += "UpdateSingleIcon_"; + if (action & AppIdTestParam::kActionUpdateTitleAndSingleIcon) + result += "UpdateTitleAndSingleIcon_"; + if (action & AppIdTestParam::kActionRemoveSingleIcon) + result += "RemoveSingleIcon_"; + if (action & AppIdTestParam::kActionAddSingleIcon) + result += "AddSingleIcon_"; + if (action & AppIdTestParam::kActionUpdateMultiIcons) + result += "UpdateMultiIcons_"; + if (action & AppIdTestParam::kActionSwitchIconSize) + result += "SwitchIcon_"; AppIdTestParam type = std::get<1>(param_info.param); if (type & AppIdTestParam::kTypeWebApp) @@ -4027,80 +3750,6 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -// A list of the supported colored images (of different sizes) used in the test. -enum : int { - kNone = 0, - kGreen = 1, - kRed = 2, -}; - -std::string GenerateIconRow(int size, int color) { - std::string size_str = base::NumberToString(size); - std::string row = " { "; - row += "\"src\": \"" + size_str + "x" + size_str + "-"; - switch (color) { - case kNone: - row += "?"; - break; - case kGreen: - row += "green"; - break; - case kRed: - row += "red"; - break; - } - row += ".png\", "; - row += "\"sizes\": \"" + size_str + "x" + size_str + "\", "; - row += "\"type\": \"image/png\" }"; - return row; -} - -std::string GenerateColoredIconList(int installability_icon, - int launcher_icon, - int install_icon, - int other_icon, - int other_icon2 = kNone) { - std::string icon_list; - if (install_icon != kNone) { - icon_list += GenerateIconRow(kInstallIconSize, install_icon); - } - if (launcher_icon != kNone) { - if (!icon_list.empty()) - icon_list += ",\n"; - icon_list += GenerateIconRow(kLauncherIconSize, launcher_icon); - } - if (other_icon != kNone) { - if (!icon_list.empty()) - icon_list += ",\n"; - icon_list += GenerateIconRow(kUnimportantIconSize, other_icon); - } - if (other_icon2 != kNone) { - if (!icon_list.empty()) - icon_list += ",\n"; - icon_list += GenerateIconRow(kUnimportantIconSize2, other_icon2); - } - if (installability_icon != kNone) { - if (!icon_list.empty()) - icon_list += ",\n"; - icon_list += GenerateIconRow(kInstallabilityIconSize, installability_icon); - } - // Installability requirements mandate at least one large icon. - if ((kLauncherIconSize < kInstallMinSize || launcher_icon == kNone) && - (kInstallIconSize < kInstallMinSize || install_icon == kNone) && - (kUnimportantIconSize < kInstallMinSize || other_icon == kNone) && - (kUnimportantIconSize2 < kInstallMinSize || other_icon2 == kNone) && - (kInstallabilityIconSize < kInstallMinSize || - installability_icon == kNone)) { - if (!icon_list.empty()) - icon_list += ",\n"; - icon_list += " { \"error\": \"Installability requirements not met\" }"; - } - - if (!icon_list.empty()) - icon_list += "\n"; - return "\n [\n" + icon_list + " ]\n "; -} - IN_PROC_BROWSER_TEST_P( ManifestUpdateManagerBrowserTest_AppIdentityParameterized, CheckCombinations) { @@ -4114,288 +3763,71 @@ } )"; - ManifestUpdateTask::BypassWindowCloseWaitingForTesting() = true; + // Starting icon set always uses solid green icons. + constexpr SkColor kOriginalIconTopLeftColor = SkColorSetRGB(0x00, 0xFF, 0x00); + // The icons that get updated are all solid red. + constexpr SkColor kUpdatedIconTopLeftColor = SkColorSetRGB(0xFF, 0x00, 0x00); + + // This is always the starting set of icons. Please note that some sizes will + // be auto-generated (see SizesToGenerate()), so the starting state when + // debugging will also consist of sizes 32, 48, 64, 96, 128. Size 256 would be + // autogenerated also, if it were not provided. + constexpr char kIconList[] = R"( + [ + { "src": "256x256-green.png", "sizes": "256x256", "type": "image/png" }, + { "src": "512x512-green.png", "sizes": "512x512", "type": "image/png" } + ] + )"; + + // If we are supposed to remove one icon, this is the end state (512 removed), + // plus auto-generated sizes (see comment in kIconList). + constexpr char kRemovedSingleIconList[] = R"( + [ + { "src": "256x256-green.png", "sizes": "256x256", "type": "image/png" }, + ] + )"; + // If we are supposed to add one icon, this is the end state (128 added), + // plus auto-generated sizes (see comment in kIconList). + constexpr char kAddedSingleIconList[] = R"( + [ + { "src": "128x128-red.png", "sizes": "256x256", "type": "image/png" }, + { "src": "256x256-green.png", "sizes": "256x256", "type": "image/png" }, + { "src": "512x512-green.png", "sizes": "512x512", "type": "image/png" } + ] + )"; + // Updating one icon only changes the bits of size 256 to red. + constexpr char kUpdatedSingleIconList[] = R"( + [ + { "src": "256x256-red.png", "sizes": "256x256", "type": "image/png" }, + { "src": "512x512-green.png", "sizes": "512x512", "type": "image/png" } + ] + )"; + // Updating multiple icons changes size 256 and size 512 to red. + constexpr char kUpdatedMultiIconList[] = R"( + [ + { "src": "256x256-red.png", "sizes": "256x256", "type": "image/png" }, + { "src": "512x512-red.png", "sizes": "512x512", "type": "image/png" } + ] + )"; + // Icon switch involves removing a size and replacing it with another. Here, + // size 256 has been removed and size 128 added. Note that size 256 will still + // be found in the end state because it gets auto-generated. + constexpr char kIconSwitchList[] = R"( + [ + { "src": "128x128-red.png", "sizes": "128x128", "type": "image/png" }, + { "src": "512x512-green.png", "sizes": "512x512", "type": "image/png" } + ] + )"; testing::TestParamInfo< std::tuple<AppIdTestParam, AppIdTestParam, AppIdTestParam>> param(GetParam(), 0); - std::string trace = "\n---------------------------\nParameterized test: " + - ParamToString(param) + "\nType: "; - if (IsPolicyApp()) - trace += "Policy"; - if (IsDefaultApp()) - trace += "Default"; - if (IsWebApp()) - trace += "WebApp"; - trace += (IsAppIdentityUpdateDialogEnabled() ? ", with AppIdDlg: YES\n" - : ", with AppIdDlg: NO\n"); - - trace += base::ReplaceStringPlaceholders( - "UPDATE: Title: $1 Launcher $2 Install $3 Other $4\n", - {base::NumberToString(TitleUpdate()), - base::NumberToString(LauncherIconUpdate()), - base::NumberToString(InstallIconUpdate()), - base::NumberToString(UnimportantIconUpdate())}, - nullptr); - trace += base::ReplaceStringPlaceholders( - "REMOVE: Launcher $1 Install $2 Other $3\n", - {base::NumberToString(LauncherIconRemove()), - base::NumberToString(InstallIconRemove()), - base::NumberToString(UnimportantIconRemove())}, - nullptr); - trace += base::ReplaceStringPlaceholders( - "SWITCH: FromLauncher $1 ToLauncher $2\n", - {base::NumberToString(IconSwitchFromLauncher()), - base::NumberToString(IconSwitchToLauncher())}, - nullptr); - trace += base::ReplaceStringPlaceholders( - "Should result in: Title update: $1 Icon update $2\n", - {base::NumberToString(ExpectTitleUpdate()), - base::NumberToString(ExpectIconUpdate())}, - nullptr); - trace += base::ReplaceStringPlaceholders( - "Sizes: InstallIcon $1, LauncherIcon $2, ExtraIcon1 $3, ExtraIcon2 $4 " - "Installability $5\n", - {base::NumberToString(kInstallIconSize), - base::NumberToString(kLauncherIconSize), - base::NumberToString(kUnimportantIconSize), - base::NumberToString(kUnimportantIconSize2), - base::NumberToString(kInstallabilityIconSize)}, - nullptr); - trace += "---------------------------\n"; - if (IsAppIdentityUpdateDialogEnabled()) chrome::SetAutoAcceptAppIdentityUpdateForTesting(true); std::string app_name = "Test app name"; - - // The 'before' and 'after' icon lists. - std::string starting_stage; - std::string ending_stage; - - // This is the default icon list (all green icons) and is overridden below, - // if need be. - starting_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - - // This is the resulting shortcut colors (per size) for the default icon list - // above, and similar to `starting_stage` it is overridden below when needed. - // NOTE: When considering which shortcut sizes appear on which platform, the - // system creates an intersection between `kDesiredIconSizesForShortcut` - // (which is platform-dependent) and `SizesToGenerate()` (which is hard-coded - // to { 32, 48, 64, 96, 128, 256 } for all platforms. This can lead to some - // discrepancies per platform. For example, Windows specifies more sizes - // in`kDesiredIconSizesForShortcut` than other OS', which is why it is common - // to find auto-generated icons for size 64 and 96 only on Windows. Similarly, - // size 512 is not part of `kDesiredIconSizesForShortcut` on Windows, and - // that size therefore does not always feature in the shortcut expectations. - std::vector<std::pair<std::pair<int, int>, SkColor>> - expected_shortcut_colors_before = { - {{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - // Although sizes 64 and 96 are within the SizesToGenerate() list they - // are listed in `kDesiredIconSizesForShortcut` on Windows only. - {{64, kWin}, SK_ColorGREEN}, - {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, - {{256, kAll}, SK_ColorGREEN}, - // The tests use size 512 as the icon size that guarantees that the - // installability requirements are met, but that size is not listed as - // a desired shortcut size on Windows. - {{512, kNotWin}, SK_ColorGREEN}}; - - // This needs to be populated for each test below. - std::vector<std::pair<std::pair<int, int>, SkColor>> - expected_shortcut_colors_if_updated; - - if (LauncherIconUpdate() && InstallIconUpdate()) { - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kRed, - /* install_icon= */ kRed, - /* other_icon= */ kGreen); - - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorRED}, - {{48, kAll}, SK_ColorRED}, - {{64, kWin}, SK_ColorRED}, - {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, - // On Mac, this size is the launcher icon, so red is expected. - {{256, kMac}, SK_ColorRED}, - // On other platforms, there is no size 256 specified, so this is - // generated from the installability icon (size 512), which is green. - {{256, kNotMac}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - } else if (IconSwitchFromLauncher()) { - // Starting stage is with a launcher icon but without an unimportant icon. - starting_stage = GenerateColoredIconList(/* installability_icon= */ kRed, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kNone); - - expected_shortcut_colors_before = { - {{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, - {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, - // On Mac, this size is the launcher icon, so green is expected. - {{256, kMac}, SK_ColorGREEN}, - // On other platforms, there is no size 256 specified, so this is - // generated from the installability icon (size 512), which is red. - {{256, kNotMac}, SK_ColorRED}, - {{512, kNotWin}, SK_ColorRED}}; - - // Ending stage is without a launcher icon but with an unimportant icon. - ending_stage = GenerateColoredIconList(/* installability_icon= */ kRed, - /* launcher_icon= */ kNone, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorGREEN}, {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorRED}, {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, {{256, kAll}, SK_ColorRED}, - {{512, kNotWin}, SK_ColorRED}}; - } else if (IconSwitchToLauncher()) { - // Starting stage is without a launcher icon but with an unimportant icon. - starting_stage = GenerateColoredIconList(/* installability_icon= */ kRed, - /* launcher_icon= */ kNone, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - - expected_shortcut_colors_before = { - {{32, kAll}, SK_ColorGREEN}, {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorRED}, {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, {{256, kAll}, SK_ColorRED}, - {{512, kNotWin}, SK_ColorRED}}; - - // Ending stage is with the a icon but without an unimportant icon. - ending_stage = GenerateColoredIconList(/* installability_icon= */ kRed, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kNone); - - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, - {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, - // On Mac, this size is the launcher icon, so green is expected. - {{256, kMac}, SK_ColorGREEN}, - // On other platforms, this is inherited from the installability icon. - {{256, kNotMac}, SK_ColorRED}, - {{512, kNotWin}, SK_ColorRED}}; - } else if (LauncherIconUpdate()) { - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kRed, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorRED}, - {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, - // On Mac, this size is the launcher icon, so red is expected. - {{256, kMac}, SK_ColorRED}, - // On other platforms, this is inherited from the installability icon. - {{256, kNotMac}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - } else if (InstallIconUpdate()) { - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kRed, - /* other_icon= */ kGreen); - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorRED}, {{48, kAll}, SK_ColorRED}, - {{64, kWin}, SK_ColorGREEN}, {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, {{256, kAll}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - } else if (UnimportantIconUpdate()) { - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kRed); - - // There should be no effect on the shortcut icons when an unimportant icon - // updates. - expected_shortcut_colors_if_updated = expected_shortcut_colors_before; - } else if (LauncherIconRemove()) { - starting_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kRed, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - expected_shortcut_colors_before = { - {{32, kAll}, SK_ColorGREEN}, - {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorRED}, - {{96, kWin}, SK_ColorRED}, - {{128, kAll}, SK_ColorRED}, - // On Mac, this size is the launcher icon, so red is expected. - {{256, kMac}, SK_ColorRED}, - // On other platforms, this is inherited from the installability icon. - {{256, kNotMac}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - - // Note that the starting stage for this request is not a set of icons that - // are all green, but instead the launcher icon is red. Then, when the - // launcher icon is removed, we can verify that it becomes auto-generated - // from other icons (and therefore turns green). - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kNone, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen); - - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorGREEN}, {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, {{256, kAll}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - } else if (InstallIconRemove()) { - // The install icon size is not a size that is auto-generated for the - // shortcut when missing, so when removed there should be - // no effect. - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kNone, - /* other_icon= */ kGreen); - expected_shortcut_colors_if_updated = expected_shortcut_colors_before; - } else if (UnimportantIconRemove()) { - starting_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kGreen, - /* other_icon2 */ kGreen); - expected_shortcut_colors_before = { - {{32, kAll}, SK_ColorGREEN}, {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, {{256, kAll}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - - // Removing an unimportant icon should have no effect on other icons. - ending_stage = GenerateColoredIconList(/* installability_icon= */ kGreen, - /* launcher_icon= */ kGreen, - /* install_icon= */ kGreen, - /* other_icon= */ kNone, - /* other_icon2 */ kGreen); - expected_shortcut_colors_if_updated = { - {{32, kAll}, SK_ColorGREEN}, {{48, kAll}, SK_ColorGREEN}, - {{64, kWin}, SK_ColorGREEN}, {{96, kWin}, SK_ColorGREEN}, - {{128, kAll}, SK_ColorGREEN}, {{256, kAll}, SK_ColorGREEN}, - {{512, kNotWin}, SK_ColorGREEN}}; - } else if (TitleUpdate()) { - ending_stage = starting_stage; // No icon change. - expected_shortcut_colors_if_updated = expected_shortcut_colors_before; - } else { - NOTREACHED(); // Unhandled test input. - } - - OverrideManifest(kManifestTemplate, {app_name, starting_stage}); + OverrideManifest(kManifestTemplate, {app_name, kIconList}); AppId app_id; if (IsDefaultApp()) { @@ -4411,32 +3843,45 @@ const WebApp* web_app = GetProvider().registrar().GetAppById(app_id); ASSERT_TRUE(web_app); - if (TitleUpdate()) + if (TitleUpdateRequested()) app_name = "Different app name"; - OverrideManifest(kManifestTemplate, {app_name, ending_stage}); - SCOPED_TRACE(trace + "Icons before: \n" + starting_stage + "\n" + - "Icons afer: \n" + ending_stage + "\n"); + if (SingleIconUpdateRequested()) { + OverrideManifest(kManifestTemplate, {app_name, kUpdatedSingleIconList}); + } else if (SingleIconAddRequested()) { + OverrideManifest(kManifestTemplate, {app_name, kAddedSingleIconList}); + } else if (SingleIconRemoveRequested()) { + OverrideManifest(kManifestTemplate, {app_name, kRemovedSingleIconList}); + } else if (MultiIconUpdateRequested()) { + OverrideManifest(kManifestTemplate, {app_name, kUpdatedMultiIconList}); + } else if (IconSwitchUpdateRequested()) { + OverrideManifest(kManifestTemplate, {app_name, kIconSwitchList}); + } else { + OverrideManifest(kManifestTemplate, {app_name, kIconList}); + } - bool expectations_match = (TitleUpdate() == ExpectTitleUpdate()) && - (AnyIconUpdate() == ExpectIconUpdate()); - if ((TitleUpdate() || AnyIconUpdate()) && expectations_match) { + bool expectations_match = (TitleUpdateRequested() == ExpectTitleUpdate()) && + (AnyIconUpdateRequested() == ExpectIconUpdate()); + if ((TitleUpdateRequested() || AnyIconUpdateRequested()) && + expectations_match) { ASSERT_EQ(ManifestUpdateResult::kAppUpdated, GetResultAfterPageLoad(GetAppURL())); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - ConfirmShortcutColors(app_id, expected_shortcut_colors_if_updated); } else { - ASSERT_EQ(ManifestUpdateResult::kAppUpToDate, + ASSERT_EQ(ExpectedResultWhenNoUpdate(), GetResultAfterPageLoad(GetAppURL())); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 0); - ConfirmShortcutColors(app_id, expected_shortcut_colors_before); } EXPECT_EQ(ExpectTitleUpdate() && expectations_match ? "Different app name" : "Test app name", GetProvider().registrar().GetAppShortName(app_id)); + + CheckShortcutInfoUpdated(app_id, ExpectIconUpdate() && expectations_match + ? kUpdatedIconTopLeftColor + : kOriginalIconTopLeftColor); } INSTANTIATE_TEST_SUITE_P( @@ -4444,22 +3889,18 @@ ManifestUpdateManagerBrowserTest_AppIdentityParameterized, testing::Combine( testing::Values(AppIdTestParam::kActionUpdateTitle, - AppIdTestParam::kActionUpdateTitleAndLauncherIcon, - AppIdTestParam::kActionUpdateLauncherIcon, - AppIdTestParam::kActionUpdateInstallIcon, - AppIdTestParam::kActionUpdateLauncherAndInstallIcon, - AppIdTestParam::kActionUpdateUnimportantIcon, - AppIdTestParam::kActionRemoveLauncherIcon, - AppIdTestParam::kActionRemoveInstallIcon, - AppIdTestParam::kActionRemoveUnimportantIcon, - AppIdTestParam::kActionSwitchFromLauncher, - AppIdTestParam::kActionSwitchToLauncher), + AppIdTestParam::kActionUpdateSingleIcon, + AppIdTestParam::kActionUpdateTitleAndSingleIcon, + AppIdTestParam::kActionUpdateMultiIcons, + AppIdTestParam::kActionAddSingleIcon, + AppIdTestParam::kActionRemoveSingleIcon, + AppIdTestParam::kActionSwitchIconSize), testing::Values(AppIdTestParam::kTypeDefaultApp, AppIdTestParam::kTypePolicyApp, AppIdTestParam::kTypeWebApp), testing::Values(AppIdTestParam::kWithFlagNone, - AppIdTestParam::kWithFlagAppIdDialog, AppIdTestParam::kWithFlagPolicyAppIdentity, + AppIdTestParam::kWithFlagAppIdDialog, AppIdTestParam::kWithFlagPolicyAppIdentity | AppIdTestParam::kWithFlagAppIdDialog)), ManifestUpdateManagerBrowserTest_AppIdentityParameterized::ParamToString);
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc index a0c65c0..ecd2ee3 100644 --- a/chrome/browser/web_applications/manifest_update_task.cc +++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -10,6 +10,7 @@ #include <vector> #include "base/feature_list.h" +#include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_features.h" @@ -21,7 +22,6 @@ #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" -#include "chrome/browser/web_applications/web_app_icon_generator.h" #include "chrome/browser/web_applications/web_app_icon_manager.h" #include "chrome/browser/web_applications/web_app_install_finalizer.h" #include "chrome/browser/web_applications/web_app_install_utils.h" @@ -87,19 +87,25 @@ icon_diff->diff_results |= ONE_OR_MORE_ICONS_CHANGED; return; } else { - if (size == kInstallIconSize) { - icon_diff->diff_results |= INSTALL_ICON_CHANGED; + // Icons that are specified in new manifest are of special interest, the + // rest is auto-generated. + bool important_icon = + std::find(downloaded_sizes.begin(), downloaded_sizes.end(), size) != + downloaded_sizes.end(); + if (!important_icon) { + icon_diff->diff_results |= GENERATED_ICON_CHANGED; + } else if ((icon_diff->diff_results & SINGLE_ICON_CHANGED) == 0 && + (icon_diff->diff_results & MULTIPLE_ICONS_CHANGED) == 0) { + icon_diff->diff_results |= SINGLE_ICON_CHANGED; icon_diff->before = disk_bitmap; icon_diff->after = downloaded_bitmap; - } else if (size == kLauncherIconSize) { - icon_diff->diff_results |= LAUNCHER_ICON_CHANGED; - if (icon_diff->before.drawsNothing() && - icon_diff->after.drawsNothing()) { - icon_diff->before = disk_bitmap; - icon_diff->after = downloaded_bitmap; - } - } else { - icon_diff->diff_results |= UNIMPORTANT_ICON_CHANGED; + } else if (icon_diff->diff_results & SINGLE_ICON_CHANGED) { + icon_diff->diff_results &= ~SINGLE_ICON_CHANGED; + icon_diff->diff_results |= MULTIPLE_ICONS_CHANGED; + // The UI can only handle showing one image at a time, at the moment. + icon_diff->before = SkBitmap(); + icon_diff->after = SkBitmap(); + return; } } } @@ -455,13 +461,17 @@ DownloadedIconsHttpResults icons_http_results) { DCHECK_EQ(stage_, Stage::kPendingIconDownload); + // TODO(crbug.com/1238622): Report `result` and `icons_http_results` in + // internals. + UMA_HISTOGRAM_ENUMERATION("WebApp.Icon.DownloadedResultOnUpdate", result); + RecordDownloadedIconHttpStatusCodes( + "WebApp.Icon.DownloadedHttpStatusCodeOnUpdate", icons_http_results); + if (result != IconsDownloadedResult::kCompleted) { DestroySelf(ManifestUpdateResult::kIconDownloadFailed); return; } - // TODO(crbug.com/1238622): Report `result` and `DownloadedIconsHttpResults`in - // UMA and internals. RecordDownloadedIconsHttpResultsCodeClass( "WebApp.Icon.HttpStatusCodeClassOnUpdate", result, icons_http_results); @@ -484,8 +494,9 @@ stage_ = Stage::kPendingAppIdentityCheck; // These calls populate the |web_application_info_| with all icon bitmap - // data. If this data does not match what we already have on disk, then an - // update is necessary. + // data. + // If this data does not match what we already have on disk, then an update + // is necessary. PopulateOtherIcons(&web_application_info_.value(), downloaded_icons_map); PopulateProductIcons(&web_application_info_.value(), &downloaded_icons_map); @@ -523,8 +534,8 @@ return; } - if (!title_change && !icon_diff.requires_app_identity_check()) { - OnPostAppIdentityUpdateCheck(AppIdentityUpdate::kAllowed); + if (icon_change && !icon_diff.supported_for_app_identity_check()) { + OnPostAppIdentityUpdateCheck(AppIdentityUpdate::kSkipped); return; }
diff --git a/chrome/browser/web_applications/manifest_update_task.h b/chrome/browser/web_applications/manifest_update_task.h index 80b21e8..54e1f138 100644 --- a/chrome/browser/web_applications/manifest_update_task.h +++ b/chrome/browser/web_applications/manifest_update_task.h
@@ -73,22 +73,19 @@ // below). ONE_OR_MORE_ICONS_CHANGED = 1 << 2, - // The launcher icon is changing. Note: that the launcher icon size is - // platform-specific and that this flag is only set if the diff process is - // allowed to continue to the end (doesn't stop as soon as it finds a - // change). - LAUNCHER_ICON_CHANGED = 1 << 3, + // Only one icon is changing. This flag is only set if the diff process is + // allowed to continue to the end (doesn't stop as soon as it finds a change). + SINGLE_ICON_CHANGED = 1 << 3, - // The launcher icon is changing. Note: that the install icon size is - // platform-specific and that this flag is only set if the diff process is - // allowed to continue to the end (doesn't stop as soon as it finds a + // Two or more icons are changing. This flag is only set if the diff process + // is allowed to continue to the end (doesn't stop as soon as it finds a // change). - INSTALL_ICON_CHANGED = 1 << 4, + MULTIPLE_ICONS_CHANGED = 1 << 4, - // An icon, other than the launcher/install icon changed. Note: that this flag + // And icon has changed, but it was a generated icon that changed. This flag // is only set if the diff process is allowed to continue to the end (doesn't // stop as soon as it finds a change). - UNIMPORTANT_ICON_CHANGED = 1 << 5, + GENERATED_ICON_CHANGED = 1 << 5, }; // A structure to keep track of the differences found while comparing icons @@ -111,9 +108,9 @@ // Returns true iff the mismatch should result in app identity dlg being // shown. - bool requires_app_identity_check() { - return ((diff_results & LAUNCHER_ICON_CHANGED) != 0) || - ((diff_results & INSTALL_ICON_CHANGED) != 0); + bool supported_for_app_identity_check() { + return diff_results == SINGLE_ICON_CHANGED || + diff_results == (SINGLE_ICON_CHANGED | GENERATED_ICON_CHANGED); } // Keeps track of all the differences discovered in the icon set.
diff --git a/chrome/browser/web_applications/manifest_update_task_unittest.cc b/chrome/browser/web_applications/manifest_update_task_unittest.cc index 36a06603..b088ba01 100644 --- a/chrome/browser/web_applications/manifest_update_task_unittest.cc +++ b/chrome/browser/web_applications/manifest_update_task_unittest.cc
@@ -12,9 +12,6 @@ namespace web_app { -static const int kUnimportantIconSize1 = 4; -static const int kUnimportantIconSize2 = 8; - namespace { // Note: Keep in sync with GetDefaultManifestFileHandlers() below. @@ -152,203 +149,337 @@ return result; } -std::string DiffResultsToString(uint32_t diff) { - std::string result = ""; - if (diff & NO_CHANGE_DETECTED) - result += "NO_CHANGE_DETECTED, "; - if (diff & MISMATCHED_IMAGE_SIZES) - result += "MISMATCHED_IMAGE_SIZES, "; - if (diff & ONE_OR_MORE_ICONS_CHANGED) - result += "ONE_OR_MORE_ICONS_CHANGED, "; - if (diff & LAUNCHER_ICON_CHANGED) - result += "LAUNCHER_ICON_CHANGED, "; - if (diff & INSTALL_ICON_CHANGED) - result += "INSTALL_ICON_CHANGED, "; - if (diff & UNIMPORTANT_ICON_CHANGED) - result += "UNIMPORTANT_ICON_CHANGED, "; - return result; -} - TEST_F(ManifestUpdateTaskTest, TestImageComparison) { - // Tests below assume there is no overlap in these values, but if - // Install/Launcher icon sizes change, a new value for kUnimportantIconSize - // must be selected that does not clash with it. Also check if launcher and - // install icon are same size, because tests might need to be updated if they - // are (browser tests especially). - static_assert(kInstallIconSize != kLauncherIconSize, "Overlap"); - static_assert(kInstallIconSize != kUnimportantIconSize1, "Overlap"); - static_assert(kInstallIconSize != kUnimportantIconSize2, "Overlap"); - static_assert(kLauncherIconSize != kUnimportantIconSize1, "Overlap"); - static_assert(kLauncherIconSize != kUnimportantIconSize2, "Overlap"); - - // Doing a FAST means stop on first error but SLOW means continue to end and - // give a more detailed error. - enum PassType { SLOW = 0, FAST = 1 }; - // Which map type the icons should be associated with. - enum MapType { ANY = 0, MASKED = 1, MONO = 2 }; - // Common icon diff result combinations: - const IconDiffResult NO_CHANGE = NO_CHANGE_DETECTED; - const IconDiffResult SIZE_CHANGE = MISMATCHED_IMAGE_SIZES; - // Result: Both important sizes change. - const IconDiffResult BOTH_CHANGE = - static_cast<IconDiffResult>(INSTALL_ICON_CHANGED | LAUNCHER_ICON_CHANGED); - // Result: All types of sizes change (important and unimportant). - const IconDiffResult ALL_CHANGE = static_cast<IconDiffResult>( - INSTALL_ICON_CHANGED | LAUNCHER_ICON_CHANGED | UNIMPORTANT_ICON_CHANGED); - - struct icon { - int icon_size; - SkColor icon_color; - }; - - const std::vector<const icon> NoIcons; - const SkColor starting_icon_color = SK_ColorTRANSPARENT; - const SkColor ending_icon_color = SK_ColorRED; - const std::vector<const icon> Icon1 = { - {kUnimportantIconSize1, starting_icon_color}}; - const std::vector<const icon> Icon1Red = { - {kUnimportantIconSize1, ending_icon_color}}; - // Another icon size. - const std::vector<const icon> Icon2 = { - {kUnimportantIconSize2, starting_icon_color}}; - - // Launcher icon (starts yellow, ends up blue). - const SkColor starting_launcher_icon_color = SK_ColorYELLOW; - const SkColor ending_launcher_icon_color = SK_ColorBLUE; - const std::vector<const icon> Launcher = { - {kLauncherIconSize, starting_launcher_icon_color}}; - const std::vector<const icon> LauncherBlue = { - {kLauncherIconSize, ending_launcher_icon_color}}; - - // Install icon (starts off green, ends up cyan). - const SkColor starting_install_icon_color = SK_ColorGREEN; - const SkColor ending_install_icon_color = SK_ColorCYAN; - const std::vector<const icon> InstallIcon = { - {kInstallIconSize, starting_install_icon_color}}; - const std::vector<const icon> InstallIconCyan = { - {kInstallIconSize, ending_install_icon_color}}; - - // Launcher and install icon together. - const std::vector<const icon> BothBefore = { - {kLauncherIconSize, starting_launcher_icon_color}, - {kInstallIconSize, starting_install_icon_color}}; - const std::vector<const icon> BothAfter = { - {kLauncherIconSize, ending_launcher_icon_color}, - {kInstallIconSize, ending_install_icon_color}}; - - // All types (Launcher, install and unimportant icon). - const std::vector<const icon> AllBefore = { - {kUnimportantIconSize1, starting_icon_color}, - {kLauncherIconSize, starting_launcher_icon_color}, - {kInstallIconSize, starting_install_icon_color}}; - const std::vector<const icon> AllAfter = { - {kUnimportantIconSize1, ending_icon_color}, - {kLauncherIconSize, ending_launcher_icon_color}, - {kInstallIconSize, ending_install_icon_color}}; - - struct { - PassType pass_type; - MapType map_current; - std::vector<const icon> current; - MapType map_downloaded; - std::vector<const icon> downloaded; - IconDiffResult expected_diff_result; - } test_cases[] = { - // Test: zero icons -> zero icons: - {FAST, ANY, NoIcons, ANY, NoIcons, NO_CHANGE}, - {SLOW, ANY, NoIcons, ANY, NoIcons, NO_CHANGE}, - // Test: zero icons -> one icon (unimportant size) via 'any' map: - {FAST, ANY, NoIcons, ANY, Icon1, SIZE_CHANGE}, - {SLOW, ANY, NoIcons, ANY, Icon1, SIZE_CHANGE}, - // Test: single icon -> zero icons: - {FAST, ANY, Icon1, ANY, NoIcons, SIZE_CHANGE}, - {SLOW, ANY, Icon1, ANY, NoIcons, SIZE_CHANGE}, - // Test: single icon -> single icon (but size changes). - {FAST, ANY, Icon1, ANY, Icon2, SIZE_CHANGE}, - {SLOW, ANY, Icon1, ANY, Icon2, SIZE_CHANGE}, - // Same as above, except across maps ('any' and 'monochrome'). - {FAST, ANY, Icon1, MONO, Icon2, SIZE_CHANGE}, - {SLOW, ANY, Icon1, MONO, Icon2, SIZE_CHANGE}, - // Same as above, except across maps ('maskable' and 'monochrome'). - {FAST, MASKED, Icon1, MONO, Icon2, SIZE_CHANGE}, - {SLOW, MASKED, Icon1, MONO, Icon2, SIZE_CHANGE}, - // Test: single icon (unimportant size) changes color. - {FAST, ANY, Icon1, ANY, Icon1Red, ONE_OR_MORE_ICONS_CHANGED}, - {SLOW, ANY, Icon1, ANY, Icon1Red, UNIMPORTANT_ICON_CHANGED}, - // Test: launcher icon changes color. - {FAST, ANY, Launcher, ANY, LauncherBlue, ONE_OR_MORE_ICONS_CHANGED}, - {SLOW, ANY, Launcher, ANY, LauncherBlue, LAUNCHER_ICON_CHANGED}, - // Test: install icon changes color. - {FAST, ANY, InstallIcon, ANY, InstallIconCyan, ONE_OR_MORE_ICONS_CHANGED}, - {SLOW, ANY, InstallIcon, ANY, InstallIconCyan, INSTALL_ICON_CHANGED}, - // Test: both Launcher and Install icon changes color. - {FAST, ANY, BothBefore, ANY, BothAfter, ONE_OR_MORE_ICONS_CHANGED}, - {SLOW, ANY, BothBefore, ANY, BothAfter, BOTH_CHANGE}, - // Test: all types (Launcher, Install and unimportant icon) change color. - {FAST, ANY, AllBefore, ANY, AllAfter, ONE_OR_MORE_ICONS_CHANGED}, - {SLOW, ANY, AllBefore, ANY, AllAfter, ALL_CHANGE}, - }; - - int i = 1; - for (const auto& test_case : test_cases) { - SCOPED_TRACE("Test no: " + base::NumberToString(i++) + " expect: " + - DiffResultsToString(test_case.expected_diff_result)); + { + // Test case: Find first difference with two empty IconBitmaps as input + // should report no differences. IconBitmaps on_disk; - for (const auto& current_icon : test_case.current) { - std::map<SquareSizePx, SkBitmap>* map; - switch (test_case.map_current) { - case ANY: - map = &on_disk.any; - break; - case MASKED: - map = &on_disk.maskable; - break; - case MONO: - map = &on_disk.monochrome; - break; - } - AddGeneratedIcon(map, current_icon.icon_size, current_icon.icon_color); - } IconBitmaps downloaded; - for (const auto& current_icon : test_case.downloaded) { - std::map<SquareSizePx, SkBitmap>* map; - switch (test_case.map_downloaded) { - case ANY: - map = &downloaded.any; - break; - case MASKED: - map = &downloaded.maskable; - break; - case MONO: - map = &downloaded.monochrome; - break; - } - AddGeneratedIcon(map, current_icon.icon_size, current_icon.icon_color); - } + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ true); + EXPECT_EQ(NO_CHANGE_DETECTED, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences with two empty IconBitmaps as input + // should report no differences. + IconBitmaps on_disk; + IconBitmaps downloaded; IconDiff diff = HaveIconBitmapsChanged( on_disk, downloaded, GenerateIconInfosFrom(on_disk), - GenerateIconInfosFrom(downloaded), test_case.pass_type == FAST); - EXPECT_STREQ(DiffResultsToString(test_case.expected_diff_result).c_str(), - DiffResultsToString(diff.diff_results).c_str()); + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ false); + EXPECT_EQ(NO_CHANGE_DETECTED, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } - if ((test_case.expected_diff_result & INSTALL_ICON_CHANGED) != 0) { - EXPECT_TRUE(diff.requires_app_identity_check()); - ASSERT_FALSE(diff.before.drawsNothing()); - ASSERT_FALSE(diff.after.drawsNothing()); - EXPECT_EQ(starting_install_icon_color, diff.before.getColor(0, 0)); - EXPECT_EQ(ending_install_icon_color, diff.after.getColor(0, 0)); - } else if ((test_case.expected_diff_result & LAUNCHER_ICON_CHANGED) != 0) { - EXPECT_TRUE(diff.requires_app_identity_check()); - ASSERT_FALSE(diff.before.drawsNothing()); - ASSERT_FALSE(diff.after.drawsNothing()); - EXPECT_EQ(starting_launcher_icon_color, diff.before.getColor(0, 0)); - EXPECT_EQ(ending_launcher_icon_color, diff.after.getColor(0, 0)); - } else { - EXPECT_FALSE(diff.requires_app_identity_check()); - EXPECT_TRUE(diff.before.drawsNothing()); - EXPECT_TRUE(diff.after.drawsNothing()); - } + { + // Test case: Find first difference when one new image has been downloaded + // should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ true); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences when one new image has been downloaded + // should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ false); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference when one image has been removed + // should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ true); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences when one new image has been removed + // should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ false); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when one image has been removed and one + // added, should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + true); + // First mismatch found will be the added image, then it will stop. + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when one image has been removed and one + // added, should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= + */ + false); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when one image has been removed and one + // added (but across maps), should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.maskable, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.monochrome, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= + */ + true); + // First mismatch found will be the fact that one of the maps has changed + // size. + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when one image has been removed and one + // added (but across maps), should report size mismatch. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.maskable, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.monochrome, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + false); + EXPECT_EQ(MISMATCHED_IMAGE_SIZES, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when one image has had its bits + // updated, should return ONE_OR_MORE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + true); + EXPECT_EQ(ONE_OR_MORE_ICONS_CHANGED, diff.diff_results); + // The expectation here might, at a glance, seem unusual because there *has* + // been a change in only a single icon. However, this was detected via the + // short pass, which does not provide |before| and |after| images (only the + // longer pass will know whether more images changed). + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when one image has had its bits + // updated, should return SINGLE_ICON_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged( + on_disk, downloaded, GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ false); + EXPECT_EQ(SINGLE_ICON_CHANGED, diff.diff_results); + // The function has checked all possibilities and is able to provide before + // and after images, because it knows only a single image changed. + EXPECT_FALSE(diff.before.drawsNothing()); + EXPECT_FALSE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when two images have had their bits + // updated, should return ONE_OR_MORE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.any, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + true); + EXPECT_EQ(ONE_OR_MORE_ICONS_CHANGED, diff.diff_results); + // Since more than two images changed, the |before| and |after| isn't + // provided. + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when two images have had their bits + // updated, should return MULTIPLE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.any, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.any, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + false); + EXPECT_EQ(MULTIPLE_ICONS_CHANGED, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when two images have had their bits + // updated (across |any| and |maskable|), should return + // ONE_OR_MORE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.maskable, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.maskable, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + true); + EXPECT_EQ(ONE_OR_MORE_ICONS_CHANGED, diff.diff_results); + // Since more than two images changed, the |before| and |after| isn't + // provided. + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when two images have had their bits + // updated (across |any| and |maskable|), should return + // MULTIPLE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.any, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.maskable, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.any, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.maskable, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + false); + EXPECT_EQ(MULTIPLE_ICONS_CHANGED, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + + { + // Test case: Find first difference, when two images have had their bits + // updated (across |maskable| and |monochrome|), should return + // ONE_OR_MORE_ICON_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.maskable, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.monochrome, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.maskable, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.monochrome, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + true); + EXPECT_EQ(ONE_OR_MORE_ICONS_CHANGED, diff.diff_results); + // Since more than two images changed, the |before| and |after| isn't + // provided. + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); + } + { + // Test case: Find all differences, when two images have had their bits + // updated (across |maskable| and |monochrome|), should return + // MULTIPLE_ICONS_CHANGED. + IconBitmaps on_disk; + IconBitmaps downloaded; + AddGeneratedIcon(&on_disk.maskable, icon_size::k256, SK_ColorRED); + AddGeneratedIcon(&on_disk.monochrome, icon_size::k512, SK_ColorRED); + AddGeneratedIcon(&downloaded.maskable, icon_size::k256, SK_ColorYELLOW); + AddGeneratedIcon(&downloaded.monochrome, icon_size::k512, SK_ColorYELLOW); + + IconDiff diff = HaveIconBitmapsChanged(on_disk, downloaded, + GenerateIconInfosFrom(on_disk), + GenerateIconInfosFrom(downloaded), + /* end_when_mismatch_detected= */ + false); + EXPECT_EQ(MULTIPLE_ICONS_CHANGED, diff.diff_results); + EXPECT_TRUE(diff.before.drawsNothing()); + EXPECT_TRUE(diff.after.drawsNothing()); } }
diff --git a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc index b43fd5a3..a76515be 100644 --- a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc
@@ -58,6 +58,13 @@ icons_map->emplace(icon_url, std::move(bitmaps)); } +void AddEmptyIconToIconsMap(const GURL& icon_url, IconsMap* icons_map) { + std::vector<SkBitmap> bitmaps; + bitmaps.emplace_back(SkBitmap{}); + + icons_map->emplace(icon_url, std::move(bitmaps)); +} + bool AreColorsEqual(SkColor expected_color, SkColor actual_color, int threshold) {
diff --git a/chrome/browser/web_applications/test/web_app_icon_test_utils.h b/chrome/browser/web_applications/test/web_app_icon_test_utils.h index b7bca044e..ec62732 100644 --- a/chrome/browser/web_applications/test/web_app_icon_test_utils.h +++ b/chrome/browser/web_applications/test/web_app_icon_test_utils.h
@@ -40,6 +40,8 @@ SkColor solid_color, IconsMap* icons_map); +void AddEmptyIconToIconsMap(const GURL& icon_url, IconsMap* icons_map); + bool AreColorsEqual(SkColor expected_color, SkColor actual_color, int threshold);
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h index b10145a..c7a844f4 100644 --- a/chrome/browser/web_applications/web_app_constants.h +++ b/chrome/browser/web_applications/web_app_constants.h
@@ -303,6 +303,9 @@ using LaunchHandler = blink::Manifest::LaunchHandler; // A result how `WebAppIconDownloader` processed the list of icon urls. +// +// Entries should not be renumbered and numeric values should never be reused. +// Update corresponding enums.xml entry when making changes here. enum class IconsDownloadedResult { // All the requested icon urls have been processed and `icons_map` populated // for successful http responses. `icons_http_results` contains success and @@ -317,6 +320,7 @@ // `WebAppIconDownloader::FailAllIfAnyFail()` flag was specified. // `icons_http_results` contains the failed url and http status code. kAbortedDueToFailure, + kMaxValue = kAbortedDueToFailure, }; const char* IconsDownloadedResultToString(IconsDownloadedResult result);
diff --git a/chrome/browser/web_applications/web_app_helpers.cc b/chrome/browser/web_applications/web_app_helpers.cc index 20f39e5..4da29c0 100644 --- a/chrome/browser/web_applications/web_app_helpers.cc +++ b/chrome/browser/web_applications/web_app_helpers.cc
@@ -18,8 +18,6 @@ namespace web_app { -namespace { - // The following string is used to build the directory name for // shortcuts to chrome applications (the kind which are installed // from a CRX). Application shortcuts to URLs use the {host}_{path} @@ -28,8 +26,6 @@ // are no naming conflicts. const char kCrxAppPrefix[] = "_crx_"; -} // namespace - std::string GenerateApplicationNameFromURL(const GURL& url) { return base::StrCat({url.host_piece(), "_", url.path_piece()}); }
diff --git a/chrome/browser/web_applications/web_app_helpers.h b/chrome/browser/web_applications/web_app_helpers.h index 5b17bfc..3278e6f9 100644 --- a/chrome/browser/web_applications/web_app_helpers.h +++ b/chrome/browser/web_applications/web_app_helpers.h
@@ -16,6 +16,8 @@ namespace web_app { +extern const char kCrxAppPrefix[]; + // Compute a deterministic name based on the URL. We use this pseudo name // as a key to store window location per application URLs in Browser and // as app id for BrowserWindow, shortcut and jump list.
diff --git a/chrome/browser/web_applications/web_app_icon_generator.h b/chrome/browser/web_applications/web_app_icon_generator.h index 452f252..7df887c 100644 --- a/chrome/browser/web_applications/web_app_icon_generator.h +++ b/chrome/browser/web_applications/web_app_icon_generator.h
@@ -10,7 +10,6 @@ #include <string> #include <vector> -#include "build/build_config.h" #include "chrome/browser/web_applications/web_application_info.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" @@ -38,17 +37,6 @@ } // namespace icon_size -#if defined(OS_MAC) -constexpr int kInstallIconSize = icon_size::k96; -constexpr int kLauncherIconSize = icon_size::k256; -#elif defined(OS_CHROMEOS) -constexpr int kInstallIconSize = icon_size::k96; -constexpr int kLauncherIconSize = icon_size::k128; -#else -constexpr int kInstallIconSize = icon_size::k48; -constexpr int kLauncherIconSize = icon_size::k128; -#endif - using SizeToBitmap = std::map<SquareSizePx, SkBitmap>; // Returns icon sizes to be generated from downloaded icons.
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc index 61b86af..28cdbf6 100644 --- a/chrome/browser/web_applications/web_app_install_task.cc +++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/feature_list.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/profiles/profile.h" @@ -765,10 +766,7 @@ PopulateProductIcons(web_app_info.get(), &icons_map); PopulateOtherIcons(web_app_info.get(), icons_map); - // TODO(crbug.com/1238622): Report `IconsDownloadedResult`and - // `DownloadedIconsHttpResults` in UMAs. - RecordDownloadedIconsHttpResultsCodeClassForSyncOrCreate(result, - icons_http_results); + RecordDownloadedIconsResultAndHttpStatusCodes(result, icons_http_results); LogDownloadedIconsErrors(*web_app_info, result, icons_map, icons_http_results); @@ -791,10 +789,7 @@ PopulateProductIcons(web_app_info.get(), &icons_map); PopulateOtherIcons(web_app_info.get(), icons_map); - // TODO(crbug.com/1238622): Report `IconsDownloadedResult`and - // `DownloadedIconsHttpResults` in UMAs. - RecordDownloadedIconsHttpResultsCodeClassForSyncOrCreate(result, - icons_http_results); + RecordDownloadedIconsResultAndHttpStatusCodes(result, icons_http_results); LogDownloadedIconsErrors(*web_app_info, result, icons_map, icons_http_results); @@ -972,15 +967,24 @@ CallInstallCallback(app_id, InstallResultCode::kSuccessNewInstall); } -void WebAppInstallTask:: - RecordDownloadedIconsHttpResultsCodeClassForSyncOrCreate( - IconsDownloadedResult result, - const DownloadedIconsHttpResults& icons_http_results) { - RecordDownloadedIconsHttpResultsCodeClass( - (install_source_ == webapps::WebappInstallSource::SYNC - ? "WebApp.Icon.HttpStatusCodeClassOnSync" - : "WebApp.Icon.HttpStatusCodeClassOnCreate"), - result, icons_http_results); +void WebAppInstallTask::RecordDownloadedIconsResultAndHttpStatusCodes( + IconsDownloadedResult result, + const DownloadedIconsHttpResults& icons_http_results) { + if (install_source_ == webapps::WebappInstallSource::SYNC) { + RecordDownloadedIconsHttpResultsCodeClass( + "WebApp.Icon.HttpStatusCodeClassOnSync", result, icons_http_results); + + UMA_HISTOGRAM_ENUMERATION("WebApp.Icon.DownloadedResultOnSync", result); + RecordDownloadedIconHttpStatusCodes( + "WebApp.Icon.DownloadedHttpStatusCodeOnSync", icons_http_results); + } else { + RecordDownloadedIconsHttpResultsCodeClass( + "WebApp.Icon.HttpStatusCodeClassOnCreate", result, icons_http_results); + + UMA_HISTOGRAM_ENUMERATION("WebApp.Icon.DownloadedResultOnCreate", result); + RecordDownloadedIconHttpStatusCodes( + "WebApp.Icon.DownloadedHttpStatusCodeOnCreate", icons_http_results); + } } void WebAppInstallTask::LogHeaderIfLogEmpty(const std::string& url) {
diff --git a/chrome/browser/web_applications/web_app_install_task.h b/chrome/browser/web_applications/web_app_install_task.h index 9cf78194..6b58969 100644 --- a/chrome/browser/web_applications/web_app_install_task.h +++ b/chrome/browser/web_applications/web_app_install_task.h
@@ -259,7 +259,7 @@ const AppId& app_id, const OsHooksErrors os_hook_errors); - void RecordDownloadedIconsHttpResultsCodeClassForSyncOrCreate( + void RecordDownloadedIconsResultAndHttpStatusCodes( IconsDownloadedResult result, const DownloadedIconsHttpResults& icons_http_results);
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 31cb2a2..8ab09bc6 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -229,20 +229,22 @@ return *fake_install_finalizer_; } - // Sets IconsMap, IconsDownloadedResult and corresponding HTTP_OK - // DownloadedIconsHttpResults. - void SetIconsMapToRetrieve(IconsMap icons_map) { + // Sets IconsMap, IconsDownloadedResult and corresponding `http_status_codes` + // to populate DownloadedIconsHttpResults. + void SetIconsMapToRetrieve(IconsMap icons_map, + IconsDownloadedResult result, + const std::vector<int>& http_status_codes) { + DCHECK_EQ(icons_map.size(), http_status_codes.size()); DCHECK(data_retriever_); - data_retriever_->SetIconsDownloadedResult( - icons_map.empty() ? IconsDownloadedResult::kPrimaryPageChanged - : IconsDownloadedResult::kCompleted); + data_retriever_->SetIconsDownloadedResult(result); - // Uses `icons_map` to infer HTTP_OK for each icon. + int icon_index = 0; DownloadedIconsHttpResults http_results; - for (const auto& url_and_bitmap : icons_map) - http_results[url_and_bitmap.first] = net::HttpStatusCode::HTTP_OK; - + for (const auto& url_and_bitmap : icons_map) { + http_results[url_and_bitmap.first] = http_status_codes[icon_index]; + ++icon_index; + } data_retriever_->SetDownloadedIconsHttpResults(std::move(http_results)); // Moves `icons_map` last. @@ -330,8 +332,11 @@ SetInstallFinalizerForTesting(); - IconsMap icons_map; - SetIconsMapToRetrieve(std::move(icons_map)); + data_retriever_->SetIconsDownloadedResult( + IconsDownloadedResult::kPrimaryPageChanged); + data_retriever_->SetDownloadedIconsHttpResults( + DownloadedIconsHttpResults{}); + data_retriever_->SetIcons(IconsMap{}); } protected: @@ -666,7 +671,8 @@ IconsMap icons_map; AddIconToIconsMap(icon_url, icon_size::k128, color, &icons_map); - SetIconsMapToRetrieve(std::move(icons_map)); + SetIconsMapToRetrieve(std::move(icons_map), IconsDownloadedResult::kCompleted, + {net::HttpStatusCode::HTTP_OK}); InstallWebAppFromManifestWithFallback(); @@ -687,9 +693,16 @@ "WebApp.Icon.HttpStatusCodeClassOnCreate", http_code_class_ok, 1); histogram_tester().ExpectTotalCount("WebApp.Icon.HttpStatusCodeClassOnSync", 0); + + histogram_tester().ExpectBucketCount("WebApp.Icon.DownloadedResultOnCreate", + IconsDownloadedResult::kCompleted, 1); + + histogram_tester().ExpectBucketCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnCreate", + net::HttpStatusCode::HTTP_OK, 1); } -TEST_F(WebAppInstallTaskTest, GetIcons_NoIconsProvided) { +TEST_F(WebAppInstallTaskTest, GetIcons_PrimaryPageChanged) { const GURL url = GURL("https://example.com/path"); CreateDefaultDataToRetrieve(url); CreateRendererAppInfo(url, "Name", "Description"); @@ -697,7 +710,9 @@ SetInstallFinalizerForTesting(); IconsMap icons_map; - SetIconsMapToRetrieve(std::move(icons_map)); + SetIconsMapToRetrieve(std::move(icons_map), + IconsDownloadedResult::kPrimaryPageChanged, + /*http_status_codes=*/{}); InstallWebAppFromManifestWithFallback(); @@ -717,6 +732,47 @@ 0); histogram_tester().ExpectTotalCount("WebApp.Icon.HttpStatusCodeClassOnSync", 0); + + histogram_tester().ExpectBucketCount( + "WebApp.Icon.DownloadedResultOnCreate", + IconsDownloadedResult::kPrimaryPageChanged, 1); + histogram_tester().ExpectTotalCount("WebApp.Icon.DownloadedResultOnSync", 0); + + histogram_tester().ExpectTotalCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnCreate", 0); + histogram_tester().ExpectTotalCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnSync", 0); +} + +TEST_F(WebAppInstallTaskTest, GetIcons_IconNotFound) { + const GURL url = GURL("https://example.com/path"); + CreateDefaultDataToRetrieve(url); + CreateRendererAppInfo(url, "Name", "Description"); + + SetInstallFinalizerForTesting(); + + IconsMap icons_map; + AddEmptyIconToIconsMap(GURL("https://example.com/app.ico"), &icons_map); + SetIconsMapToRetrieve(std::move(icons_map), IconsDownloadedResult::kCompleted, + {net::HttpStatusCode::HTTP_NOT_FOUND}); + + InstallWebAppFromManifestWithFallback(); + + std::unique_ptr<WebApplicationInfo> web_app_info = + fake_install_finalizer().web_app_info(); + EXPECT_TRUE(ContainsOneIconOfEachSize(web_app_info->icon_bitmaps.any)); + EXPECT_TRUE(web_app_info->manifest_icons.empty()); + EXPECT_TRUE(web_app_info->shortcuts_menu_item_infos.empty()); + + histogram_tester().ExpectBucketCount("WebApp.Icon.DownloadedResultOnCreate", + IconsDownloadedResult::kCompleted, 1); + histogram_tester().ExpectTotalCount("WebApp.Icon.DownloadedResultOnSync", 0); + + histogram_tester().ExpectBucketCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnCreate", + net::HttpStatusCode::HTTP_NOT_FOUND, 1); + histogram_tester().ExpectTotalCount( + "WebApp.Icon.DownloadedHttpStatusCodeOnSync", 0); } TEST_F(WebAppInstallTaskTest, WriteDataToDisk) { @@ -842,7 +898,8 @@ IconsMap icons_map; AddIconToIconsMap(GURL("https://example.com/app.ico"), icon_size::k512, SK_ColorBLUE, &icons_map); - SetIconsMapToRetrieve(std::move(icons_map)); + SetIconsMapToRetrieve(std::move(icons_map), IconsDownloadedResult::kCompleted, + {net::HttpStatusCode::HTTP_OK}); const base::FilePath web_apps_dir = GetWebAppsRootDirectory(profile()); const base::FilePath manifest_resources_directory =
diff --git a/chrome/browser/web_applications/web_app_install_utils.cc b/chrome/browser/web_applications/web_app_install_utils.cc index dcea922..5efd96b 100644 --- a/chrome/browser/web_applications/web_app_install_utils.cc +++ b/chrome/browser/web_applications/web_app_install_utils.cc
@@ -14,6 +14,8 @@ #include "base/check.h" #include "base/check_op.h" #include "base/containers/contains.h" +#include "base/containers/flat_set.h" +#include "base/metrics/histogram.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/strings/string_piece.h" @@ -34,6 +36,7 @@ #include "components/webapps/browser/banners/app_banner_settings_helper.h" #include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/browser/installable/installable_metrics.h" +#include "net/http/http_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h" @@ -621,6 +624,32 @@ } } +void RecordDownloadedIconHttpStatusCodes( + base::StringPiece histogram_name, + const DownloadedIconsHttpResults& icons_http_results) { + if (icons_http_results.empty()) + return; + + // Do not use UMA_HISTOGRAM_... macros here, as it caches the Histogram + // instance and thus only works if |histogram_name| is constant. + base::HistogramBase* counter = base::CustomHistogram::FactoryGet( + histogram_name.data(), net::HttpUtil::GetStatusCodesForHistogram(), + base::HistogramBase::kUmaTargetedHistogramFlag); + + // A web app may contain arbitrary number of icons. The histogram assumes that + // most of them fail with same http status codes and counts each http status + // code only once. + std::vector<int> http_status_codes; + http_status_codes.reserve(icons_http_results.size()); + for (const auto& url_and_http_status_code : icons_http_results) + http_status_codes.push_back(url_and_http_status_code.second); + + base::flat_set<int> unique_http_status_codes{std::move(http_status_codes)}; + + for (int http_status_code : unique_http_status_codes) + counter->Add(net::HttpUtil::MapStatusCodeForHistogram(http_status_code)); +} + webapps::WebappInstallSource ConvertExternalInstallSourceToInstallSource( ExternalInstallSource external_install_source) { webapps::WebappInstallSource install_source;
diff --git a/chrome/browser/web_applications/web_app_install_utils.h b/chrome/browser/web_applications/web_app_install_utils.h index e03a311..b415ec4 100644 --- a/chrome/browser/web_applications/web_app_install_utils.h +++ b/chrome/browser/web_applications/web_app_install_utils.h
@@ -84,6 +84,11 @@ IconsDownloadedResult result, const DownloadedIconsHttpResults& icons_http_results); +// Records http status code for each processed icon url. +void RecordDownloadedIconHttpStatusCodes( + base::StringPiece histogram_name, + const DownloadedIconsHttpResults& icons_http_results); + webapps::WebappInstallSource ConvertExternalInstallSourceToInstallSource( ExternalInstallSource external_install_source);
diff --git a/chrome/browser/web_applications/web_app_internals_browsertest.cc b/chrome/browser/web_applications/web_app_internals_browsertest.cc index f7719b3..f22a39a 100644 --- a/chrome/browser/web_applications/web_app_internals_browsertest.cc +++ b/chrome/browser/web_applications/web_app_internals_browsertest.cc
@@ -68,11 +68,11 @@ ~WebAppInternalsBrowserTest() override = default; void SetUp() override { - embedded_test_server_.AddDefaultHandlers(GetChromeTestDataDir()); - embedded_test_server_.RegisterRequestHandler( + embedded_test_server()->AddDefaultHandlers(GetChromeTestDataDir()); + embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&WebAppInternalsBrowserTest::RequestHandlerOverride, base::Unretained(this))); - ASSERT_TRUE(embedded_test_server_.Start()); + ASSERT_TRUE(embedded_test_server()->Start()); InProcessBrowserTest::SetUp(); } @@ -128,12 +128,7 @@ }); } - net::EmbeddedTestServer& embedded_test_server() { - return embedded_test_server_; - } - private: - net::EmbeddedTestServer embedded_test_server_; net::EmbeddedTestServer::HandleRequestCallback request_override_; OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; @@ -144,10 +139,10 @@ IN_PROC_BROWSER_TEST_F(WebAppInternalsBrowserTest, PRE_InstallManagerErrorsPersist) { - OverrideHttpRequest(embedded_test_server().GetURL("/banners/bad_icon.png"), + OverrideHttpRequest(embedded_test_server()->GetURL("/banners/bad_icon.png"), net::HTTP_NOT_FOUND); - AppId app_id = InstallWebApp(embedded_test_server().GetURL( + AppId app_id = InstallWebApp(embedded_test_server()->GetURL( "/banners/manifest_test_page.html?manifest=manifest_bad_icon.json")); const WebApp* web_app = GetProvider().registrar().GetAppById(app_id); @@ -155,7 +150,7 @@ EXPECT_TRUE(web_app->is_generated_icon()); const std::string expected_error = base::ReplaceStringPlaceholders( - kBadIconErrorTemplate, {embedded_test_server().base_url().spec()}, + kBadIconErrorTemplate, {embedded_test_server()->base_url().spec()}, nullptr); ASSERT_TRUE(GetProvider().install_manager().error_log());
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 94561e8..b5fc734 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1641383754-1872da093008b26a220a2c3af6a07c0ef34391ca.profdata +chrome-linux-main-1641513596-bc9c0cbf42a80edbd2f41b044d6f482611f9bc1a.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 416aef4..6fe8a063 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1641361707-bd23138002c20068f2d0aee2bf236c589c40b364.profdata +chrome-mac-main-1641513596-33a199135c98f1bd8d43505973ebe82876c465c8.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index b592d9e2..29ef47c 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1641371975-7c08d8df5e32933a8ffd2dffeee3fe9ad8b5daad.profdata +chrome-win32-main-1641524185-6a2df378799924d950af4e30382d7ddcd4873e87.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 606173a5..f5952aa 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1641340775-d2e3b869b30691210c88f6e0b016fd64e5700e9a.profdata +chrome-win64-main-1641524185-f75f782c5c3ffb7b439e42a1487d9930fff2d66f.profdata
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl index f604db6..c58183c 100644 --- a/chrome/common/extensions/api/autotest_private.idl +++ b/chrome/common/extensions/api/autotest_private.idl
@@ -595,6 +595,8 @@ boolean markTimeOfFirstAdd; }; + callback CouldAllowCrostiniCallback = void (boolean canBeAllowed); + interface Functions { // Must be called to allow autotestPrivateAPI events to be fired. static void initializeEvents(); @@ -797,6 +799,12 @@ [supportsPromises] static void importCrostini(DOMString path, VoidCallback callback); + // Returns whether crostini could ever be allowed. + // |callback|: Called with a boolean indicating if crostini can ever be + // allowed in the current profile. + [supportsPromises] static void couldAllowCrostini( + CouldAllowCrostiniCallback callback); + // Sets mock Plugin VM policy. // |imageUrl|: URL to the image to install. // |imageHash|: Hash for the provided image.
diff --git a/chrome/common/extensions/api/common_extension_api_unittest.cc b/chrome/common/extensions/api/common_extension_api_unittest.cc index df52acc..8606bebf 100644 --- a/chrome/common/extensions/api/common_extension_api_unittest.cc +++ b/chrome/common/extensions/api/common_extension_api_unittest.cc
@@ -25,6 +25,7 @@ #include "base/values.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_features_unittest.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/features/feature_session_type.h" @@ -976,9 +977,7 @@ ExtensionAPI::CreateWithDefaultConfiguration()); scoped_refptr<const Extension> extension = - ExtensionBuilder("Test") - .SetAction(ExtensionBuilder::ActionType::BROWSER_ACTION) - .Build(); + ExtensionBuilder("Test").SetAction(ActionInfo::TYPE_BROWSER).Build(); EXPECT_TRUE(extension_api ->IsAvailable("browserAction", extension.get(),
diff --git a/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc b/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc index 698ce74..6583d93 100644 --- a/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc +++ b/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc
@@ -83,9 +83,9 @@ } // static +// TODO(crbug.com/1065748): Clean up this function and related paths. bool UrlHandlers::CanBookmarkAppHandleUrl(const Extension* app, const GURL& url) { - DCHECK(app->from_bookmark()); return !!GetMatchingUrlHandler(app, url); } @@ -137,13 +137,6 @@ // TODO(sergeygs): Also add a verification to the CWS installer that the // URL patterns claimed here belong to the app's author verified sites. URLPattern pattern(URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS); - // System Web Apps are bookmark apps that point to chrome:// URLs. - // TODO(calamity): Remove once Bookmark Apps are no longer on Extensions. - if (extension->location() == mojom::ManifestLocation::kExternalComponent && - extension->from_bookmark()) { - pattern = URLPattern(URLPattern::SCHEME_CHROMEUI); - } - if (pattern.Parse(str_pattern) != URLPattern::ParseResult::kSuccess) { *error = ErrorUtils::FormatErrorMessageUTF16( merrors::kInvalidURLHandlerPatternElement, handler_id);
diff --git a/chrome/common/extensions/manifest_handlers/app_launch_info.cc b/chrome/common/extensions/manifest_handlers/app_launch_info.cc index cdb5ae2..699b5f9 100644 --- a/chrome/common/extensions/manifest_handlers/app_launch_info.cc +++ b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
@@ -51,24 +51,6 @@ return true; } -bool HasValidComponentBookmarkAppURL(const GURL& url) { - // For component Bookmark Apps we additionally accept chrome:// and - // chrome-untrusted://. - // - // Making chrome-untrusted:// work with URLPattern has many side-effects e.g. - // it makes chrome-untrusted:// URLs scriptable. Given that - // chrome-untrusted:// support is only needed temporarily until Bookmark Apps - // are deprecated, we simply check the parsed URL scheme, rather than adding - // chrome-untrusted:// to URLPattern and dealing with all the side-effects. - if (url.SchemeIs(content::kChromeUIScheme)) - return true; - if (url.SchemeIs(content::kChromeUIUntrustedScheme)) - return true; - - URLPattern pattern(Extension::kValidBookmarkAppSchemes); - return pattern.IsValidScheme(url.scheme()); -} - static base::LazyInstance<AppLaunchInfo>::DestructorAtExit g_empty_app_launch_info = LAZY_INSTANCE_INITIALIZER; @@ -185,27 +167,10 @@ return false; } - if (!extension->from_bookmark()) { - URLPattern pattern(Extension::kValidWebExtentSchemes); - // For non-Bookmark Apps, we only accept kValidWebExtentSchemes. - if (!pattern.IsValidScheme(url.scheme())) { - set_launch_web_url_error(); - return false; - } - } else if (extension->location() != - mojom::ManifestLocation::kExternalComponent) { - // For non-component Bookmark Apps we only accept - // kValidBookmarkAppSchemes. - URLPattern pattern(Extension::kValidBookmarkAppSchemes); - if (!pattern.IsValidScheme(url.scheme())) { - set_launch_web_url_error(); - return false; - } - } else { - if (!HasValidComponentBookmarkAppURL(url)) { - set_launch_web_url_error(); - return false; - } + URLPattern pattern(Extension::kValidWebExtentSchemes); + if (!pattern.IsValidScheme(url.scheme())) { + set_launch_web_url_error(); + return false; } launch_web_url_ = url; @@ -221,10 +186,7 @@ } // If there is no extent, we default the extent based on the launch URL. - // Skip this step if the extension is from a bookmark app, as they are - // permissionless. - if (extension->web_extent().is_empty() && !launch_web_url_.is_empty() && - !extension->from_bookmark()) { + if (extension->web_extent().is_empty() && !launch_web_url_.is_empty()) { URLPattern pattern(Extension::kValidWebExtentSchemes); if (!pattern.SetScheme("*")) { *error = ErrorUtils::FormatErrorMessageUTF16(
diff --git a/chrome/common/extensions/sync_helper.cc b/chrome/common/extensions/sync_helper.cc index b236567..c9889fc 100644 --- a/chrome/common/extensions/sync_helper.cc +++ b/chrome/common/extensions/sync_helper.cc
@@ -43,10 +43,6 @@ return false; } - // Boomkark extensions are deprecated. See crbug.com/1065748 - if (extension->from_bookmark()) - return false; - switch (extension->GetType()) { case Manifest::TYPE_EXTENSION: case Manifest::TYPE_HOSTED_APP:
diff --git a/chrome/installer/setup/DEPS b/chrome/installer/setup/DEPS index e5f723b9..d2053154 100644 --- a/chrome/installer/setup/DEPS +++ b/chrome/installer/setup/DEPS
@@ -12,6 +12,7 @@ specific_include_rules = { ".*_unittest\.cc": [ + "+chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h", "+chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h", "+chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h", "+chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h",
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 101d034..cbc7018f 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc
@@ -922,33 +922,27 @@ // patch to current exe, and store the resulting binary in the path // specified by --new-setup-exe. But we need to first unpack the file // given in --update-setup-exe. - base::ScopedTempDir temp_path; - if (!temp_path.CreateUniqueTempDir()) { - PLOG(ERROR) << "Could not create temporary path."; - } else { - base::FilePath compressed_archive( - cmd_line.GetSwitchValuePath(installer::switches::kUpdateSetupExe)); - VLOG(1) << "Opening archive " << compressed_archive.value(); - // The top unpack failure result with 28 days aggregation (>=0.01%) - // Setup.Install.LzmaUnPackResult_SetupExePatch - // 0.02% PATH_NOT_FOUND - // - // More information can also be found with metric: - // Setup.Install.LzmaUnPackNTSTATUS_SetupExePatch - if (installer::ArchivePatchHelper::UncompressAndPatch( - temp_path.GetPath(), compressed_archive, setup_exe, - cmd_line.GetSwitchValuePath(installer::switches::kNewSetupExe), - installer::UnPackConsumer::SETUP_EXE_PATCH)) { - status = installer::NEW_VERSION_UPDATED; - } - if (!temp_path.Delete()) { - // PLOG would be nice, but Delete() doesn't leave a meaningful value in - // the Windows last-error code. - LOG(WARNING) << "Scheduling temporary path " - << temp_path.GetPath().value() - << " for deletion at reboot."; - ScheduleDirectoryForDeletion(temp_path.GetPath()); - } + + const base::FilePath compressed_archive( + cmd_line.GetSwitchValuePath(installer::switches::kUpdateSetupExe)); + VLOG(1) << "Opening archive " << compressed_archive.value(); + // The top unpack failure result with 28 days aggregation (>=0.01%) + // Setup.Install.LzmaUnPackResult_SetupExePatch + // 0.02% PATH_NOT_FOUND + // + // More information can also be found with metric: + // Setup.Install.LzmaUnPackNTSTATUS_SetupExePatch + + // We use the `new_setup_exe` directory as the working directory for + // `ArchivePatchHelper::UncompressAndPatch`. For System installs, this + // directory would be under %ProgramFiles% (a directory that only admins can + // write to by default) and hence a secure location. + const base::FilePath new_setup_exe( + cmd_line.GetSwitchValuePath(installer::switches::kNewSetupExe)); + if (installer::ArchivePatchHelper::UncompressAndPatch( + new_setup_exe.DirName(), compressed_archive, setup_exe, + new_setup_exe, installer::UnPackConsumer::SETUP_EXE_PATCH)) { + status = installer::NEW_VERSION_UPDATED; } *exit_code = InstallUtil::GetInstallReturnCode(status);
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc index 74dd6d6..0bed46a2 100644 --- a/chrome/installer/setup/setup_util_unittest.cc +++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -32,6 +32,7 @@ #include "base/win/scoped_handle.h" #include "build/branding_buildflags.h" #include "build/build_config.h" +#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h" @@ -635,20 +636,13 @@ GURL dmserver_url("dmserver.com"); std::string nonce = "nonce"; - // Create a fake success response. - enterprise_management::DeviceManagementResponse response; - response.mutable_browser_public_key_upload_response()->set_response_code( - enterprise_management::BrowserPublicKeyUploadResponse::SUCCESS); - std::string response_str; - response.SerializeToString(&response_str); - // Trigger the key rotation with a real persistence delegate (empty) but with // a mocked network delegate. auto mock_network_delegate = std::make_unique<enterprise_connectors::test::MockKeyNetworkDelegate>(); EXPECT_CALL(*mock_network_delegate, SendPublicKeyToDmServerSync(dmserver_url, token, testing::_)) - .WillOnce(testing::Return(response_str)); + .WillOnce(testing::Return(/*http_code=*/200)); auto key_rotation_manager = enterprise_connectors::KeyRotationManager::CreateForTesting(
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index 11b15ce..2dda2923 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc
@@ -94,8 +94,10 @@ // Tells installer to expect to be run as a subsidiary to an MSI. const char kMsi[] = "msi"; -// Useful only when used with --update-setup-exe, otherwise ignored. It -// specifies the full path where updated setup.exe will be stored. +// Useful only when used with --update-setup-exe; otherwise ignored. Specifies +// the full path where the updated setup.exe will be written. Any other files +// created in the indicated directory may be deleted by the caller after process +// termination. const char kNewSetupExe[] = "new-setup-exe"; // Specifies a nonce to use with the rotate device key command.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 350fef6..6a29a52 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -350,8 +350,10 @@ url::Replacements<char> replacements; replacements.ClearQuery(); replacements.ClearRef(); - return url.ReplaceComponents(replacements) == - "chrome-untrusted://terminal/html/nassh.html"; + url = url.ReplaceComponents(replacements); + // TODO(crbug.com/1283153): remove nassh.html when the migration is done. + return url == "chrome-untrusted://terminal/html/nassh.html" || + url == "chrome-untrusted://terminal/html/terminal_ssh.html"; } #endif
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7bda1ad5..339deff 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -122,6 +122,7 @@ # require many files from it. This makes linking more efficient. static_library("test_support") { defines = [] + deps = [] testonly = true sources = [ @@ -143,6 +144,8 @@ "../browser/signin/identity_test_environment_profile_adaptor.h", "base/chrome_render_view_host_test_harness.cc", "base/chrome_render_view_host_test_harness.h", + "base/chrome_render_view_test.cc", + "base/chrome_render_view_test.h", "base/chrome_test_launcher.cc", "base/chrome_test_launcher.h", "base/chrome_test_suite.cc", @@ -187,6 +190,19 @@ "base/web_feature_histogram_tester.h", ] + if (enable_extensions) { + sources += [ + "../browser/apps/platform_apps/app_browsertest_util.cc", + "../browser/apps/platform_apps/app_browsertest_util.h", + ] + + deps += [ + "//components/media_router/browser:test_support", + "//components/media_router/common:test_support", + "//extensions/renderer", + ] + } + if (is_chrome_branded && (is_mac || is_win || (is_posix && !is_android && !is_chromeos_ash) || is_fuchsia)) { @@ -204,12 +220,14 @@ configs += [ "//build/config:precompiled_headers" ] - deps = [ + deps += [ "//build:chromeos_buildflags", "//chrome/app:command_ids", "//chrome/common/search:mojo_bindings", + "//components/autofill/content/renderer:test_support", "//components/safe_browsing/content/renderer/phishing_classifier:unit_tests_support", "//components/security_interstitials/content:security_interstitial_page", + "//components/spellcheck/renderer", ] # New deps should go in the non-iOS section below. @@ -780,16 +798,11 @@ "../browser/subresource_filter/subresource_filter_browser_test_harness.cc", "../browser/subresource_filter/subresource_filter_browser_test_harness.h", "../browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc", + "../renderer/safe_browsing/phishing_classifier_browsertest.cc", "android/browsertests_apk/android_browsertests_jni_onload.cc", "base/android/android_browser_test_browsertest_android.cc", ] - sources += [ - "../renderer/safe_browsing/phishing_classifier_browsertest.cc", - "../test/base/chrome_render_view_test.cc", - "../test/base/chrome_render_view_test.h", - ] - deps += [ "//components/autofill/content/renderer:test_support", "//components/browsing_data/core:core", @@ -2101,8 +2114,6 @@ "../renderer/translate/per_frame_translate_agent_browsertest.cc", "../renderer/translate/translate_agent_browsertest.cc", "../renderer/translate/translate_script_browsertest.cc", - "base/chrome_render_view_test.cc", - "base/chrome_render_view_test.h", "base/devtools_listener.cc", "base/devtools_listener.h", "base/devtools_listener_browsertest.cc", @@ -2525,8 +2536,6 @@ "../browser/apps/platform_apps/api/music_manager_private/music_manager_private_browsertest.cc", "../browser/apps/platform_apps/api/sync_file_system/sync_file_system_apitest.cc", "../browser/apps/platform_apps/api/sync_file_system/sync_file_system_browsertest.cc", - "../browser/apps/platform_apps/app_browsertest_util.cc", - "../browser/apps/platform_apps/app_browsertest_util.h", "../browser/apps/platform_apps/audio_focus_web_contents_observer_browsertest.cc", "../browser/extensions/active_tab_apitest.cc", "../browser/extensions/alert_apitest.cc", @@ -2544,6 +2553,7 @@ "../browser/extensions/api/commands/command_service_browsertest.cc", "../browser/extensions/api/content_settings/content_settings_apitest.cc", "../browser/extensions/api/context_menus/context_menu_apitest.cc", + "../browser/extensions/api/context_menus/extension_context_menu_browsertest.cc", "../browser/extensions/api/cookies/cookies_apitest.cc", "../browser/extensions/api/cryptotoken_private/cryptotoken_private_browsertest.cc", "../browser/extensions/api/debugger/debugger_apitest.cc", @@ -2563,6 +2573,7 @@ "../browser/extensions/api/extension_action/browser_action_browsertest.cc", "../browser/extensions/api/extension_action/extension_action_apitest.cc", "../browser/extensions/api/extension_action/page_action_apitest.cc", + "../browser/extensions/api/extension_action/page_action_browsertest.cc", "../browser/extensions/api/extension_action/test_extension_action_api_observer.cc", "../browser/extensions/api/extension_action/test_extension_action_api_observer.h", "../browser/extensions/api/extension_action/test_icon_image_observer.cc", @@ -2586,13 +2597,16 @@ "../browser/extensions/api/management/management_api_non_persistent_apitest.cc", "../browser/extensions/api/management/management_apitest.cc", "../browser/extensions/api/management/management_browsertest.cc", + "../browser/extensions/api/messaging/messaging_apitest.cc", "../browser/extensions/api/messaging/native_messaging_apitest.cc", + "../browser/extensions/api/messaging/service_worker_messaging_apitest.cc", "../browser/extensions/api/metrics_private/metrics_apitest.cc", "../browser/extensions/api/module/module_apitest.cc", "../browser/extensions/api/page_capture/page_capture_apitest.cc", "../browser/extensions/api/passwords_private/passwords_private_apitest.cc", "../browser/extensions/api/permissions/permissions_apitest.cc", "../browser/extensions/api/preference/preference_apitest.cc", + "../browser/extensions/api/printer_provider/printer_provider_apitest.cc", "../browser/extensions/api/processes/processes_apitest.cc", "../browser/extensions/api/proxy/proxy_apitest.cc", "../browser/extensions/api/resources_private/resources_private_apitest.cc", @@ -2611,6 +2625,8 @@ "../browser/extensions/api/tab_capture/tab_capture_performance_test_base.h", "../browser/extensions/api/tab_capture/tab_capture_performancetest.cc", "../browser/extensions/api/tab_groups/tab_groups_api_apitest.cc", + "../browser/extensions/api/tabs/execute_script_apitest.cc", + "../browser/extensions/api/tabs/tabs_apitest.cc", "../browser/extensions/api/tabs/tabs_test.cc", "../browser/extensions/api/test/apitest_apitest.cc", "../browser/extensions/api/top_sites/top_sites_apitest.cc", @@ -2651,12 +2667,10 @@ "../browser/extensions/crx_installer_browsertest.cc", "../browser/extensions/error_console/error_console_browsertest.cc", "../browser/extensions/events_apitest.cc", - "../browser/extensions/execute_script_apitest.cc", "../browser/extensions/extension_action_runner_browsertest.cc", "../browser/extensions/extension_bindings_apitest.cc", "../browser/extensions/extension_bookmarklet_browsertest.cc", "../browser/extensions/extension_browsertest_browsertest.cc", - "../browser/extensions/extension_context_menu_browsertest.cc", "../browser/extensions/extension_cookies_browsertest.cc", "../browser/extensions/extension_csp_bypass_browsertest.cc", "../browser/extensions/extension_disabled_ui_browsertest.cc", @@ -2675,8 +2689,8 @@ "../browser/extensions/extension_install_prompt_test_helper.cc", "../browser/extensions/extension_install_prompt_test_helper.h", "../browser/extensions/extension_install_ui_browsertest.cc", + "../browser/extensions/extension_l10n_browsertest.cc", "../browser/extensions/extension_loading_browsertest.cc", - "../browser/extensions/extension_messages_apitest.cc", "../browser/extensions/extension_modules_apitest.cc", "../browser/extensions/extension_override_apitest.cc", "../browser/extensions/extension_resource_request_policy_apitest.cc", @@ -2685,7 +2699,6 @@ "../browser/extensions/extension_startup_browsertest.cc", "../browser/extensions/extension_storage_apitest.cc", "../browser/extensions/extension_tab_util_browsertest.cc", - "../browser/extensions/extension_tabs_apitest.cc", "../browser/extensions/extension_unload_browsertest.cc", "../browser/extensions/extension_untrusted_webui_apitest.cc", "../browser/extensions/extension_url_loader_throttle_browsertest.cc", @@ -2713,9 +2726,7 @@ "../browser/extensions/native_bindings_apitest.cc", "../browser/extensions/navigation_observer_browsertest.cc", "../browser/extensions/options_page_apitest.cc", - "../browser/extensions/page_action_browsertest.cc", "../browser/extensions/preinstalled_apps_browsertest.cc", - "../browser/extensions/printer_provider_apitest.cc", "../browser/extensions/process_management_browsertest.cc", "../browser/extensions/process_manager_browsertest.cc", "../browser/extensions/process_util_browsertest.cc", @@ -2724,7 +2735,6 @@ "../browser/extensions/sandboxed_pages_apitest.cc", "../browser/extensions/script_executor_browsertest.cc", "../browser/extensions/service_worker_apitest.cc", - "../browser/extensions/service_worker_messaging_apitest.cc", "../browser/extensions/shared_module_apitest.cc", "../browser/extensions/shared_worker_apitest.cc", "../browser/extensions/startup_helper_browsertest.cc", @@ -3485,6 +3495,7 @@ "../browser/ui/app_list/search/files/drive_search_browsertest.cc", "../browser/ui/app_list/search/help_app_search_browsertest.cc", "../browser/ui/ash/accelerator_commands_browsertest.cc", + "../browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc", "../browser/ui/ash/ash_web_view_impl_browsertest.cc", "../browser/ui/ash/assistant/assistant_context_browsertest.cc", "../browser/ui/ash/back_gesture_browsertest.cc", @@ -3568,6 +3579,7 @@ "../browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc", "../browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc", "../browser/ui/webui/signin/inline_login_dialog_chromeos_browsertest.cc", + "../browser/ui/webui/signin/signin_helper_chromeos_browsertest.cc", "../browser/ui/window_sizer/window_sizer_chromeos_uitest.cc", "../browser/web_applications/app_service/link_capturing_migration_manager_browsertest.cc", "../browser/web_applications/app_service/web_apps_browsertest.cc", @@ -4884,8 +4896,6 @@ "../renderer/subresource_redirect/robots_rules_parser_unittest.cc", "../renderer/subresource_redirect/subresource_redirect_util_unittest.cc", "../renderer/v8_unwinder_unittest.cc", - "../test/base/chrome_render_view_test.cc", - "../test/base/chrome_render_view_test.h", "../test/base/menu_model_test.cc", "../test/base/menu_model_test.h", "../test/base/v8_unit_test.cc", @@ -6682,10 +6692,6 @@ "../browser/ui/ash/network/tether_notification_presenter_unittest.cc", "../browser/ui/ash/projector/projector_client_impl_unittest.cc", "../browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc", - "../browser/ui/ash/quick_answers/quick_answers_controller_unittest.cc", - "../browser/ui/ash/quick_answers/quick_answers_state_controller_unittest.cc", - "../browser/ui/ash/quick_answers/quick_answers_ui_controller_unittest.cc", - "../browser/ui/ash/quick_answers/ui/quick_answers_view_unittest.cc", "../browser/ui/ash/session_controller_client_impl_unittest.cc", "../browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc", "../browser/ui/ash/shelf/arc_app_shelf_id_unittest.cc", @@ -6694,6 +6700,10 @@ "../browser/ui/ash/shelf/shelf_context_menu_unittest.cc", "../browser/ui/ash/wallpaper_controller_client_impl_unittest.cc", "../browser/ui/ash/window_pin_util_unittest.cc", + "../browser/ui/quick_answers/quick_answers_controller_unittest.cc", + "../browser/ui/quick_answers/quick_answers_state_controller_unittest.cc", + "../browser/ui/quick_answers/quick_answers_ui_controller_unittest.cc", + "../browser/ui/quick_answers/ui/quick_answers_view_unittest.cc", "../browser/ui/webui/chromeos/login/fake_update_required_screen_handler.cc", "../browser/ui/webui/chromeos/login/fake_update_required_screen_handler.h", "../browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc", @@ -6878,6 +6888,7 @@ "../browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc", "../browser/extensions/api/extension_action/extension_action_api_unittest.cc", "../browser/extensions/api/file_system/file_system_api_unittest.cc", + "../browser/extensions/api/gcm/extension_gcm_app_handler_unittest.cc", "../browser/extensions/api/identity/extension_token_key_unittest.cc", "../browser/extensions/api/identity/gaia_remote_consent_flow_unittest.cc", "../browser/extensions/api/identity/identity_api_unittest.cc", @@ -6956,7 +6967,6 @@ "../browser/extensions/extension_error_controller_unittest.cc", "../browser/extensions/extension_error_ui_default_unittest.cc", "../browser/extensions/extension_garbage_collector_unittest.cc", - "../browser/extensions/extension_gcm_app_handler_unittest.cc", "../browser/extensions/extension_icon_manager_unittest.cc", "../browser/extensions/extension_install_prompt_unittest.cc", "../browser/extensions/extension_management_unittest.cc", @@ -7312,6 +7322,7 @@ if (!is_android && !is_win) { sources += [ "../browser/ui/startup/startup_browser_creator_impl_unittest.cc", + "../browser/ui/startup/startup_browser_creator_unittest.cc", "../browser/ui/startup/startup_tab_provider_unittest.cc", ] } @@ -7486,10 +7497,14 @@ } if (is_linux || is_mac || is_win) { - sources += [ "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc" ] + sources += [ + "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc", + "../browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc", + ] deps += [ "../browser/enterprise/connectors/device_trust/key_management/browser", + "../browser/enterprise/connectors/device_trust/key_management/browser:test_support", "../browser/enterprise/connectors/device_trust/key_management/browser:unit_tests", "../browser/enterprise/connectors/device_trust/key_management/browser/commands:unit_tests", "../browser/enterprise/connectors/device_trust/key_management/core", @@ -7983,8 +7998,8 @@ if (is_chromeos_ash) { sources += [ - "../browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.cc", - "../browser/ui/ash/quick_answers/test/chrome_quick_answers_test_base.h", + "../browser/ui/quick_answers/test/chrome_quick_answers_test_base.cc", + "../browser/ui/quick_answers/test/chrome_quick_answers_test_base.h", "base/chrome_ash_test_base.cc", "base/chrome_ash_test_base.h", ] @@ -8300,6 +8315,7 @@ "../browser/extensions/api/notifications/notifications_apitest.cc", "../browser/extensions/api/omnibox/omnibox_api_interactive_test.cc", "../browser/extensions/api/tabs/tabs_interactive_test.cc", + "../browser/extensions/api/tabs/window_open_interactive_apitest.cc", "../browser/extensions/app_window_uitest.cc", "../browser/extensions/chrome_extension_test_notification_observer.cc", "../browser/extensions/chrome_extension_test_notification_observer.h", @@ -8312,7 +8328,6 @@ "../browser/extensions/extension_function_test_utils.h", "../browser/extensions/extension_keybinding_apitest.cc", "../browser/extensions/omnibox_focus_interactive_test.cc", - "../browser/extensions/window_open_interactive_apitest.cc", "../browser/focus_ring_browsertest.cc", "../browser/media/webrtc/media_stream_permission_interactive_uitest.cc", "../browser/media/webrtc/webrtc_interactive_uitest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java index f8a85da7..194940f7 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -371,7 +371,7 @@ public static void switchTabInCurrentTabModel(final ChromeActivity activity, final int tabIndex) { TestThreadUtils.runOnUiThreadBlocking( - () -> { TabModelUtils.setIndex(activity.getCurrentTabModel(), tabIndex); }); + () -> { TabModelUtils.setIndex(activity.getCurrentTabModel(), tabIndex, false); }); } /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java index eca17df..390e78d 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java
@@ -106,7 +106,7 @@ } @Override - public void setIndex(int i, @TabSelectionType int type) { + public void setIndex(int i, @TabSelectionType int type, boolean skipLoadingTab) { mIndex = i; }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java index a35b6a5..b475a44 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java
@@ -31,12 +31,12 @@ for (int i = 0; i < tabCount; i++) { addMockTab(); } - if (tabCount > 0) TabModelUtils.setIndex(getModel(false), 0); + if (tabCount > 0) TabModelUtils.setIndex(getModel(false), 0, false); for (int i = 0; i < incognitoTabCount; i++) { addMockIncognitoTab(); } - if (incognitoTabCount > 0) TabModelUtils.setIndex(getModel(true), 0); + if (incognitoTabCount > 0) TabModelUtils.setIndex(getModel(true), 0, false); mTabCount = tabCount; }
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index c7dadb2..7d52320 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -233,7 +233,8 @@ TestingFactories testing_factories, const std::string& profile_name, absl::optional<bool> override_policy_connector_is_managed, - absl::optional<OTRProfileID> otr_profile_id) + absl::optional<OTRProfileID> otr_profile_id, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) : prefs_(std::move(prefs)), original_profile_(parent), guest_session_(guest_session), @@ -253,7 +254,8 @@ override_policy_connector_is_managed_( override_policy_connector_is_managed), otr_profile_id_(otr_profile_id), - policy_service_(std::move(policy_service)) { + policy_service_(std::move(policy_service)), + url_loader_factory_(url_loader_factory) { if (parent) parent->SetOffTheRecordProfile(std::unique_ptr<Profile>(this)); @@ -809,7 +811,7 @@ scoped_refptr<network::SharedURLLoaderFactory> TestingProfile::GetURLLoaderFactory() { - return nullptr; + return url_loader_factory_; } content::ResourceContext* TestingProfile::GetResourceContext() { @@ -1054,6 +1056,11 @@ profile_name_ = profile_name; } +void TestingProfile::Builder::SetSharedURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + url_loader_factory_ = url_loader_factory; +} + void TestingProfile::Builder::OverridePolicyConnectorIsManagedForTesting( bool is_managed) { override_policy_connector_is_managed_ = is_managed; @@ -1087,7 +1094,8 @@ #endif // BUILDFLAG(IS_CHROMEOS_LACROS) supervised_user_id_, std::move(user_cloud_policy_manager_), std::move(policy_service_), std::move(testing_factories_), profile_name_, - override_policy_connector_is_managed_, absl::optional<OTRProfileID>()); + override_policy_connector_is_managed_, absl::optional<OTRProfileID>(), + url_loader_factory_); } TestingProfile* TestingProfile::Builder::BuildOffTheRecord( @@ -1111,7 +1119,7 @@ supervised_user_id_, std::move(user_cloud_policy_manager_), std::move(policy_service_), std::move(testing_factories_), profile_name_, override_policy_connector_is_managed_, - absl::optional<OTRProfileID>(otr_profile_id)); + absl::optional<OTRProfileID>(otr_profile_id), url_loader_factory_); } TestingProfile* TestingProfile::Builder::BuildIncognito(
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 2de3571..7ed3a5ac 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h
@@ -171,6 +171,10 @@ // Sets the UserProfileName to be used by this profile. void SetProfileName(const std::string& profile_name); + // Sets the SharedURLLoaderFactory to be used by this profile. + void SetSharedURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + void OverridePolicyConnectorIsManagedForTesting(bool is_managed); // Creates the TestingProfile using previously-set settings. @@ -212,6 +216,7 @@ TestingFactories testing_factories_; std::string profile_name_{kDefaultProfileUserName}; absl::optional<bool> override_policy_connector_is_managed_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; }; // Multi-profile aware constructor that takes the path to a directory managed @@ -253,7 +258,8 @@ TestingFactories testing_factories, const std::string& profile_name, absl::optional<bool> override_policy_connector_is_managed, - absl::optional<OTRProfileID> otr_profile_id); + absl::optional<OTRProfileID> otr_profile_id, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~TestingProfile() override; @@ -521,6 +527,8 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) raw_ptr<TestingPrefStore> supervised_user_pref_store_ = nullptr; #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; }; #endif // CHROME_TEST_BASE_TESTING_PROFILE_H_
diff --git a/chrome/test/data/banners/192x192-green.png b/chrome/test/data/banners/192x192-green.png deleted file mode 100644 index 60217629..0000000 --- a/chrome/test/data/banners/192x192-green.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/192x192-red.png b/chrome/test/data/banners/192x192-red.png deleted file mode 100644 index 57c601e3..0000000 --- a/chrome/test/data/banners/192x192-red.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/2x2-green.png b/chrome/test/data/banners/2x2-green.png deleted file mode 100644 index 3b95dc5..0000000 --- a/chrome/test/data/banners/2x2-green.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/2x2-red.png b/chrome/test/data/banners/2x2-red.png deleted file mode 100644 index 6ee73b0..0000000 --- a/chrome/test/data/banners/2x2-red.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/48x48-green.png b/chrome/test/data/banners/48x48-green.png deleted file mode 100644 index e3165d9..0000000 --- a/chrome/test/data/banners/48x48-green.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/48x48-red.png b/chrome/test/data/banners/48x48-red.png deleted file mode 100644 index 4023bfa0..0000000 --- a/chrome/test/data/banners/48x48-red.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/4x4-green.png b/chrome/test/data/banners/4x4-green.png deleted file mode 100644 index 638a81f3..0000000 --- a/chrome/test/data/banners/4x4-green.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/4x4-red.png b/chrome/test/data/banners/4x4-red.png deleted file mode 100644 index a8db5643..0000000 --- a/chrome/test/data/banners/4x4-red.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/96x96-green.png b/chrome/test/data/banners/96x96-green.png deleted file mode 100644 index 64c5eb1..0000000 --- a/chrome/test/data/banners/96x96-green.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/96x96-red.png b/chrome/test/data/banners/96x96-red.png deleted file mode 100644 index 97b1cbd..0000000 --- a/chrome/test/data/banners/96x96-red.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/banners/background-color.html b/chrome/test/data/banners/background-color.html new file mode 100644 index 0000000..887ef48 --- /dev/null +++ b/chrome/test/data/banners/background-color.html
@@ -0,0 +1,15 @@ +<html> + <head> + <title>Manifest test app with background color</title> + <link rel="manifest" href="background-color.json"> + <meta id="background-color" name="background-color" content="blue"> + <script> + window.onload = () => { + navigator.serviceWorker.register('service_worker.js'); + }; + </script> + </head> + <body> + Manifest test app with a background color. + </body> +</html>
diff --git a/chrome/test/data/banners/background-color.json b/chrome/test/data/banners/background-color.json new file mode 100644 index 0000000..0e98bf4 --- /dev/null +++ b/chrome/test/data/banners/background-color.json
@@ -0,0 +1,14 @@ +{ + "name": "Manifest test app with background color", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "background-color.html", + "display": "standalone", + "background_color": "blue", + "orientation": "landscape" +}
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js index 551cfd6..ee0a60f 100644 --- a/chrome/test/data/extensions/api_test/autotest_private/test.js +++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -251,6 +251,12 @@ chrome.autotestPrivate.importCrostini('backup', chrome.test.callbackFail( 'Crostini is not available for the current user')); }, + function couldAllowCrostini() { + chrome.autotestPrivate.couldAllowCrostini(chrome.test.callbackPass( + result => { + chrome.test.assertFalse(result); + })); + }, function takeScreenshot() { chrome.autotestPrivate.takeScreenshot( function(base64Png) {
diff --git a/chrome/test/data/extensions/api_test/enterprise_device_attributes/manifest.json b/chrome/test/data/extensions/api_test/enterprise_device_attributes/manifest.json index e589325..e5edfd9 100644 --- a/chrome/test/data/extensions/api_test/enterprise_device_attributes/manifest.json +++ b/chrome/test/data/extensions/api_test/enterprise_device_attributes/manifest.json
@@ -3,7 +3,7 @@ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9wuYZskRPc1EcmC5ZUbfo+XaVc5JrBnTYAXWqJCfhOkHbTecxEFibuIs1gEAqaFeNsKXpVa1p8n9wpsvXUOC0fvZr7K0N7LZ0TBveslthw+Nn1eQJ/kTKVeVm3FJ4It1PUEN9fN6kmSJ4Qq9gQjMq3iLtafThKS550m2ZKFYlSFIwaqiPpPy8jjDRaf5s2TwTGfnP5t9sf2c87syoq1Z/qy9xi07EG3WgJ1Nf6MjGNqBGfG0qs+73ycXMbH6iya1xardy/7gLb3BVkGHoMsKiViFB3krcaYOvhithZSmmFnbR4zlDLmr04mU7bpS6Su5qIJfjZM+m5BbV3oBlSHD3QIDAQAB", "name": "Basic tests", "version": "0.1", - "manifest_version": 2, + "manifest_version": 3, "permissions": [ "enterprise.deviceAttributes" ]
diff --git a/chrome/test/data/extensions/api_test/enterprise_networking_attributes/manifest.json b/chrome/test/data/extensions/api_test/enterprise_networking_attributes/manifest.json index 09945ee7..cf3264b 100644 --- a/chrome/test/data/extensions/api_test/enterprise_networking_attributes/manifest.json +++ b/chrome/test/data/extensions/api_test/enterprise_networking_attributes/manifest.json
@@ -3,7 +3,7 @@ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4qozNx/Ly/K+BZ+jHR1PRonQse5jRsQ2D+R8gP4/QOV7gPxahFrAnBYkGPWeeINS89S23cPYPx99SH1x4RlU84scEE/UQhr1PnrNGC8Z+Y87K+xL8rq0zxNKzl183aqImw+sB2PS4F6/An+N6O9oGuTgi5RmT9dxkd5pwuyXnxWYZK+GK2KfG+0JOG9/c/gzkIqosOXmfH71usa8GwYmVCNieC3mcWkm9cb7QbXW3fqPI7mDJjt48XAU9wDiy8EiOypH7iXhK0CCFfqcqM9oTnrHSBPierC/WsNNUrq9pBsdSH2ryio+mfc7K+b9ZvFabAZI6VnqYA/Hmp1gppCJvQIDAQAB", "name": "enterprise.networkingAttributes API test extension", "version": "1.0", - "manifest_version": 2, + "manifest_version": 3, "permissions": [ "enterprise.networkingAttributes" ]
diff --git a/chrome/test/data/extensions/error_console/bad_extension_page/manifest.json b/chrome/test/data/extensions/error_console/bad_extension_page/manifest.json index bf8e5887..806a5fb 100644 --- a/chrome/test/data/extensions/error_console/bad_extension_page/manifest.json +++ b/chrome/test/data/extensions/error_console/bad_extension_page/manifest.json
@@ -5,5 +5,5 @@ "chrome_url_overrides": { "newtab": "blank.html" }, - "manifest_version": 2 + "manifest_version": 3 }
diff --git a/chrome/test/data/extensions/error_console/content_script_log_and_runtime_error/manifest.json b/chrome/test/data/extensions/error_console/content_script_log_and_runtime_error/manifest.json index 60fdd2a9..be894d7b 100644 --- a/chrome/test/data/extensions/error_console/content_script_log_and_runtime_error/manifest.json +++ b/chrome/test/data/extensions/error_console/content_script_log_and_runtime_error/manifest.json
@@ -11,5 +11,5 @@ "js": ["content_script.js"] } ], - "manifest_version": 2 + "manifest_version": 3 }
diff --git a/chrome/test/data/extensions/error_console/manifest_warnings/manifest.json b/chrome/test/data/extensions/error_console/manifest_warnings/manifest.json index 4dcb3ce..59ed29c 100644 --- a/chrome/test/data/extensions/error_console/manifest_warnings/manifest.json +++ b/chrome/test/data/extensions/error_console/manifest_warnings/manifest.json
@@ -1,6 +1,6 @@ { "name": "Error Console Manifest Warnings Test", - "manifest_version": 2, + "manifest_version": 3, "version": "1.1", "not_a_real_key": "not_a_real_value", "permissions": [
diff --git a/chrome/test/data/extensions/settings_override/manifest.json b/chrome/test/data/extensions/settings_override/manifest.json index d1fa7f21..bbad04b 100644 --- a/chrome/test/data/extensions/settings_override/manifest.json +++ b/chrome/test/data/extensions/settings_override/manifest.json
@@ -1,7 +1,7 @@ { "name": "chrome.extension.settings_override", "version": "0.1", - "manifest_version": 2, + "manifest_version": 3, "description": "end-to-end browser test for chrome.settings_override API", "chrome_settings_overrides": { "homepage": "http://www.homepage.__MSG_url_domain__/?param=__PARAM__",
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index c65cfed..50aea000 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -7802,7 +7802,7 @@ } ] }, - "FullscreenNotificationUrlExemptList": { + "KeepFullscreenWithoutNotificationUrlAllowList": { "os": [ "chromeos_ash" ], @@ -7810,19 +7810,19 @@ { "policies": {}, "prefs": { - "ash.fullscreen_notification_url_exempt_list": { + "ash.keep_fullscreen_without_notification_url_allow_list": { "default_value": [] } } }, { "policies": { - "FullscreenNotificationUrlExemptList": [ + "KeepFullscreenWithoutNotificationUrlAllowList": [ "*" ] }, "prefs": { - "ash.fullscreen_notification_url_exempt_list": { + "ash.keep_fullscreen_without_notification_url_allow_list": { "value": [ "*" ] @@ -11695,6 +11695,9 @@ "ReportDeviceLoginLogout": { "reason_for_missing_test": "Maps into CrosSettings" }, + "ReportCRDSessions": { + "reason_for_missing_test": "Maps into CrosSettings" + }, "ReportDevicePrintJobs": { "reason_for_missing_test": "Maps into CrosSettings" },
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 35b9342..32f8d0d 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -515,7 +515,6 @@ deps += [ "chromeos:closure_compile", "cr_components/chromeos:closure_compile", - "cr_elements:closure_compile", "nearby_share:closure_compile", "nearby_share/shared:closure_compile", "settings/chromeos:closure_compile",
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js index 1d7f2563b..226cce5 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
@@ -80,12 +80,12 @@ } /** - * @return {!HTMLElement} + * @return {!CrButtonElement} */ function getSessionLogButton() { assertTrue(!!page); - return /** @type {!HTMLElement} */ (page.$$('.session-log-button')); + return /** @type {!CrButtonElement} */ (page.$$('.session-log-button')); } /** @@ -208,5 +208,23 @@ }) .then(() => assertFalse(isVisible(getCautionBanner()))); }); + + test('SaveSessionLogDisabledUntilResolved', () => { + return initializeDiagnosticsApp( + fakeSystemInfo, fakeBatteryChargeStatus, fakeBatteryHealth, + fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage) + .then(() => { + assertFalse(getSessionLogButton().disabled); + + DiagnosticsBrowserProxy.setSuccess(true); + getSessionLogButton().click(); + assertTrue(getSessionLogButton().disabled); + + return flushTasks(); + }) + .then(() => { + assertFalse(getSessionLogButton().disabled); + }); + }); } }
diff --git a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js index 257a565..dd58ea0c 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
@@ -239,6 +239,23 @@ .then(() => assertRunTestButtonsEnabled(cards)); }); + test('SaveSessionLogDisabledWhenPendingResult', () => { + return initializeSystemPage( + fakeSystemInfo, fakeBatteryChargeStatus, fakeBatteryHealth, + fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage) + .then(() => { + assertFalse(getSessionLogButton().disabled); + DiagnosticsBrowserProxy.setSuccess(true); + + getSessionLogButton().click(); + assertTrue(getSessionLogButton().disabled); + return flushTasks(); + }) + .then(() => { + assertFalse(getSessionLogButton().disabled); + }); + }); + test('SaveSessionLogSuccessShowsToast', () => { return initializeSystemPage( fakeSystemInfo, fakeBatteryChargeStatus, fakeBatteryHealth,
diff --git a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn index 6a5ee3e..19429b1 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn +++ b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn
@@ -29,21 +29,25 @@ target_gen_dir), ] in_files = [ - "google_photos_collection_element_test.js", - "google_photos_photos_by_album_id_element_test.js", - "local_images_element_test.js", + "ambient_subpage_element_test.ts", + "google_photos_collection_element_test.ts", + "google_photos_photos_by_album_id_element_test.ts", + "local_images_element_test.ts", "personalization_app_component_test.ts", - "personalization_app_controller_test.js", + "personalization_app_controller_test.ts", "personalization_app_test_utils.ts", - "personalization_breadcrumb_element_test.js", - "personalization_main_element_test.js", + "personalization_breadcrumb_element_test.ts", + "personalization_main_element_test.ts", "personalization_router_element_test.ts", - "personalization_toast_element_test.js", - "test_personalization_store.js", + "personalization_toast_element_test.ts", + "test_personalization_store.ts", "test_wallpaper_interface_provider.ts", - "wallpaper_collections_element_test.js", + "user_subpage_element_test.ts", + "wallpaper_collections_element_test.ts", "wallpaper_fullscreen_element_test.ts", "wallpaper_images_element_test.ts", + "wallpaper_observer_test.ts", + "wallpaper_preview_element_test.ts", "wallpaper_selected_element_test.ts", ] deps = [ "//ash/webui/personalization_app/resources:build_ts" ]
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts new file mode 100644 index 0000000..5726f3c --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts
@@ -0,0 +1,27 @@ +// 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 {AmbientSubpage} from 'chrome://personalization/trusted/ambient/ambient_subpage_element.js'; + +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; + +import {initElement, teardownElement} from './personalization_app_test_utils.js'; + +export function AmbientSubpageTest() { + let ambientSubpageElement: AmbientSubpage|null; + + setup(function() {}); + + teardown(async () => { + await teardownElement(ambientSubpageElement); + ambientSubpageElement = null; + }); + + test('displays content', async () => { + ambientSubpageElement = initElement(AmbientSubpage); + assertEquals( + 'Ambient', + ambientSubpageElement.shadowRoot!.querySelector('h2')!.innerText); + }); +}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.ts similarity index 78% rename from chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.ts index add9ca4..3dbc5ac8 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_collection_element_test.ts
@@ -12,19 +12,16 @@ import {TestPersonalizationStore} from './test_personalization_store.js'; export function GooglePhotosCollectionTest() { - /** @type {?HTMLElement} */ - let googlePhotosCollectionElement = null; + let googlePhotosCollectionElement: GooglePhotosCollection|null; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; + let personalizationStore: TestPersonalizationStore; /** * Returns the match for |selector| in |googlePhotosCollectionElement|'s * shadow DOM. - * @return {?Element|undefined} */ - function querySelector(selector) { - return googlePhotosCollectionElement?.shadowRoot?.querySelector(selector); + function querySelector(selector: string): HTMLElement|null { + return googlePhotosCollectionElement!.shadowRoot!.querySelector(selector); } setup(() => { @@ -68,7 +65,7 @@ // Photos content should be present and visible. const photosContent = querySelector('#photosContent'); assertTrue(!!photosContent); - assertFalse(photosContent.hidden); + assertFalse(photosContent!.hidden); // Albums content should be absent. assertEquals(querySelector('#albumsContent'), null); @@ -96,34 +93,34 @@ // Tab strip should be present and visible. const tabStrip = querySelector('#tabStrip'); assertTrue(!!tabStrip); - assertFalse(tabStrip.hidden); + assertFalse(tabStrip!.hidden); // Photos tab should be present, visible, and pressed. const photosTab = querySelector('#photosTab'); assertTrue(!!photosTab); - assertFalse(photosTab.hidden); - assertEquals(photosTab.getAttribute('aria-pressed'), 'true'); + assertFalse(photosTab!.hidden); + assertEquals(photosTab!.getAttribute('aria-pressed'), 'true'); // Photos content should be present and visible. const photosContent = querySelector('#photosContent'); assertTrue(!!photosContent); - assertFalse(photosContent.hidden); + assertFalse(photosContent!.hidden); // Albums tab should be present, visible, and *not* pressed. const albumsTab = querySelector('#albumsTab'); assertTrue(!!albumsTab); - assertFalse(albumsTab.hidden); - assertEquals(albumsTab.getAttribute('aria-pressed'), 'false'); + assertFalse(albumsTab!.hidden); + assertEquals(albumsTab!.getAttribute('aria-pressed'), 'false'); // Albums content should be present and hidden. const albumsContent = querySelector('#albumsContent'); assertTrue(!!albumsContent); - assertTrue(albumsContent.hidden); + assertTrue(albumsContent!.hidden); // Photos by album id content should be present and hidden. const photosByAlbumIdContent = querySelector('#photosByAlbumIdContent'); assertTrue(!!photosByAlbumIdContent); - assertTrue(photosByAlbumIdContent.hidden); + assertTrue(photosByAlbumIdContent!.hidden); // Clicking the albums tab should cause: // * albums tab to be visible and pressed. @@ -131,14 +128,14 @@ // * photos tab to be visible and *not* pressed. // * photos content to be hidden. // * photos by album id content to be hidden. - albumsTab.click(); - assertFalse(albumsTab.hidden); - assertEquals(albumsTab.getAttribute('aria-pressed'), 'true'); - assertFalse(albumsContent.hidden); - assertFalse(photosTab.hidden); - assertEquals(photosTab.getAttribute('aria-pressed'), 'false'); - assertTrue(photosContent.hidden); - assertTrue(photosByAlbumIdContent.hidden); + albumsTab!.click(); + assertFalse(albumsTab!.hidden); + assertEquals(albumsTab!.getAttribute('aria-pressed'), 'true'); + assertFalse(albumsContent!.hidden); + assertFalse(photosTab!.hidden); + assertEquals(photosTab!.getAttribute('aria-pressed'), 'false'); + assertTrue(photosContent!.hidden); + assertTrue(photosByAlbumIdContent!.hidden); // Selecting an album should cause: // * tab strip to be hidden. @@ -147,10 +144,10 @@ // * photos content to be hidden. googlePhotosCollectionElement.setAttribute('album-id', '1'); await waitAfterNextRender(googlePhotosCollectionElement); - assertEquals(window.getComputedStyle(tabStrip).display, 'none'); - assertFalse(photosByAlbumIdContent.hidden); - assertTrue(albumsContent.hidden); - assertTrue(photosContent.hidden); + assertEquals(window.getComputedStyle(tabStrip!).display, 'none'); + assertFalse(photosByAlbumIdContent!.hidden); + assertTrue(albumsContent!.hidden); + assertTrue(photosContent!.hidden); // Un-selecting an album should cause: // * tab strip to be visible. @@ -159,10 +156,10 @@ // * photos content to be hidden. googlePhotosCollectionElement.removeAttribute('album-id'); await waitAfterNextRender(googlePhotosCollectionElement); - assertEquals(window.getComputedStyle(tabStrip).display, 'block'); - assertTrue(photosByAlbumIdContent.hidden); - assertFalse(albumsContent.hidden); - assertTrue(photosContent.hidden); + assertEquals(window.getComputedStyle(tabStrip!).display, 'block'); + assertTrue(photosByAlbumIdContent!.hidden); + assertFalse(albumsContent!.hidden); + assertTrue(photosContent!.hidden); // Clicking the photos tab should cause: // * photos tab to be visible and pressed. @@ -170,14 +167,14 @@ // * albums tab to be visible and *not* pressed. // * albums content to be hidden. // * photos by album id content to be hidden. - photosTab.click(); - assertFalse(photosTab.hidden); - assertEquals(photosTab.getAttribute('aria-pressed'), 'true'); - assertFalse(photosContent.hidden); - assertFalse(albumsTab.hidden); - assertEquals(albumsTab.getAttribute('aria-pressed'), 'false'); - assertTrue(albumsContent.hidden); - assertTrue(photosByAlbumIdContent.hidden); + photosTab!.click(); + assertFalse(photosTab!.hidden); + assertEquals(photosTab!.getAttribute('aria-pressed'), 'true'); + assertFalse(photosContent!.hidden); + assertFalse(albumsTab!.hidden); + assertEquals(albumsTab!.getAttribute('aria-pressed'), 'false'); + assertTrue(albumsContent!.hidden); + assertTrue(photosByAlbumIdContent!.hidden); }); test('displays zero state when there is no content', async () => { @@ -208,6 +205,6 @@ // Zero state should be present and visible. const zeroState = querySelector('#zeroState'); assertTrue(!!zeroState); - assertFalse(zeroState.hidden); + assertFalse(zeroState!.hidden); }); }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts similarity index 81% rename from chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts index b786c80..38d1c678 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts
@@ -11,30 +11,17 @@ import {TestPersonalizationStore} from './test_personalization_store.js'; export function GooglePhotosPhotosByAlbumIdTest() { - /** @type {?HTMLElement} */ - let googlePhotosPhotosByAlbumIdElement = null; + let googlePhotosPhotosByAlbumIdElement: GooglePhotosPhotosByAlbumId|null; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; - - /** - * Returns the match for |selector| in |googlePhotosPhotosByAlbumIdElement|'s - * shadow DOM. - * @return {?Element|undefined} - */ - function querySelector(selector) { - return googlePhotosPhotosByAlbumIdElement?.shadowRoot?.querySelector( - selector); - } + let personalizationStore: TestPersonalizationStore; /** * Returns all matches for |selector| in * |googlePhotosPhotosByAlbumIdElement|'s shadow DOM. - * @return {?Array<Element>} */ - function querySelectorAll(selector) { + function querySelectorAll(selector: string): Element[]|null { const matches = - googlePhotosPhotosByAlbumIdElement?.shadowRoot?.querySelectorAll( + googlePhotosPhotosByAlbumIdElement!.shadowRoot!.querySelectorAll( selector); return matches ? [...matches] : null; } @@ -60,7 +47,7 @@ // Initially no album id selected. Photos should be absent. const photoSelector = 'wallpaper-grid-item:not([hidden]) .photo'; - assertEquals(querySelectorAll(photoSelector).length, 0); + assertEquals(querySelectorAll(photoSelector)!.length, 0); const {fetchGooglePhotosAlbum: fetchGooglePhotosAlbumPromise} = promisifyWallpaperControllerFunctionsForTesting(); @@ -68,7 +55,7 @@ // Select an album id. Photos should be absent since they are not loaded. googlePhotosPhotosByAlbumIdElement.setAttribute('album-id', '1'); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 0); + assertEquals(querySelectorAll(photoSelector)!.length, 0); // Expect a request to load photos for the selected album id. const [, , albumId] = await fetchGooglePhotosAlbumPromise; @@ -83,7 +70,7 @@ }; personalizationStore.notifyObservers(); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 0); + assertEquals(querySelectorAll(photoSelector)!.length, 0); // Load photos for an album id other than that which is selected. Photos // should still be absent since they are still not loaded for the selected @@ -99,7 +86,7 @@ }; personalizationStore.notifyObservers(); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 0); + assertEquals(querySelectorAll(photoSelector)!.length, 0); // Finish loading photos for the selected album id. Photos should now be // present since they are finished loading for the selected album id. @@ -114,19 +101,19 @@ }; personalizationStore.notifyObservers(); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 100); + assertEquals(querySelectorAll(photoSelector)!.length, 100); // Select the other album id for which data is already loaded. Photos should // immediately update since they are already loaded for the selected album // id. googlePhotosPhotosByAlbumIdElement.setAttribute('album-id', '2'); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 50); + assertEquals(querySelectorAll(photoSelector)!.length, 50); // Un-select the album id. Photos should be absent since no album id is // selected. googlePhotosPhotosByAlbumIdElement.removeAttribute('album-id'); await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement); - assertEquals(querySelectorAll(photoSelector).length, 0); + assertEquals(querySelectorAll(photoSelector)!.length, 0); }); }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts similarity index 82% rename from chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts index ed59e89..2663bee0 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
@@ -12,20 +12,16 @@ import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; export function LocalImagesTest() { - /** @type {?HTMLElement} */ - let localImagesElement = null; + let localImagesElement: LocalImages|null; - /** @type {?TestWallpaperProvider} */ - let wallpaperProvider = null; + let wallpaperProvider: TestWallpaperProvider; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; + let personalizationStore: TestPersonalizationStore; /** * Get all currently visible photo loading placeholders. - * @return {!Array<HTMLElement>} */ - function getLoadingPlaceholders() { + function getLoadingPlaceholders(): HTMLElement[] { if (!localImagesElement) { return []; } @@ -34,7 +30,7 @@ '.photo-inner-container.placeholder:not([style*="display: none"])', ]; return Array.from( - localImagesElement.shadowRoot.querySelectorAll(selectors.join(' '))); + localImagesElement.shadowRoot!.querySelectorAll(selectors.join(' '))); } setup(() => { @@ -107,13 +103,13 @@ localImagesElement = initElement(LocalImages, {hidden: false}); const ironList = - localImagesElement.shadowRoot.querySelector('iron-list'); + localImagesElement.shadowRoot!.querySelector('iron-list'); assertTrue(!!ironList); // Both items are sent. No images are rendered yet because they are not // done loading thumbnails. - assertEquals(2, ironList.items.length); - assertEquals(0, ironList.shadowRoot.querySelectorAll('img').length); + assertEquals(2, ironList!.items!.length); + assertEquals(0, ironList!.shadowRoot!.querySelectorAll('img').length); // Set loading finished for first thumbnail. personalizationStore.data.wallpaper.loading.local.data = { @@ -121,10 +117,10 @@ }; personalizationStore.notifyObservers(); await waitAfterNextRender(localImagesElement); - assertEquals(2, ironList.items.length); - let imgTags = localImagesElement.shadowRoot.querySelectorAll('img'); + assertEquals(2, ironList!.items!.length); + let imgTags = localImagesElement.shadowRoot!.querySelectorAll('img'); assertEquals(1, imgTags.length); - assertEquals('data://localimage0data', imgTags[0].src); + assertEquals('data://localimage0data', imgTags![0]!.src); // Set loading failed for second thumbnail. personalizationStore.data.wallpaper.loading.local.data = { @@ -138,9 +134,9 @@ personalizationStore.notifyObservers(); await waitAfterNextRender(localImagesElement); // Still only first thumbnail displayed. - imgTags = localImagesElement.shadowRoot.querySelectorAll('img'); + imgTags = localImagesElement.shadowRoot!.querySelectorAll('img'); assertEquals(1, imgTags.length); - assertEquals('data://localimage0data', imgTags[0].src); + assertEquals('data://localimage0data', imgTags![0]!.src); }); test( @@ -161,7 +157,7 @@ // iron-list pre-creates some extra DOM elements but marks them as // hidden. Ignore them here to only get visible images. - const images = localImagesElement.shadowRoot.querySelectorAll( + const images = localImagesElement.shadowRoot!.querySelectorAll( '.photo-container:not([hidden]) .photo-inner-container'); assertEquals(2, images.length); @@ -175,8 +171,8 @@ personalizationStore.notifyObservers(); assertEquals(2, images.length); - assertEquals(images[0].getAttribute('aria-selected'), 'false'); - assertEquals(images[1].getAttribute('aria-selected'), 'true'); + assertEquals(images[0]!.getAttribute('aria-selected'), 'false'); + assertEquals(images[1]!.getAttribute('aria-selected'), 'true'); }); test('images have proper aria label when loaded', async () => { @@ -195,7 +191,7 @@ // iron-list pre-creates some extra DOM elements but marks them as // hidden. Ignore them here to only get visible images. - const images = localImagesElement.shadowRoot.querySelectorAll( + const images = localImagesElement.shadowRoot!.querySelectorAll( '.photo-container:not([hidden]) .photo-inner-container'); assertEquals(2, images.length); @@ -204,10 +200,10 @@ image => image.getAttribute('aria-selected') === 'false')); // Every image has aria-label set. assertEquals( - images[0].getAttribute('aria-label'), - wallpaperProvider.localImages[0].path); + images[0]!.getAttribute('aria-label'), + wallpaperProvider.localImages![0]!.path); assertEquals( - images[1].getAttribute('aria-label'), - wallpaperProvider.localImages[1].path); + images[1]!.getAttribute('aria-label'), + wallpaperProvider.localImages![1]!.path); }); }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_test.ts index 91a7a2e..bd5f9c8f 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_test.ts
@@ -5,6 +5,7 @@ import 'chrome://personalization/strings.m.js'; import 'chrome://webui-test/mojo_webui_test_support.js'; +import {AmbientSubpageTest} from './ambient_subpage_element_test.js'; import {GooglePhotosCollectionTest} from './google_photos_collection_element_test.js'; import {GooglePhotosPhotosByAlbumIdTest} from './google_photos_photos_by_album_id_element_test.js'; import {LocalImagesTest} from './local_images_element_test.js'; @@ -12,9 +13,12 @@ import {PersonalizationMainTest} from './personalization_main_element_test.js'; import {PersonalizationRouterTest} from './personalization_router_element_test.js'; import {PersonalizationToastTest} from './personalization_toast_element_test.js'; +import {UserSubpageTest} from './user_subpage_element_test.js'; import {WallpaperCollectionsTest} from './wallpaper_collections_element_test.js'; import {WallpaperFullscreenTest} from './wallpaper_fullscreen_element_test.js'; import {WallpaperImagesTest} from './wallpaper_images_element_test.js'; +import {WallpaperObserverTest} from './wallpaper_observer_test.js'; +import {WallpaperPreviewTest} from './wallpaper_preview_element_test.js'; import {WallpaperSelectedTest} from './wallpaper_selected_element_test.js'; // Mute console.warn during tests. Several tests intentionally hit asserts to @@ -22,6 +26,7 @@ window.console.warn = () => {}; const testCases = [ + AmbientSubpageTest, GooglePhotosCollectionTest, GooglePhotosPhotosByAlbumIdTest, LocalImagesTest, @@ -29,10 +34,13 @@ PersonalizationMainTest, PersonalizationRouterTest, PersonalizationToastTest, + UserSubpageTest, WallpaperCollectionsTest, WallpaperFullscreenTest, WallpaperImagesTest, + WallpaperPreviewTest, WallpaperSelectedTest, + WallpaperObserverTest, ]; for (const testCase of testCases) {
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts similarity index 94% rename from chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.js rename to chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts index bcd5bfb..8447d77 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
@@ -9,7 +9,6 @@ import * as wallpaperAction from 'chrome://personalization/trusted/wallpaper/wallpaper_actions.js'; import {fetchCollections, fetchGooglePhotosAlbum, fetchLocalData, getLocalImages, initializeBackdropData, initializeGooglePhotosData, selectWallpaper} from 'chrome://personalization/trusted/wallpaper/wallpaper_controller.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; - import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestPersonalizationStore} from './test_personalization_store.js'; @@ -17,11 +16,9 @@ /** * Get a sub-property in obj. Splits on '.' - * @param {!Object} obj - * @param {string} key */ -function getProperty(obj, key) { - let ref = obj; +function getProperty(obj: object, key: string): unknown { + let ref: any = obj; for (const part of key.split('.')) { ref = ref[part]; } @@ -30,12 +27,10 @@ /** * Returns a function that returns only nested subproperties in state. - * @param {!Array<string>} keys - * @return {!Function} */ -function filterAndFlattenState(keys) { +function filterAndFlattenState(keys: string[]): (state: any) => any { return (state) => { - const result = {}; + const result: any = {}; for (const key of keys) { result[key] = getProperty(state, key); } @@ -44,8 +39,8 @@ } suite('Personalization app controller', () => { - let wallpaperProvider; - let personalizationStore; + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; setup(() => { wallpaperProvider = new TestWallpaperProvider(); @@ -386,7 +381,7 @@ personalizationStore.reset(personalizationStore.data); // Only keep the first image. - wallpaperProvider.localImages = [wallpaperProvider.localImages[0]]; + wallpaperProvider.localImages = [wallpaperProvider.localImages![0]!]; await fetchLocalData(wallpaperProvider, personalizationStore); assertDeepEquals( @@ -439,7 +434,7 @@ // Subtract image 1 and add NewPath.png. wallpaperProvider.localImages = [ - wallpaperProvider.localImages[0], + wallpaperProvider.localImages![0]!, {path: 'NewPath.png'}, ]; @@ -553,8 +548,8 @@ suite('full screen mode', () => { const fullscreenPreviewFeature = 'fullScreenPreviewEnabled'; - let wallpaperProvider; - let personalizationStore; + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; setup(() => { wallpaperProvider = new TestWallpaperProvider(); @@ -575,12 +570,12 @@ { const selectWallpaperPromise = selectWallpaper( - wallpaperProvider.images[0], wallpaperProvider, + wallpaperProvider.images![0]!, wallpaperProvider, personalizationStore); const [assetId, previewMode] = await wallpaperProvider.whenCalled('selectWallpaper'); assertFalse(previewMode); - assertEquals(wallpaperProvider.images[0].assetId, assetId); + assertEquals(wallpaperProvider.images![0]!.assetId, assetId); await selectWallpaperPromise; @@ -594,13 +589,13 @@ loadTimeData.overrideValues({[fullscreenPreviewFeature]: true}); const selectWallpaperPromise = selectWallpaper( - wallpaperProvider.images[0], wallpaperProvider, + wallpaperProvider.images![0]!, wallpaperProvider, personalizationStore); const [assetId, previewMode] = await wallpaperProvider.whenCalled('selectWallpaper'); assertTrue(previewMode); - assertEquals(wallpaperProvider.images[0].assetId, assetId); + assertEquals(wallpaperProvider.images![0]!.assetId, assetId); await selectWallpaperPromise; @@ -610,8 +605,8 @@ }); suite('observes pendingState during wallpaper selection', () => { - let wallpaperProvider; - let personalizationStore; + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; setup(() => { wallpaperProvider = new TestWallpaperProvider(); @@ -623,21 +618,21 @@ 'sets pendingState to selected image for successful operation', async () => { await selectWallpaper( - wallpaperProvider.images[0], wallpaperProvider, + wallpaperProvider.images![0]!, wallpaperProvider, personalizationStore); assertDeepEquals( [ { name: 'begin_select_image', - image: wallpaperProvider.images[0], + image: wallpaperProvider.images![0], }, { name: 'begin_load_selected_image', }, { name: 'end_select_image', - image: wallpaperProvider.images[0], + image: wallpaperProvider.images![0], success: true, }, { @@ -652,19 +647,19 @@ [ // Begin selecting image. { - 'wallpaper.pendingSelected': wallpaperProvider.images[0], + 'wallpaper.pendingSelected': wallpaperProvider.images![0], }, // Begin loading image. { - 'wallpaper.pendingSelected': wallpaperProvider.images[0], + 'wallpaper.pendingSelected': wallpaperProvider.images![0], }, // End selecting image. { - 'wallpaper.pendingSelected': wallpaperProvider.images[0], + 'wallpaper.pendingSelected': wallpaperProvider.images![0], }, // Set fullscreen enabled { - 'wallpaper.pendingSelected': wallpaperProvider.images[0], + 'wallpaper.pendingSelected': wallpaperProvider.images![0], }, ], personalizationStore.states.map( @@ -675,7 +670,7 @@ 'clears pendingState when error occured and only one request', async () => { await selectWallpaper( - wallpaperProvider.localImages[0], wallpaperProvider, + wallpaperProvider.localImages![0]!, wallpaperProvider, personalizationStore); // Reset the history of actions and prior states, but keep the current // state. @@ -686,7 +681,7 @@ // sets selected image without file path to force fail the operation. wallpaperProvider.localImages = [{path: ''}]; await selectWallpaper( - wallpaperProvider.localImages[0], wallpaperProvider, + wallpaperProvider.localImages[0]!, wallpaperProvider, personalizationStore); assertDeepEquals( @@ -736,8 +731,8 @@ }); suite('local images available but no internet connection', () => { - let wallpaperProvider; - let personalizationStore; + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; setup(() => { wallpaperProvider = new TestWallpaperProvider(); @@ -751,7 +746,7 @@ loadTimeData.overrideValues({['networkError']: 'someError'}); // Set collections to null to simulate collections failure. - wallpaperProvider.setCollections(null); + wallpaperProvider.setCollectionsToFail(); // Assume that collections are loaded before local images. const collectionsPromise =
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.ts similarity index 78% rename from chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.ts index b4e068a0..a531059 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_breadcrumb_element_test.ts
@@ -17,22 +17,18 @@ import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; export function PersonalizationBreadcrumbTest() { - /** @type {?HTMLElement} */ - let breadcrumbElement = null; + let breadcrumbElement: PersonalizationBreadcrumb|null; - /** @type {?TestWallpaperProvider} */ - let wallpaperProvider = null; + let wallpaperProvider: TestWallpaperProvider; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; + let personalizationStore: TestPersonalizationStore; /** * Asserts that the specified |breadcrumbContainer| has children conforming * to the specified |breadcrumbs|, e.g. ["Wallpaper", "Google Photos"]. - * @param {HTMLElement} breadcrumbContainer - * @param {Array<string>} breadcrumbs */ - function assertBreadcrumbs(breadcrumbContainer, breadcrumbs) { + function assertBreadcrumbs( + breadcrumbContainer: HTMLElement, breadcrumbs: string[]) { // Ignore child elements which are not breadcrumbs. const breadcrumbEls = [...breadcrumbContainer.children].filter(child => { return child.classList.contains('breadcrumb'); @@ -44,13 +40,13 @@ const breadcrumb = breadcrumbs[i]; const breadcrumbEl = breadcrumbEls[i]; - assertEquals(breadcrumbEl.textContent, breadcrumb); + assertEquals(breadcrumbEl!.textContent, breadcrumb); if (i < breadcrumbs.length - 1) { // Breadcrumbs are separated by a chevron icon. - const chevronEl = breadcrumbEl.nextElementSibling; - assertEquals(chevronEl.tagName, 'IRON-ICON'); - assertEquals(chevronEl.getAttribute('icon'), 'cr:chevron-right'); + const chevronEl = breadcrumbEl!.nextElementSibling; + assertEquals(chevronEl!.tagName, 'IRON-ICON'); + assertEquals(chevronEl!.getAttribute('icon'), 'cr:chevron-right'); } } } @@ -73,16 +69,16 @@ breadcrumbElement = initElement(PersonalizationBreadcrumb); const breadcrumbContainer = - breadcrumbElement.shadowRoot.getElementById('breadcrumbContainer'); + breadcrumbElement.shadowRoot!.getElementById('breadcrumbContainer'); assertTrue(!!breadcrumbContainer && !breadcrumbContainer.hidden); - assertBreadcrumbs(breadcrumbContainer, [breadcrumbElement.i18n('title')]); + assertBreadcrumbs(breadcrumbContainer!, [breadcrumbElement.i18n('title')]); }); test('shows collection name when collection is selected', async () => { - const collection = wallpaperProvider.collections[0]; + const collection = wallpaperProvider.collections![0]; breadcrumbElement = initElement( PersonalizationBreadcrumb, - {'path': Paths.CollectionImages, 'collectionId': collection.id}); + {'path': Paths.CollectionImages, 'collectionId': collection!.id}); personalizationStore.data.wallpaper.backdrop.collections = wallpaperProvider.collections; @@ -91,11 +87,11 @@ await waitAfterNextRender(breadcrumbElement); const breadcrumbContainer = - breadcrumbElement.shadowRoot.getElementById('breadcrumbContainer'); + breadcrumbElement.shadowRoot!.getElementById('breadcrumbContainer'); assertTrue(!!breadcrumbContainer && !breadcrumbContainer.hidden); assertBreadcrumbs( - breadcrumbContainer, - [breadcrumbElement.i18n('title'), collection.name]); + breadcrumbContainer!, + [breadcrumbElement.i18n('title'), collection!.name]); }); test('show album name when Google Photos subpage is loaded', async () => { @@ -117,9 +113,9 @@ }); const breadcrumbContainer = - breadcrumbElement.shadowRoot.getElementById('breadcrumbContainer'); + breadcrumbElement.shadowRoot!.getElementById('breadcrumbContainer'); assertTrue(!!breadcrumbContainer && !breadcrumbContainer.hidden); - assertBreadcrumbs(breadcrumbContainer, [ + assertBreadcrumbs(breadcrumbContainer!, [ breadcrumbElement.i18n('title'), breadcrumbElement.i18n('googlePhotosLabel'), googlePhotosAlbum.name ]); @@ -134,9 +130,9 @@ PersonalizationBreadcrumb, {'path': Paths.GooglePhotosCollection}); const breadcrumbContainer = - breadcrumbElement.shadowRoot.getElementById('breadcrumbContainer'); + breadcrumbElement.shadowRoot!.getElementById('breadcrumbContainer'); assertTrue(!!breadcrumbContainer && !breadcrumbContainer.hidden); - assertBreadcrumbs(breadcrumbContainer, [ + assertBreadcrumbs(breadcrumbContainer!, [ breadcrumbElement.i18n('title'), breadcrumbElement.i18n('googlePhotosLabel') ]); @@ -153,9 +149,9 @@ await waitAfterNextRender(breadcrumbElement); const breadcrumbContainer = - breadcrumbElement.shadowRoot.getElementById('breadcrumbContainer'); + breadcrumbElement.shadowRoot!.getElementById('breadcrumbContainer'); assertTrue(!!breadcrumbContainer && !breadcrumbContainer.hidden); - assertBreadcrumbs(breadcrumbContainer, [ + assertBreadcrumbs(breadcrumbContainer!, [ breadcrumbElement.i18n('title'), breadcrumbElement.i18n('myImagesLabel') ]); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.js deleted file mode 100644 index c575d8a..0000000 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.js +++ /dev/null
@@ -1,40 +0,0 @@ -// 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 {PersonalizationMain} from 'chrome://personalization/trusted/personalization_main_element.js'; - -import {assertEquals} from 'chrome://webui-test/chai_assert.js'; - -import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js'; -import {TestPersonalizationStore} from './test_personalization_store.js'; -import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; - -export function PersonalizationMainTest() { - /** @type {?HTMLElement} */ - let personalizationMainElement = null; - - /** @type {?TestWallpaperProvider} */ - let wallpaperProvider = null; - - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; - - setup(function() { - const mocks = baseSetup(); - wallpaperProvider = mocks.wallpaperProvider; - personalizationStore = mocks.personalizationStore; - }); - - teardown(async () => { - await teardownElement(personalizationMainElement); - personalizationMainElement = null; - }); - - test('displays content', async () => { - personalizationMainElement = initElement(PersonalizationMain); - assertEquals( - 'Personalization', - personalizationMainElement.shadowRoot.querySelector('h1').innerText); - }); -}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.ts new file mode 100644 index 0000000..9be7815 --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_main_element_test.ts
@@ -0,0 +1,27 @@ +// 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 {PersonalizationMain} from 'chrome://personalization/trusted/personalization_main_element.js'; + +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; + +import {initElement, teardownElement} from './personalization_app_test_utils.js'; + +export function PersonalizationMainTest() { + let personalizationMainElement: PersonalizationMain|null; + + setup(function() {}); + + teardown(async () => { + await teardownElement(personalizationMainElement); + personalizationMainElement = null; + }); + + test('displays content', async () => { + personalizationMainElement = initElement(PersonalizationMain); + assertEquals( + 'Personalization', + personalizationMainElement.shadowRoot!.querySelector('h1')!.innerText); + }); +}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts similarity index 83% rename from chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts index 4b7f8e7..b7bbbdc 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts
@@ -12,11 +12,9 @@ import {TestPersonalizationStore} from './test_personalization_store.js'; export function PersonalizationToastTest() { - /** @type {!HTMLElement} */ - let personalizationToastElement; + let personalizationToastElement: PersonalizationToastElement; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; + let personalizationStore: TestPersonalizationStore; setup(() => { const mocks = baseSetup(); @@ -38,10 +36,10 @@ personalizationStore.notifyObservers(); await waitAfterNextRender(personalizationToastElement); assertTrue( - !!personalizationToastElement.shadowRoot.getElementById('container')); + !!personalizationToastElement.shadowRoot!.getElementById('container')); assertEquals( personalizationStore.data.error, - personalizationToastElement.shadowRoot.querySelector('p').innerText); + personalizationToastElement.shadowRoot!.querySelector('p')!.innerText); }); test('deploys an dismiss action when dismiss is clicked', async () => { @@ -50,7 +48,7 @@ await waitAfterNextRender(personalizationToastElement); personalizationStore.expectAction(PersonalizationActionName.DISMISS_ERROR); - personalizationToastElement.shadowRoot.querySelector('cr-button').click(); + personalizationToastElement.shadowRoot!.querySelector('cr-button')!.click(); await personalizationStore.waitForAction( PersonalizationActionName.DISMISS_ERROR); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.js b/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts similarity index 73% rename from chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.js rename to chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts index a10f2db9..508ecf2c 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.js +++ b/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts
@@ -5,22 +5,30 @@ /** * @fileoverview a mock store for personalization app. Use to monitor actions * and manipulate state. - * - * Skip type-checks for this file because ../../test_store.js is not properly - * typed. - * @suppress {checkTypes} */ import {reduce} from 'chrome://personalization/trusted/personalization_reducers.js'; import {emptyState} from 'chrome://personalization/trusted/personalization_state.js'; import {PersonalizationStore} from 'chrome://personalization/trusted/personalization_store.js'; +import {Action} from 'chrome://resources/js/cr/ui/store.js'; import {TestStore} from 'chrome://webui-test/test_store.js'; export class TestPersonalizationStore extends TestStore { - constructor(data) { + // received actions and states. + private actions_: Action[]; + private states_: any[]; + + constructor(data: any) { super(data, PersonalizationStore, emptyState(), reduce); this.actions_ = []; this.states_ = []; + + // manually override `reduce_` method because it's private. + this['reduce_'] = (action: Action) => { + super['reduce_'](action); + this.actions_.push(action); + this.states_.push(this.data); + }; } get actions() { @@ -31,18 +39,10 @@ return this.states_; } - /** @override */ replaceSingleton() { PersonalizationStore.setInstance(this); } - /** @override */ - reduce_(action) { - super.reduce_(action); - this.actions_.push(action); - this.states_.push(this.data); - } - reset(data = {}) { this.data = Object.assign(emptyState(), data); this.resetLastAction();
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts index 8564f043..eae7b91 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
@@ -95,7 +95,7 @@ private collections_: WallpaperCollection[]|null; private images_: WallpaperImage[]|null; - localImages: FilePath[]; + localImages: FilePath[]|null; localImageData: Record<string, string>; currentWallpaper: CurrentWallpaper; selectWallpaperResponse = true;
diff --git a/chrome/test/data/webui/chromeos/personalization_app/user_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/user_subpage_element_test.ts new file mode 100644 index 0000000..84655a4 --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/user_subpage_element_test.ts
@@ -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. + +import {UserSubpage} from 'chrome://personalization/trusted/user/user_subpage_element.js'; + +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; + +import {initElement, teardownElement} from './personalization_app_test_utils.js'; + +export function UserSubpageTest() { + let userSubpageElement: UserSubpage|null; + + setup(function() {}); + + teardown(async () => { + await teardownElement(userSubpageElement); + userSubpageElement = null; + }); + + test('displays content', async () => { + userSubpageElement = initElement(UserSubpage); + assertEquals( + 'User', userSubpageElement.shadowRoot!.querySelector('h2')!.innerText); + }); +}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.js b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts similarity index 75% rename from chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.js rename to chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts index 8cd2d336..bb3c089 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.js +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts
@@ -3,9 +3,11 @@ // found in the LICENSE file. import {kMaximumGooglePhotosPreviews, kMaximumLocalImagePreviews} from 'chrome://personalization/common/constants.js'; +import {WallpaperCollection} from 'chrome://personalization/trusted/personalization_app.mojom-webui.js'; import {emptyState} from 'chrome://personalization/trusted/personalization_state.js'; import {promisifyIframeFunctionsForTesting, WallpaperCollections} from 'chrome://personalization/trusted/wallpaper/wallpaper_collections_element.js'; - +import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; @@ -14,14 +16,11 @@ import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; export function WallpaperCollectionsTest() { - /** @type {?HTMLElement} */ - let wallpaperCollectionsElement = null; + let wallpaperCollectionsElement: WallpaperCollections|null = null; - /** @type {?TestWallpaperProvider} */ - let wallpaperProvider = null; + let wallpaperProvider: TestWallpaperProvider; - /** @type {?TestPersonalizationStore} */ - let personalizationStore = null; + let personalizationStore: TestPersonalizationStore; setup(function() { const mocks = baseSetup(); @@ -48,15 +47,17 @@ personalizationStore.notifyObservers(); // Wait for |sendCollections| to be called. - const [target, data] = await sendCollectionsPromise; + const [target, data] = await ( + sendCollectionsPromise as + Promise<[Window, Array<WallpaperCollection>]>); await waitAfterNextRender(wallpaperCollectionsElement); const iframe = - wallpaperCollectionsElement.shadowRoot.querySelector('iframe'); - assertFalse(iframe.hidden); + wallpaperCollectionsElement.shadowRoot!.querySelector('iframe'); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); - assertDeepEquals(wallpaperProvider.collections, data); + assertWindowObjectsEqual(iframe!.contentWindow, target); + assertDeepEquals(wallpaperProvider!.collections, data); }); test('sends Google Photos count when loaded', async () => { @@ -70,14 +71,15 @@ personalizationStore.notifyObservers(); // Wait for |sendGooglePhotosCount| to be called. - const [target, data] = await sendGooglePhotosCountPromise; + const [target, data] = await ( + sendGooglePhotosCountPromise as Promise<[Window, number | null]>); await waitAfterNextRender(wallpaperCollectionsElement); const iframe = - wallpaperCollectionsElement.shadowRoot.querySelector('iframe'); - assertFalse(iframe.hidden); + wallpaperCollectionsElement.shadowRoot!.querySelector('iframe'); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); + assertWindowObjectsEqual(iframe!.contentWindow, target); assertDeepEquals( personalizationStore.data.wallpaper.googlePhotos.count, data); }); @@ -95,14 +97,15 @@ personalizationStore.notifyObservers(); // Wait for |sendGooglePhotosPhotos| to be called. - const [target, data] = await sendGooglePhotosPhotosPromise; + const [target, data] = await ( + sendGooglePhotosPhotosPromise as Promise<[Window, Array<Url>| null]>); await waitAfterNextRender(wallpaperCollectionsElement); const iframe = - wallpaperCollectionsElement.shadowRoot.querySelector('iframe'); - assertFalse(iframe.hidden); + wallpaperCollectionsElement.shadowRoot!.querySelector('iframe'); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); + assertWindowObjectsEqual(iframe!.contentWindow, target); assertDeepEquals( personalizationStore.data.wallpaper.googlePhotos.photos.slice( 0, kMaximumGooglePhotosPreviews), @@ -128,23 +131,25 @@ promisifyIframeFunctionsForTesting(); personalizationStore.data.wallpaper.backdrop.images = { - 'id_0': [wallpaperProvider.images[0]] + 'id_0': [wallpaperProvider.images![0]] }; personalizationStore.data.wallpaper.loading.images = {'id_0': false}; personalizationStore.notifyObservers(); - let counts = (await sendImageCountsPromise)[1]; + let counts = (await ( + sendImageCountsPromise as + Promise<[Window, {[key: string]: number | null}]>))[1]; assertDeepEquals({'id_0': 1}, counts); // Load two collections in at once, and simulate one failure. sendImageCountsPromise = promisifyIframeFunctionsForTesting().sendImageCounts; personalizationStore.data.wallpaper.backdrop.images = { - 'id_0': [wallpaperProvider.images[0]], - 'id_1': [wallpaperProvider.images[0], wallpaperProvider.images[1]], + 'id_0': [wallpaperProvider.images![0]], + 'id_1': [wallpaperProvider.images![0], wallpaperProvider.images![1]], 'id_2': [], 'id_3': null, - 'id_4': [wallpaperProvider.images[0], wallpaperProvider.images[2]], + 'id_4': [wallpaperProvider.images![0], wallpaperProvider.images![2]], }; personalizationStore.data.wallpaper.loading.images = { 'id_0': false, @@ -155,7 +160,9 @@ }; personalizationStore.notifyObservers(); - counts = (await sendImageCountsPromise)[1]; + counts = (await ( + sendImageCountsPromise as + Promise<[Window, {[key: string]: number | null}]>))[1]; assertDeepEquals( {'id_0': 1, 'id_1': 2, 'id_2': 0, 'id_3': null, 'id_4': 1}, counts); }); @@ -178,14 +185,15 @@ personalizationStore.notifyObservers(); // Wait for |sendLocalImages| to be called. - const [target, data] = await sendLocalImagesPromise; + const [target, data] = + await (sendLocalImagesPromise as Promise<[Window, FilePath[]]>); await waitAfterNextRender(wallpaperCollectionsElement); const iframe = - wallpaperCollectionsElement.shadowRoot.querySelector('iframe'); - assertFalse(iframe.hidden); + wallpaperCollectionsElement.shadowRoot!.querySelector('iframe'); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); + assertWindowObjectsEqual(iframe!.contentWindow, target); assertDeepEquals(wallpaperProvider.localImages, data); }); @@ -209,32 +217,35 @@ personalizationStore.notifyObservers(); // Wait for |sendCollections| to be called. - let [target, data] = await sendCollectionsPromise; + let [target, data] = await ( + sendCollectionsPromise as + Promise<[Window, Array<WallpaperCollection>]>); await waitAfterNextRender(wallpaperCollectionsElement); const iframe = - wallpaperCollectionsElement.shadowRoot.querySelector('iframe'); - assertFalse(iframe.hidden); + wallpaperCollectionsElement.shadowRoot!.querySelector('iframe'); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); + assertWindowObjectsEqual(iframe!.contentWindow, target); assertEquals(null, data); // Wait for |sendLocalImages| to be called. - [target, data] = await sendLocalImagesPromise; + let [imageTarget, imageData] = + await (sendLocalImagesPromise as Promise<[Window, FilePath[]]>); await waitAfterNextRender(wallpaperCollectionsElement); - assertFalse(iframe.hidden); + assertFalse(iframe!.hidden); - assertWindowObjectsEqual(iframe.contentWindow, target); - assertDeepEquals(wallpaperProvider.localImages, data); + assertWindowObjectsEqual(iframe!.contentWindow, imageTarget); + assertDeepEquals(wallpaperProvider.localImages, imageData); }); test('shows error when fails to load', async () => { wallpaperCollectionsElement = initElement(WallpaperCollections); // No error displayed while loading. - let error = - wallpaperCollectionsElement.shadowRoot.querySelector('wallpaper-error'); + let error = wallpaperCollectionsElement.shadowRoot!.querySelector( + 'wallpaper-error'); assertTrue(error === null); personalizationStore.data.wallpaper.loading = { @@ -247,13 +258,13 @@ personalizationStore.notifyObservers(); await waitAfterNextRender(wallpaperCollectionsElement); - error = - wallpaperCollectionsElement.shadowRoot.querySelector('wallpaper-error'); + error = wallpaperCollectionsElement.shadowRoot!.querySelector( + 'wallpaper-error'); assertTrue(!!error); // Iframe should be hidden if there is an error. - assertTrue( - wallpaperCollectionsElement.shadowRoot.querySelector('iframe').hidden); + assertTrue(wallpaperCollectionsElement.shadowRoot!.querySelector( + 'iframe')!.hidden); }); test('loads backdrop data and saves to store', async () => { @@ -267,7 +278,9 @@ wallpaperCollectionsElement = initElement(WallpaperCollections); - const [_, collections] = await sendCollectionsPromise; + const [_, collections] = await ( + sendCollectionsPromise as + Promise<[Window, Array<WallpaperCollection>]>); assertDeepEquals(wallpaperProvider.collections, collections); assertDeepEquals( @@ -318,7 +331,7 @@ await sendLocalImages; // No thumbnails loaded so none sent. - assertFalse(wallpaperCollectionsElement.didSendLocalImageData_); + assertFalse(wallpaperCollectionsElement['didSendLocalImageData_']); // First thumbnail loads in. personalizationStore.data.wallpaper.loading.local.data = { @@ -329,12 +342,12 @@ }; personalizationStore.notifyObservers(); - await wallpaperCollectionsElement.iframePromise_; + await wallpaperCollectionsElement['iframePromise_']; await waitAfterNextRender(wallpaperCollectionsElement); // Should not have sent any image data since more thumbnails are still // loading. - assertFalse(wallpaperCollectionsElement.didSendLocalImageData_); + assertFalse(wallpaperCollectionsElement['didSendLocalImageData_']); // Second thumbnail fails loading. Third succeeds. personalizationStore.data.wallpaper.loading.local.data = { @@ -351,9 +364,10 @@ // 2 thumbnails have now loaded. 1 failed. But there are no more // remaining to try loading, should send local image data anyway. - const [_, sentData] = await sendLocalImageData; + const [_, sentData] = await ( + sendLocalImageData as Promise<[Window, Record<string, string>]>); - assertTrue(wallpaperCollectionsElement.didSendLocalImageData_); + assertTrue(wallpaperCollectionsElement['didSendLocalImageData_']); assertDeepEquals( { 'LocalImage0.png': 'local_data_0',
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_observer_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_observer_test.ts new file mode 100644 index 0000000..e9c28f03 --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_observer_test.ts
@@ -0,0 +1,77 @@ +// 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 {emptyState} from 'chrome://personalization/trusted/personalization_state.js'; +import {WallpaperActionName} from 'chrome://personalization/trusted/wallpaper/wallpaper_actions.js'; +import {WallpaperObserver} from 'chrome://personalization/trusted/wallpaper/wallpaper_observer.js'; +import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js'; + +import {baseSetup} from './personalization_app_test_utils.js'; +import {TestPersonalizationStore} from './test_personalization_store.js'; +import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; + +export function WallpaperObserverTest() { + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; + + setup(() => { + const mocks = baseSetup(); + wallpaperProvider = mocks.wallpaperProvider; + personalizationStore = mocks.personalizationStore; + WallpaperObserver.initWallpaperObserverIfNeeded(); + }); + + teardown(() => { + WallpaperObserver.shutdown(); + }); + + test('sets wallpaper image in store on first load', async () => { + personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); + const action = await personalizationStore.waitForAction( + WallpaperActionName.SET_SELECTED_IMAGE); + assertDeepEquals(wallpaperProvider.currentWallpaper, action.image); + }); + + test('sets selected wallpaper data in store on changed', async () => { + // Make sure state starts as expected. + assertDeepEquals(emptyState(), personalizationStore.data); + + personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); + wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( + wallpaperProvider.currentWallpaper); + + const {image} = await personalizationStore.waitForAction( + WallpaperActionName.SET_SELECTED_IMAGE); + + assertDeepEquals(wallpaperProvider.currentWallpaper, image); + }); + + test('skips updating OnWallpaperChange while in fullscreen', async () => { + personalizationStore.data.wallpaper.fullscreen = true; + + personalizationStore.resetLastAction(); + + wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( + wallpaperProvider.currentWallpaper); + + assertEquals(null, personalizationStore.lastAction); + + personalizationStore.data.wallpaper.fullscreen = false; + personalizationStore.notifyObservers(); + + personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); + + wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( + wallpaperProvider.currentWallpaper); + + const action = await personalizationStore.waitForAction( + WallpaperActionName.SET_SELECTED_IMAGE); + + assertDeepEquals( + { + name: WallpaperActionName.SET_SELECTED_IMAGE, + image: wallpaperProvider.currentWallpaper, + }, + action); + }); +} \ No newline at end of file
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_preview_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_preview_element_test.ts new file mode 100644 index 0000000..8553804e --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_preview_element_test.ts
@@ -0,0 +1,118 @@ +// 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 wallpaper-preview component. */ + +import {WallpaperPreview} from 'chrome://personalization/trusted/wallpaper/wallpaper_preview_element.js'; + +import {assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; + +import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/test_util.js'; + +import {baseSetup, initElement} from './personalization_app_test_utils.js'; +import {TestPersonalizationStore} from './test_personalization_store.js'; +import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; + +export function WallpaperPreviewTest() { + let wallpaperPreviewElement: WallpaperPreview|null; + let wallpaperProvider: TestWallpaperProvider; + let personalizationStore: TestPersonalizationStore; + + setup(() => { + const mocks = baseSetup(); + wallpaperProvider = mocks.wallpaperProvider; + personalizationStore = mocks.personalizationStore; + }); + + teardown(async () => { + if (wallpaperPreviewElement) { + wallpaperPreviewElement.remove(); + } + wallpaperPreviewElement = null; + await flushTasks(); + }); + + test( + 'shows loading placeholder when there are in-flight requests', + async () => { + personalizationStore.data.wallpaper.loading = { + ...personalizationStore.data.wallpaper.loading, + selected: 1, + setImage: 0, + }; + wallpaperPreviewElement = initElement(WallpaperPreview); + + assertEquals( + null, wallpaperPreviewElement.shadowRoot!.querySelector('img')); + + const placeholder = wallpaperPreviewElement.shadowRoot!.getElementById( + 'imagePlaceholder'); + + assertTrue(!!placeholder); + + // Loading placeholder should be hidden. + personalizationStore.data.wallpaper.loading = { + ...personalizationStore.data.wallpaper.loading, + selected: 0, + setImage: 0, + }; + personalizationStore.data.wallpaper.currentSelected = + wallpaperProvider.currentWallpaper; + personalizationStore.notifyObservers(); + await waitAfterNextRender(wallpaperPreviewElement); + + assertEquals('none', placeholder!.style.display); + + // Sent a request to update user wallpaper. Loading placeholder should + // come back. + personalizationStore.data.wallpaper.loading = { + ...personalizationStore.data.wallpaper.loading, + selected: 0, + setImage: 1, + }; + personalizationStore.notifyObservers(); + await waitAfterNextRender(wallpaperPreviewElement); + + assertEquals('', placeholder!.style.display); + }); + + test('shows wallpaper image when loaded', async () => { + personalizationStore.data.wallpaper.currentSelected = + wallpaperProvider.currentWallpaper; + + wallpaperPreviewElement = initElement(WallpaperPreview); + await waitAfterNextRender(wallpaperPreviewElement); + + const img = wallpaperPreviewElement.shadowRoot!.querySelector('img'); + assertEquals( + `chrome://image/?${wallpaperProvider.currentWallpaper.url.url}`, + img!.src); + }); + + test('shows placeholders when image fails to load', async () => { + wallpaperPreviewElement = initElement(WallpaperPreview); + await waitAfterNextRender(wallpaperPreviewElement); + + // Still loading. + personalizationStore.data.wallpaper.loading.selected = true; + personalizationStore.data.wallpaper.currentSelected = null; + personalizationStore.notifyObservers(); + await waitAfterNextRender(wallpaperPreviewElement); + + const placeholder = + wallpaperPreviewElement.shadowRoot!.getElementById('imagePlaceholder'); + assertTrue(!!placeholder); + + // Loading finished and still no current wallpaper. + personalizationStore.data.wallpaper.loading.selected = false; + personalizationStore.notifyObservers(); + await waitAfterNextRender(wallpaperPreviewElement); + + // Dom-if will set display: none if the element is hidden. Make sure it is + // not hidden. + assertNotEquals('none', placeholder!.style.display); + assertEquals( + null, wallpaperPreviewElement.shadowRoot!.querySelector('img')); + }); +} \ No newline at end of file
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts index e00b3b7e..6603c399 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts
@@ -5,11 +5,10 @@ /** @fileoverview Test suite for wallpaper-selected component. */ import {Paths} from 'chrome://personalization/trusted/personalization_router_element.js'; -import {emptyState} from 'chrome://personalization/trusted/personalization_state.js'; -import {WallpaperActionName} from 'chrome://personalization/trusted/wallpaper/wallpaper_actions.js'; -import {mockTimeoutForTesting, WallpaperSelected} from 'chrome://personalization/trusted/wallpaper/wallpaper_selected_element.js'; +import {WallpaperSelected} from 'chrome://personalization/trusted/wallpaper/wallpaper_selected_element.js'; -import {assertDeepEquals, assertEquals, assertFalse, assertNotEquals, assertNotReached, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; + import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/test_util.js'; import {baseSetup, initElement} from './personalization_app_test_utils.js'; @@ -84,21 +83,13 @@ assertEquals('', placeholder!.style.display); }); - test('sets wallpaper image in store on first load', async () => { - personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); - wallpaperSelectedElement = initElement(WallpaperSelected); - const action = await personalizationStore.waitForAction( - WallpaperActionName.SET_SELECTED_IMAGE); - assertDeepEquals(wallpaperProvider.currentWallpaper, action.image); - }); - test('shows wallpaper image and attribution when loaded', async () => { personalizationStore.data.wallpaper.currentSelected = wallpaperProvider.currentWallpaper; wallpaperSelectedElement = initElement(WallpaperSelected); await waitAfterNextRender(wallpaperSelectedElement); - + const img = wallpaperSelectedElement.shadowRoot!.querySelector('img'); assertEquals( `chrome://image/?${wallpaperProvider.currentWallpaper.url.url}`, @@ -209,24 +200,6 @@ null, wallpaperSelectedElement.shadowRoot!.querySelector('img')); }); - test('sets selected wallpaper data in store on changed', async () => { - // Make sure state starts as expected. - assertDeepEquals(emptyState(), personalizationStore.data); - - wallpaperSelectedElement = initElement(WallpaperSelected); - - await wallpaperProvider.whenCalled('setWallpaperObserver'); - - personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); - wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( - wallpaperProvider.currentWallpaper); - - const {image} = await personalizationStore.waitForAction( - WallpaperActionName.SET_SELECTED_IMAGE); - - assertDeepEquals(wallpaperProvider.currentWallpaper, image); - }); - test('shows image url with data scheme', async () => { personalizationStore.data.wallpaper.currentSelected = { url: {url: 'data:image/png;base64,abc='}, @@ -288,90 +261,4 @@ 'refreshWallpaper'); assertFalse(newRefreshWallpaper!.hidden); }); - - test('sets current image to null after timeout', async () => { - let timeoutCallback: Function; - mockTimeoutForTesting({ - setTimeout(callback, delay) { - assertEquals(120 * 1000, delay); - timeoutCallback = callback as Function; - return 1234; - }, - clearTimeout() { - assertNotReached('Should not clear timeout'); - }, - }); - - wallpaperProvider.wallpaperObserverUpdateTimeout = 100; - - wallpaperSelectedElement = - initElement(WallpaperSelected, {'path': Paths.CollectionImages}); - await waitAfterNextRender(wallpaperSelectedElement); - - personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); - - timeoutCallback!.call(wallpaperSelectedElement); - - const action = await personalizationStore.waitForAction( - WallpaperActionName.SET_SELECTED_IMAGE); - assertEquals(null, action.image); - }); - - test('cancels timeout after receiving first image', async () => { - const timeoutId = 1234; - const clearTimeoutPromise = new Promise<void>(resolve => { - mockTimeoutForTesting({ - setTimeout() { - return timeoutId; - }, - clearTimeout(id) { - assertEquals(timeoutId, id); - resolve(); - }, - }); - }); - - wallpaperSelectedElement = - initElement(WallpaperSelected, {'path': Paths.CollectionImages}); - await waitAfterNextRender(wallpaperSelectedElement); - - wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( - wallpaperProvider.currentWallpaper); - - await clearTimeoutPromise; - }); - - test('skips updating OnWallpaperChange while in fullscreen', async () => { - personalizationStore.data.wallpaper.fullscreen = true; - - wallpaperSelectedElement = - initElement(WallpaperSelected, {'path': Paths.CollectionImages}); - await waitAfterNextRender(wallpaperSelectedElement); - - personalizationStore.resetLastAction(); - - wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( - wallpaperProvider.currentWallpaper); - await waitAfterNextRender(wallpaperSelectedElement); - - assertEquals(null, personalizationStore.lastAction); - - personalizationStore.data.wallpaper.fullscreen = false; - personalizationStore.notifyObservers(); - - personalizationStore.expectAction(WallpaperActionName.SET_SELECTED_IMAGE); - - wallpaperProvider.wallpaperObserverRemote!.onWallpaperChanged( - wallpaperProvider.currentWallpaper); - - const action = await personalizationStore.waitForAction( - WallpaperActionName.SET_SELECTED_IMAGE); - - assertDeepEquals( - { - name: WallpaperActionName.SET_SELECTED_IMAGE, - image: wallpaperProvider.currentWallpaper, - }, - action); - }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/fake_shimless_rma_service_test.js b/chrome/test/data/webui/chromeos/shimless_rma/fake_shimless_rma_service_test.js index 7970d7b..20a6458 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/fake_shimless_rma_service_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/fake_shimless_rma_service_test.js
@@ -281,10 +281,10 @@ }); test('SetGetRsuDisableWriteProtectChallengeResultUpdatesResult', () => { - let expected_challenge = '9876543210'; - service.setGetRsuDisableWriteProtectChallengeResult(expected_challenge); + let expectedChallenge = '9876543210'; + service.setGetRsuDisableWriteProtectChallengeResult(expectedChallenge); return service.getRsuDisableWriteProtectChallenge().then((challenge) => { - assertEquals(challenge.challenge, expected_challenge); + assertEquals(challenge.challenge, expectedChallenge); }); }); @@ -321,7 +321,7 @@ }); test('SetGetComponentListResultUpdatesResult', () => { - let expected_components = [ + let expectedComponents = [ { component: ComponentType.kKeyboard, state: ComponentRepairStatus.kOriginal @@ -331,9 +331,9 @@ state: ComponentRepairStatus.kMissing }, ]; - service.setGetComponentListResult(expected_components); + service.setGetComponentListResult(expectedComponents); return service.getComponentList().then((components) => { - assertDeepEquals(components.components, expected_components); + assertDeepEquals(components.components, expectedComponents); }); }); @@ -493,10 +493,10 @@ }); test('SetGetOriginalSerialNumberResultUpdatesResult', () => { - let expected_serial_number = '123456789'; - service.setGetOriginalSerialNumberResult(expected_serial_number); - return service.getOriginalSerialNumber().then((serial_number) => { - assertEquals(serial_number.serialNumber, expected_serial_number); + let expectedSerialNumber = '123456789'; + service.setGetOriginalSerialNumberResult(expectedSerialNumber); + return service.getOriginalSerialNumber().then((serialNumber) => { + assertEquals(serialNumber.serialNumber, expectedSerialNumber); }); }); @@ -507,10 +507,10 @@ }); test('SetGetOriginalRegionResultUpdatesResult', () => { - let expected_region = 1; - service.setGetOriginalRegionResult(expected_region); + let expectedRegion = 1; + service.setGetOriginalRegionResult(expectedRegion); return service.getOriginalRegion().then((region) => { - assertEquals(region.regionIndex, expected_region); + assertEquals(region.regionIndex, expectedRegion); }); }); @@ -521,10 +521,10 @@ }); test('SetGetOriginalSkuResultUpdatesResult', () => { - let expected_sku = 1; - service.setGetOriginalSkuResult(expected_sku); + let expectedSku = 1; + service.setGetOriginalSkuResult(expectedSku); return service.getOriginalSku().then((sku) => { - assertEquals(sku.skuIndex, expected_sku); + assertEquals(sku.skuIndex, expectedSku); }); }); @@ -534,11 +534,25 @@ }); }); - test('SetGetOriginalRegionResultUpdatesResult', () => { - const expected_whiteLabel = 1; - service.setGetOriginalWhiteLabelResult(expected_whiteLabel); + test('SetGetOriginalWhiteLabelResultUpdatesResult', () => { + const expectedWhiteLabel = 1; + service.setGetOriginalWhiteLabelResult(expectedWhiteLabel); return service.getOriginalWhiteLabel().then((whiteLabel) => { - assertEquals(whiteLabel.whiteLabelIndex, expected_whiteLabel); + assertEquals(whiteLabel.whiteLabelIndex, expectedWhiteLabel); + }); + }); + + test('GetOriginalDramPartNumberDefaultUndefined', () => { + return service.getOriginalDramPartNumber().then((dramPartNumber) => { + assertEquals(dramPartNumber, undefined); + }); + }); + + test('SetGetOriginalDramPartNumberResultUpdatesResult', () => { + const expectedDramPartNumber = '123-456-789'; + service.setGetOriginalDramPartNumberResult(expectedDramPartNumber); + return service.getOriginalDramPartNumber().then((dramPartNumber) => { + assertEquals(dramPartNumber.dramPartNumber, expectedDramPartNumber); }); }); @@ -549,7 +563,7 @@ ]; service.setStates(states); - return service.setDeviceInformation('serial number', 1, 2, 3) + return service.setDeviceInformation('serial number', 1, 2, 3, '123-456-789') .then((state) => { assertEquals(state.state, State.kChooseDestination); assertEquals(state.error, RmadErrorCode.kOk); @@ -920,12 +934,12 @@ * Implements * HardwareVerificationStatusObserverRemote. * onHardwareVerificationResult() - * @param {boolean} is_compliant - * @param {string} error_message + * @param {boolean} isCompliant + * @param {string} errorMessage */ - onHardwareVerificationResult(is_compliant, error_message) { - assertEquals(true, is_compliant); - assertEquals('ok', error_message); + onHardwareVerificationResult(isCompliant, errorMessage) { + assertEquals(true, isCompliant); + assertEquals('ok', errorMessage); } }); service.observeHardwareVerificationStatus(observer);
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_destination_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_destination_page_test.js index 0f77da0b..a80547af 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_destination_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_destination_page_test.js
@@ -106,4 +106,14 @@ assertEquals(component.onNextButtonClick(), resolver.promise); }); + + test('ChooseDestinationPageDisabledRadioGroup', async () => { + await initializeChooseDestinationPage(); + + const chooseDestinationGroup = + component.shadowRoot.querySelector('#chooseDestinationGroup'); + assertFalse(chooseDestinationGroup.disabled); + component.allButtonsDisabled = true; + assertTrue(chooseDestinationGroup.disabled); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_wp_disable_method_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_wp_disable_method_page_test.js index cb525732..6d97925 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_wp_disable_method_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_choose_wp_disable_method_page_test.js
@@ -129,4 +129,14 @@ assertEquals(callCounter, 1); assertDeepEquals(savedResult, expectedResult); }); + + test('ChooseWpDisableMethodDisableRadioGroup', async () => { + await initializeChooseWpDisableMethodPage(); + + const hwwpDisableMethodGroup = + component.shadowRoot.querySelector('#hwwpDisableMethod'); + assertFalse(hwwpDisableMethodGroup.disabled); + component.allButtonsDisabled = true; + assertTrue(hwwpDisableMethodGroup.disabled); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js index 1d49f83..fc55339 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js
@@ -117,4 +117,21 @@ component.shadowRoot.querySelector('#rsuCodeDialogLink').click(); assertTrue(component.shadowRoot.querySelector('#rsuChallengeDialog').open); }); + + test('EnterRsuWpDisableCodePageDisableInput', async () => { + await initializeEnterRsuWpDisableCodePage('', ''); + + const rsuCodeInput = component.shadowRoot.querySelector('#rsuCode'); + assertFalse(rsuCodeInput.disabled); + component.allButtonsDisabled = true; + assertTrue(rsuCodeInput.disabled); + }); + + test('EnterRsuWpDisableCodePageStopChallengeDialogOpening', async () => { + await initializeEnterRsuWpDisableCodePage('', ''); + + component.allButtonsDisabled = true; + component.shadowRoot.querySelector('#rsuCodeDialogLink').click(); + assertFalse(component.shadowRoot.querySelector('#rsuChallengeDialog').open); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_device_information_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_device_information_page_test.js index 0a32e39..7d5e585 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_device_information_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_device_information_page_test.js
@@ -11,6 +11,7 @@ import {flushTasks} from '../../test_util.js'; let fakeSerialNumber = 'serial# 0001'; +let fakeDramPartNumber = 'dram# 0123'; // TODO(gavindodd) how to update selectedIndex and trigger on-change // automatically. @@ -48,19 +49,17 @@ service.reset(); }); - /** - * @param {string} serialNumber - * @return {!Promise} - */ - async function initializeReimagingDeviceInformationPage(serialNumber) { + /** @return {!Promise} */ + async function initializeReimagingDeviceInformationPage() { assertFalse(!!component); - service.setGetOriginalSerialNumberResult(serialNumber); + service.setGetOriginalSerialNumberResult(fakeSerialNumber); service.setGetRegionListResult(fakeDeviceRegions); service.setGetOriginalRegionResult(2); service.setGetWhiteLabelListResult(fakeDeviceWhiteLabels); service.setGetOriginalWhiteLabelResult(3); service.setGetSkuListResult(fakeDeviceSkus); service.setGetOriginalSkuResult(1); + service.setGetOriginalDramPartNumberResult(fakeDramPartNumber); component = /** @type {!ReimagingDeviceInformationPage} */ ( document.createElement('reimaging-device-information-page')); @@ -75,7 +74,7 @@ } test('ReimagingDeviceInformationPageInitializes', async () => { - await initializeReimagingDeviceInformationPage(fakeSerialNumber); + await initializeReimagingDeviceInformationPage(); const serialNumberComponent = component.shadowRoot.querySelector('#serialNumber'); @@ -104,7 +103,7 @@ test('ReimagingDeviceInformationPageNextReturnsInformation', async () => { const resolver = new PromiseResolver(); - await initializeReimagingDeviceInformationPage(fakeSerialNumber); + await initializeReimagingDeviceInformationPage(); const serialNumberComponent = component.shadowRoot.querySelector('#serialNumber'); @@ -113,14 +112,18 @@ const whiteLabelSelectComponent = component.shadowRoot.querySelector('#whiteLabelSelect'); const skuSelectComponent = component.shadowRoot.querySelector('#skuSelect'); + const dramPartNumberComponent = + component.shadowRoot.querySelector('#dramPartNumber'); let expectedSerialNumber = 'expected serial number'; let expectedRegionIndex = 0; let expectedWhiteLabelIndex = 1; let expectedSkuIndex = 2; + let expectedDramPartNumber = 'expected dram part number'; serialNumberComponent.value = expectedSerialNumber; regionSelectComponent.selectedIndex = expectedRegionIndex; whiteLabelSelectComponent.selectedIndex = expectedWhiteLabelIndex; skuSelectComponent.selectedIndex = expectedSkuIndex; + dramPartNumberComponent.value = expectedDramPartNumber; // TODO(gavindodd) how to update selectedIndex and trigger on-change // automatically. suppressedComponentOnSelectedChange_(component); @@ -129,15 +132,17 @@ let regionIndex; let whiteLabelIndex; let skuIndex; + let dramPartNumber; let callCounter = 0; service.setDeviceInformation = (resultSerialNumber, resultRegionIndex, resultSkuIndex, - resultWhiteLabelIndex) => { + resultWhiteLabelIndex, resultDramPartNumber) => { callCounter++; serialNumber = resultSerialNumber; regionIndex = resultRegionIndex; whiteLabelIndex = resultWhiteLabelIndex; skuIndex = resultSkuIndex; + dramPartNumber = resultDramPartNumber; return resolver.promise; }; @@ -153,12 +158,14 @@ assertEquals(expectedRegionIndex, regionIndex); assertEquals(expectedWhiteLabelIndex, whiteLabelIndex); assertEquals(expectedSkuIndex, skuIndex); + assertEquals(expectedDramPartNumber, dramPartNumber); assertDeepEquals(expectedResult, savedResult); }); test('ReimagingDeviceInformationPageModifySerialNumberAndReset', async () => { - await initializeReimagingDeviceInformationPage(fakeSerialNumber); + await initializeReimagingDeviceInformationPage(); + component.allButtonsDisabled = false; let serialNumber = fakeSerialNumber + 'new serial number'; const serialNumberComponent = component.shadowRoot.querySelector('#serialNumber'); @@ -177,6 +184,169 @@ assertTrue(resetSerialNumberComponent.disabled); }); + test('ReimagingDeviceInformationPageInputsDisabled', async () => { + await initializeReimagingDeviceInformationPage(); + + const serialNumberInput = + component.shadowRoot.querySelector('#serialNumber'); + const serialNumberButton = + component.shadowRoot.querySelector('#resetSerialNumber'); + const regionSelect = component.shadowRoot.querySelector('#regionSelect'); + const regionButton = component.shadowRoot.querySelector('#resetRegion'); + const skuSelect = component.shadowRoot.querySelector('#skuSelect'); + const skuButton = component.shadowRoot.querySelector('#resetSku'); + + component.allButtonsDisabled = false; + assertFalse(serialNumberInput.disabled); + assertFalse(regionSelect.disabled); + assertFalse(skuSelect.disabled); + + component.allButtonsDisabled = true; + assertTrue(serialNumberInput.disabled); + assertTrue(regionSelect.disabled); + assertTrue(skuSelect.disabled); + }); + + test( + 'ReimagingDeviceInformationPageModifyDramPartNumberAndReset', + async () => { + await initializeReimagingDeviceInformationPage(); + + let dramPartNumber = fakeDramPartNumber + 'new part number'; + const dramPartNumberComponent = + component.shadowRoot.querySelector('#dramPartNumber'); + const resetDramPartNumberComponent = + component.shadowRoot.querySelector('#resetDramPartNumber'); + + assertEquals(dramPartNumberComponent.value, fakeDramPartNumber); + assertTrue(resetDramPartNumberComponent.disabled); + dramPartNumberComponent.value = dramPartNumber; + await flushTasks(); + assertFalse(resetDramPartNumberComponent.disabled); + assertEquals(dramPartNumberComponent.value, dramPartNumber); + resetDramPartNumberComponent.click(); + await flushTasks(); + assertEquals(dramPartNumberComponent.value, fakeDramPartNumber); + assertTrue(resetDramPartNumberComponent.disabled); + }); + + test( + 'ReimagingDeviceInformationPageSerialNumberUpdatesNextDisable', + async () => { + const resolver = new PromiseResolver(); + await initializeReimagingDeviceInformationPage(); + let disableNextButtonEventFired = false; + let disableNextButton = false; + component.addEventListener('disable-next-button', (e) => { + disableNextButtonEventFired = true; + disableNextButton = e.detail; + }); + + const serialNumberComponent = + component.shadowRoot.querySelector('#serialNumber'); + serialNumberComponent.value = ''; + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertTrue(disableNextButton); + + disableNextButtonEventFired = false; + serialNumberComponent.value = 'valid serial number'; + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertFalse(disableNextButton); + }); + + test('ReimagingDeviceInformationPageRegionUpdatesNextDisable', async () => { + const resolver = new PromiseResolver(); + await initializeReimagingDeviceInformationPage(); + let disableNextButtonEventFired = false; + let disableNextButton = false; + component.addEventListener('disable-next-button', (e) => { + disableNextButtonEventFired = true; + disableNextButton = e.detail; + }); + + const regionSelectComponent = + component.shadowRoot.querySelector('#regionSelect'); + regionSelectComponent.selectedIndex = -1; + // TODO(gavindodd) how to update selectedIndex and trigger on-change + // automatically. + suppressedComponentOnSelectedChange_(component); + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertTrue(disableNextButton); + + disableNextButtonEventFired = false; + regionSelectComponent.selectedIndex = 1; + // TODO(gavindodd) how to update selectedIndex and trigger on-change + // automatically. + suppressedComponentOnSelectedChange_(component); + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertFalse(disableNextButton); + }); + + test('ReimagingDeviceInformationPageSkuUpdatesNextDisable', async () => { + const resolver = new PromiseResolver(); + await initializeReimagingDeviceInformationPage(); + let disableNextButtonEventFired = false; + let disableNextButton = false; + component.addEventListener('disable-next-button', (e) => { + disableNextButtonEventFired = true; + disableNextButton = e.detail; + }); + + const skuSelectComponent = component.shadowRoot.querySelector('#skuSelect'); + skuSelectComponent.selectedIndex = -1; + // TODO(gavindodd) how to update selectedIndex and trigger on-change + // automatically. + suppressedComponentOnSelectedChange_(component); + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertTrue(disableNextButton); + + disableNextButtonEventFired = false; + skuSelectComponent.selectedIndex = 1; + // TODO(gavindodd) how to update selectedIndex and trigger on-change + // automatically. + suppressedComponentOnSelectedChange_(component); + await flushTasks(); + + assertTrue(disableNextButtonEventFired); + assertFalse(disableNextButton); + }); + + test( + 'ReimagingDeviceInformationPageDramPartNumberDoesNotUpdateNextDisable', + async () => { + const resolver = new PromiseResolver(); + await initializeReimagingDeviceInformationPage(); + let disableNextButtonEventFired = false; + let disableNextButton = false; + component.addEventListener('disable-next-button', (e) => { + disableNextButtonEventFired = true; + disableNextButton = e.detail; + }); + + const dramPartNumberComponent = + component.shadowRoot.querySelector('#dramPartNumber'); + dramPartNumberComponent.value = ''; + await flushTasks(); + + assertFalse(disableNextButtonEventFired); + + disableNextButtonEventFired = false; + dramPartNumberComponent.value = 'valid dram part number'; + await flushTasks(); + + assertFalse(disableNextButtonEventFired); + }); + // TODO(gavindodd): Add tests for the selection lists when they are // reimplemented and bound. // The standard `select` object is not bound.
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_provisioning_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_provisioning_page_test.js index 78320d8..88235be4 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_provisioning_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_provisioning_page_test.js
@@ -166,4 +166,14 @@ await flushTasks(); assertEquals(1, callCount); }); + + test('ProvisioningFailedRetryDisabled', async () => { + await initializeWaitForProvisioningPage(); + + const retryButton = + component.shadowRoot.querySelector('#retryProvisioningButton'); + assertFalse(retryButton.disabled); + component.allButtonsDisabled = true; + assertTrue(retryButton.disabled); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_finalize_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_finalize_page_test.js index 8213e71..3be7649f 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_finalize_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_finalize_page_test.js
@@ -5,6 +5,7 @@ import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js'; import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js'; +import {ShimlessRma} from 'chrome://shimless-rma/shimless_rma.js'; import {FinalizationStatus} from 'chrome://shimless-rma/shimless_rma_types.js'; import {WrapupFinalizePage} from 'chrome://shimless-rma/wrapup_finalize_page.js'; @@ -12,6 +13,13 @@ import {flushTasks} from '../../test_util.js'; export function wrapupFinalizePageTest() { + /** + * ShimlessRma is needed to handle the 'transition-state' event used + * when handling calibration overall progress signals. + * @type {?ShimlessRma} + */ + let shimless_rma_component = null; + /** @type {?WrapupFinalizePage} */ let component = null; @@ -28,6 +36,8 @@ }); teardown(() => { + shimless_rma_component.remove(); + shimless_rma_component = null; component.remove(); component = null; service.reset(); @@ -39,6 +49,11 @@ function initializeFinalizePage() { assertFalse(!!component); + shimless_rma_component = + /** @type {!ShimlessRma} */ (document.createElement('shimless-rma')); + assertTrue(!!shimless_rma_component); + document.body.appendChild(shimless_rma_component); + component = /** @type {!WrapupFinalizePage} */ ( document.createElement('wrapup-finalize-page')); assertTrue(!!component); @@ -87,4 +102,52 @@ assertDeepEquals(savedResult, expectedResult); }); + + test('FinalizationFailedBlockingRetry', async () => { + const resolver = new PromiseResolver(); + await initializeFinalizePage(); + + const retryButton = + component.shadowRoot.querySelector('#retryFinalizationButton'); + assertTrue(retryButton.hidden); + + let callCount = 0; + service.retryFinalization = () => { + callCount++; + return resolver.promise; + }; + service.triggerFinalizationObserver( + FinalizationStatus.kFailedBlocking, 1.0, 0); + await flushTasks(); + + assertFalse(retryButton.hidden); + retryButton.click(); + + await flushTasks(); + assertEquals(1, callCount); + }); + + test('FinalizationFailedNonBlockingRetry', async () => { + const resolver = new PromiseResolver(); + await initializeFinalizePage(); + + const retryButton = + component.shadowRoot.querySelector('#retryFinalizationButton'); + assertTrue(retryButton.hidden); + + let callCount = 0; + service.retryFinalization = () => { + callCount++; + return resolver.promise; + }; + service.triggerFinalizationObserver( + FinalizationStatus.kFailedNonBlocking, 1.0, 0); + await flushTasks(); + + assertFalse(retryButton.hidden); + retryButton.click(); + + await flushTasks(); + assertEquals(1, callCount); + }); }
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn index b179e93..483153f 100644 --- a/chrome/test/data/webui/cr_elements/BUILD.gn +++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -3,34 +3,10 @@ # found in the LICENSE file. import("//build/config/chromeos/ui_mode.gni") -import("//third_party/closure_compiler/closure_args.gni") -import("//third_party/closure_compiler/compile_js.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") import("../namespace_rewrites.gni") -if (is_chromeos_ash) { - js_type_check("closure_compile") { - is_polymer3 = true - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/test/data/webui/", - "js_module_root=./gen/chrome/test/data/webui/", - ] - - deps = [ ":cr_searchable_drop_down_tests" ] - } - - js_library("cr_searchable_drop_down_tests") { - deps = [ - "..: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", - ] - externs_list = [ "$externs_path/mocha-2.5.js" ] - } -} - generate_grd("build_grdp") { grd_prefix = "webui_cr_elements" out_grd = "$target_gen_dir/resources.grdp" @@ -86,8 +62,17 @@ "cr_toolbar_search_field_tests.ts", "cr_toolbar_test.ts", "cr_view_manager_test.ts", + "find_shortcut_mixin_test.ts", "iron_list_focus_test.ts", ] + + if (is_chromeos_ash) { + in_files += [ + "cr_searchable_drop_down_tests.ts", + "find_shortcut_behavior_test.ts", + ] + } + definitions = [ "//tools/typescript/definitions/settings_private.d.ts" ] deps = [ "//ui/webui/resources:library" ] extra_deps = [ "..:generate_definitions" ]
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js index 8836b11..68bb568f 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -115,7 +115,7 @@ var CrElementsFindShortcutBehaviorTest = class extends CrElementsBrowserTest { /** @override */ get browsePreload() { - return 'chrome://test/test_loader.html?module=cr_elements/find_shortcut_behavior_test.js'; + return 'chrome://test/test_loader.html?module=cr_elements/find_shortcut_behavior_test.js&host=webui-test'; } }; @@ -127,7 +127,7 @@ var CrElementsFindShortcutMixinTest = class extends CrElementsBrowserTest { /** @override */ get browsePreload() { - return 'chrome://test/test_loader.html?module=cr_elements/find_shortcut_mixin_test.js'; + return 'chrome://test/test_loader.html?module=cr_elements/find_shortcut_mixin_test.js&host=webui-test'; } }; @@ -251,7 +251,7 @@ var CrElementsSearchableDropDownTest = class extends CrElementsBrowserTest { /** @override */ get browsePreload() { - return 'chrome://test/test_loader.html?module=cr_elements/cr_searchable_drop_down_tests.js'; + return 'chrome://test/test_loader.html?module=cr_elements/cr_searchable_drop_down_tests.js&host=webui-test'; } };
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.ts similarity index 66% rename from chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.js rename to chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.ts index 8b6c748..3f6185b 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.ts
@@ -5,43 +5,38 @@ // clang-format off import 'chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js'; +import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; +import {CrSearchableDropDownElement} from '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'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../chai_assert.js'; +import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; // clang-format on suite('cr-searchable-drop-down', function() { - /** @type {!CrSearchableDropDownElement} */ - let dropDown; - - /** @type {!HTMLElement} */ - let outsideElement; - - /** @type {!CrInputElement} */ - let searchInput; + let dropDown: CrSearchableDropDownElement; + let outsideElement: HTMLElement; + let searchInput: CrInputElement; /** - * @param {!Array<string>} items The list of items to be populated in the - * drop down. + * @param items The list of items to be populated in the drop down. */ - function setItems(items) { + function setItems(items: string[]) { dropDown.items = items; flush(); } - /** @return {!NodeList} */ - function getList() { - return dropDown.shadowRoot.querySelectorAll('.list-item'); + function getList(): NodeListOf<HTMLElement> { + return dropDown.shadowRoot!.querySelectorAll<HTMLElement>('.list-item'); } /** - * @param {string} searchTerm The string used to filter the list of items in - * the drop down. + * @param searchTerm The string used to filter the list of items in the drop + * down. */ - function search(searchTerm) { + function search(searchTerm: string) { const input = /** @type {!CrInputElement} */ ( - dropDown.shadowRoot.querySelector('cr-input')); + dropDown.shadowRoot!.querySelector('cr-input')!); input.value = searchTerm; input.fire('input'); flush(); @@ -49,7 +44,7 @@ function blur() { const input = /** @type {!CrInputElement} */ ( - dropDown.shadowRoot.querySelector('cr-input')); + dropDown.shadowRoot!.querySelector('cr-input')!); input.fire('blur'); flush(); } @@ -70,7 +65,7 @@ keyDownOn(searchInput, 0, [], 'Tab'); } - function pointerDown(element) { + function pointerDown(element: HTMLElement) { element.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, cancelable: true, @@ -80,7 +75,7 @@ } function getSelectedElement() { - return dropDown.shadowRoot.querySelector('[selected_]'); + return dropDown.shadowRoot!.querySelector('[selected_]'); } setup(function() { @@ -89,10 +84,8 @@ <cr-searchable-drop-down label="test drop down"> </cr-searchable-drop-down> `; - dropDown = /** @type {!CrSearchableDropDownElement} */ ( - document.querySelector('cr-searchable-drop-down')); - outsideElement = - /** @type {!HTMLElement} */ (document.querySelector('#outside')); + dropDown = document.querySelector('cr-searchable-drop-down')!; + outsideElement = document.querySelector<HTMLElement>('#outside')!; searchInput = dropDown.$.search; flush(); }); @@ -103,9 +96,9 @@ const itemList = getList(); assertEquals(3, itemList.length); - assertEquals('one', itemList[0].textContent.trim()); - assertEquals('two', itemList[1].textContent.trim()); - assertEquals('three', itemList[2].textContent.trim()); + assertEquals('one', itemList[0]!.textContent!.trim()); + assertEquals('two', itemList[1]!.textContent!.trim()); + assertEquals('three', itemList[2]!.textContent!.trim()); }); test('filter works correctly', function() { @@ -113,20 +106,20 @@ search('c'); assertEquals(1, getList().length); - assertEquals('cat', getList()[0].textContent.trim()); + assertEquals('cat', getList()[0]!.textContent!.trim()); assertTrue(dropDown.invalid); search('at'); assertEquals(3, getList().length); - assertEquals('cat', getList()[0].textContent.trim()); - assertEquals('hat', getList()[1].textContent.trim()); - assertEquals('rat', getList()[2].textContent.trim()); + assertEquals('cat', getList()[0]!.textContent!.trim()); + assertEquals('hat', getList()[1]!.textContent!.trim()); + assertEquals('rat', getList()[2]!.textContent!.trim()); assertTrue(dropDown.invalid); search('ra'); assertEquals(2, getList().length); - assertEquals('rat', getList()[0].textContent.trim()); - assertEquals('rake', getList()[1].textContent.trim()); + assertEquals('rat', getList()[0]!.textContent!.trim()); + assertEquals('rake', getList()[1]!.textContent!.trim()); assertTrue(dropDown.invalid); }); @@ -135,7 +128,7 @@ assertNotEquals('dog', dropDown.value); - getList()[0].click(); + getList()[0]!.click(); assertEquals('dog', dropDown.value); @@ -153,7 +146,7 @@ assertNotEquals('dog', dropDown.value); - getList()[0].click(); + getList()[0]!.click(); assertEquals('dog', dropDown.value); @@ -168,13 +161,13 @@ // Dropdown opening is tied to focus. dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertNotEquals('dog', dropDown.value); - getList()[0].click(); + getList()[0]!.click(); assertEquals('dog', dropDown.value); - assertFalse(dropDown.$$('iron-dropdown').opened); + assertFalse(dropDown.$.dropdown.opened); }); test('click outside closes dropdown', function() { @@ -182,12 +175,12 @@ // Dropdown opening is tied to focus. dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertNotEquals('dog', dropDown.value); pointerDown(outsideElement); assertNotEquals('dog', dropDown.value); - assertFalse(dropDown.$$('iron-dropdown').opened); + assertFalse(dropDown.$.dropdown.opened); }); test('tab closes dropdown', function() { @@ -195,60 +188,60 @@ // Dropdown opening is tied to focus. dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); tab(); - assertFalse(dropDown.$$('iron-dropdown').opened); + assertFalse(dropDown.$.dropdown.opened); }); test('selected moves after up/down', function() { setItems(['dog', 'cat', 'mouse']); dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertEquals(null, getSelectedElement()); down(); - assertEquals('dog', getSelectedElement().textContent.trim()); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); down(); - assertEquals('cat', getSelectedElement().textContent.trim()); + assertEquals('cat', getSelectedElement()!.textContent!.trim()); down(); - assertEquals('mouse', getSelectedElement().textContent.trim()); + assertEquals('mouse', getSelectedElement()!.textContent!.trim()); down(); - assertEquals('dog', getSelectedElement().textContent.trim()); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); up(); - assertEquals('mouse', getSelectedElement().textContent.trim()); + assertEquals('mouse', getSelectedElement()!.textContent!.trim()); up(); - assertEquals('cat', getSelectedElement().textContent.trim()); + assertEquals('cat', getSelectedElement()!.textContent!.trim()); up(); - assertEquals('dog', getSelectedElement().textContent.trim()); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); up(); - assertEquals('mouse', getSelectedElement().textContent.trim()); + assertEquals('mouse', getSelectedElement()!.textContent!.trim()); enter(); assertEquals('mouse', dropDown.value); - assertFalse(dropDown.$$('iron-dropdown').opened); + assertFalse(dropDown.$.dropdown.opened); }); test('enter re-opens dropdown after selection', function() { setItems(['dog', 'cat', 'mouse']); dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertEquals(null, getSelectedElement()); down(); - assertEquals('dog', getSelectedElement().textContent.trim()); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); enter(); assertEquals('dog', dropDown.value); - assertFalse(dropDown.$$('iron-dropdown').opened); + assertFalse(dropDown.$.dropdown.opened); enter(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertEquals(null, getSelectedElement()); }); @@ -256,48 +249,48 @@ setItems(['dog', 'cat', 'mouse']); dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertEquals(null, getSelectedElement()); up(); - assertEquals('mouse', getSelectedElement().textContent.trim()); + assertEquals('mouse', getSelectedElement()!.textContent!.trim()); }); test('selected follows mouse', function() { setItems(['dog', 'cat', 'mouse']); dropDown.$.search.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); + assertTrue(dropDown.$.dropdown.opened); assertEquals(null, getSelectedElement()); - move(getList()[1], {x: 0, y: 0}, {x: 0, y: 0}, 1); - assertEquals('cat', getSelectedElement().textContent.trim()); - move(getList()[2], {x: 0, y: 0}, {x: 0, y: 0}, 1); - assertEquals('mouse', getSelectedElement().textContent.trim()); + move(getList()[1]!, {x: 0, y: 0}, {x: 0, y: 0}, 1); + assertEquals('cat', getSelectedElement()!.textContent!.trim()); + move(getList()[2]!, {x: 0, y: 0}, {x: 0, y: 0}, 1); + assertEquals('mouse', getSelectedElement()!.textContent!.trim()); // Interacting with the keyboard should update the selected element. up(); - assertEquals('cat', getSelectedElement().textContent.trim()); + assertEquals('cat', getSelectedElement()!.textContent!.trim()); // When the user moves the mouse again, the selected element should change. - move(getList()[0], {x: 0, y: 0}, {x: 0, y: 0}, 1); - assertEquals('dog', getSelectedElement().textContent.trim()); + move(getList()[0]!, {x: 0, y: 0}, {x: 0, y: 0}, 1); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); }); test('input retains focus', function() { setItems(['dog', 'cat', 'mouse']); searchInput.focus(); - assertTrue(dropDown.$$('iron-dropdown').opened); - assertEquals(searchInput, dropDown.shadowRoot.activeElement); + assertTrue(dropDown.$.dropdown.opened); + assertEquals(searchInput, dropDown.shadowRoot!.activeElement); assertEquals(null, getSelectedElement()); down(); - assertEquals('dog', getSelectedElement().textContent.trim()); - assertEquals(searchInput, dropDown.shadowRoot.activeElement); + assertEquals('dog', getSelectedElement()!.textContent!.trim()); + assertEquals(searchInput, dropDown.shadowRoot!.activeElement); }); // If the error-message-allowed flag is passed and the |errorMessage| property @@ -335,7 +328,8 @@ // The show-loading attribute should determine whether or not the loading // spinner and message are shown. test('loading spinner is shown and hidden', function() { - const progress = dropDown.shadowRoot.querySelector('#loading-box'); + const progress = + dropDown.shadowRoot!.querySelector<HTMLElement>('#loading-box')!; assertTrue(progress.hidden); dropDown.showLoading = true; @@ -348,13 +342,13 @@ // The readonly attribute is passed through to the inner cr-input. test('readonly attribute', function() { - const input = dropDown.shadowRoot.querySelector('cr-input'); + const input = dropDown.shadowRoot!.querySelector('cr-input')!; dropDown.readonly = true; - assertTrue(input.readonly); + assertTrue(!!input.readonly); dropDown.readonly = false; - assertFalse(input.readonly); + assertFalse(!!input.readonly); }); // When a user types in the dropdown but does not choose a valid option, the @@ -362,7 +356,7 @@ test('value resets on loss of focus', function() { setItems(['dog', 'cat', 'mouse']); - getList()[0].click(); + getList()[0]!.click(); assertEquals('dog', searchInput.value); assertFalse(dropDown.invalid); @@ -381,7 +375,7 @@ dropDown.updateValueOnInput = true; setItems(['dog', 'cat', 'mouse']); - getList()[0].click(); + getList()[0]!.click(); assertEquals('dog', searchInput.value); assertFalse(dropDown.invalid); @@ -401,10 +395,10 @@ search('rat'); assertEquals(1, getList().length); - assertEquals('rat', getList()[0].textContent.trim()); + assertEquals('rat', getList()[0]!.textContent!.trim()); blur(); - getList()[0].click(); + getList()[0]!.click(); assertEquals('rat', dropDown.value); });
diff --git a/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js b/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js deleted file mode 100644 index f82e21e3..0000000 --- a/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js +++ /dev/null
@@ -1,248 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// clang-format off -import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; - -import {FindShortcutBehavior, FindShortcutManager} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; -import {assert} from 'chrome://resources/js/assert.m.js'; -import {isMac} from 'chrome://resources/js/cr.m.js'; -import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; -import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; -import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {eventToPromise} from 'chrome://test/test_util.js'; -// clang-format on - -suite('find-shortcut', () => { - /** @override */ - - /** - * @type {PromiseResolver<!{modalContextOpen: boolean, self: HTMLElement}>} - */ - let wait; - /** @type {boolean} */ - let resolved; - - const pressCtrlF = () => - pressAndReleaseKeyOn(window, 70, isMac ? 'meta' : 'ctrl', 'f'); - const pressSlash = () => pressAndReleaseKeyOn(window, 191, '', '/'); - - /** - * Checks that the handleFindShortcut method is being called for the - * element reference |expectedSelf| when a find shortcut is invoked. - * @param {!HTMLElement} expectedSelf - * @param {boolean} expectedModalContextOpen - * @param {function()} pressShortcut - * @return {!Promise} - */ - const check = async ( - expectedSelf, expectedModalContextOpen = false, - pressShortcut = pressCtrlF) => { - wait = new PromiseResolver(); - resolved = false; - pressShortcut(); - const args = await wait.promise; - assertEquals(expectedSelf, args.self); - assertEquals(!!expectedModalContextOpen, args.modalContextOpen); - }; - - /** - * Registers for a keydown event to check whether the bubbled up event has - * defaultPrevented set to true, in which case the event was handled. - * @param {boolean} defaultPrevented - * @return {!Promise} - */ - const listenOnceAndCheckDefaultPrevented = async defaultPrevented => { - const e = await eventToPromise('keydown', window); - assertEquals(e.defaultPrevented, defaultPrevented); - }; - - suiteSetup(() => { - Polymer({ - is: 'find-shortcut-element-manual-listen', - _template: null, - - behaviors: [FindShortcutBehavior], - - findShortcutListenOnAttach: false, - hasFocus: false, - - handleFindShortcut(modalContextOpen) { - assert(!resolved); - wait.resolve({modalContextOpen, self: this}); - return true; - }, - - searchInputHasFocus() { - return this.hasFocus; - } - }); - - Polymer({ - is: 'find-shortcut-element', - _template: null, - behaviors: [FindShortcutBehavior], - - handledResponse: true, - hasFocus: false, - - handleFindShortcut(modalContextOpen) { - assert(!resolved); - wait.resolve({modalContextOpen, self: this}); - return this.handledResponse; - }, - - searchInputHasFocus() { - return this.hasFocus; - }, - }); - PolymerTest.clearBody(); - }); - - teardown(() => { - PolymerTest.clearBody(); - assertEquals(0, FindShortcutManager.listeners.length); - }); - - test('handled', async () => { - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - await check(testElement); - }); - - test('handled with modal context open', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <cr-dialog></cr-dialog>`; - const testElement = document.body.querySelector('find-shortcut-element'); - const dialog = document.body.querySelector('cr-dialog'); - dialog.showModal(); - await check(testElement, true); - }); - - test('handled with modal context closed', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <cr-dialog></cr-dialog>`; - const testElement = document.body.querySelector('find-shortcut-element'); - const dialog = document.body.querySelector('cr-dialog'); - dialog.showModal(); - assertTrue(dialog.open); - const whenCloseFired = eventToPromise('close', dialog); - dialog.close(); - await whenCloseFired; - await check(testElement); - }); - - test('last listener is active', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element>`; - assertEquals(2, FindShortcutManager.listeners.length); - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - await check(testElements[1]); - }); - - test('can remove listeners out of order', async () => { - document.body.innerHTML = ` - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen> - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element-manual-listen'); - testElements[0].becomeActiveFindShortcutListener(); - testElements[1].becomeActiveFindShortcutListener(); - testElements[0].removeSelfAsFindShortcutListener(); - await check(testElements[1]); - testElements[1].removeSelfAsFindShortcutListener(); - }); - - test('removing self when not active throws exception', () => { - document.body.innerHTML = ` - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen>`; - const testElement = - document.body.querySelector('find-shortcut-element-manual-listen'); - assertThrows(() => testElement.removeSelfAsFindShortcutListener()); - }); - - test('throw exception when try to become active already a listener', () => { - document.body.innerHTML = ` - <find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - </find-shortcut-element>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - assertThrows(() => testElements[0].becomeActiveFindShortcutListener()); - assertThrows(() => testElements[1].becomeActiveFindShortcutListener()); - }); - - test('cmd+ctrl+f bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - pressAndReleaseKeyOn(window, 70, ['meta', 'ctrl'], 'f'); - await bubbledUp; - }); - - test('find shortcut bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(true); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - await check(testElement); - await bubbledUp; - }); - - test('shortcut with no listeners bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - pressAndReleaseKeyOn(window, 70, isMac ? 'meta' : 'ctrl', 'f'); - await bubbledUp; - }); - - test('inner listener is active when listening on attach', async () => { - document.body.innerHTML = ` - <find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - </find-shortcut-element>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - assertEquals(2, FindShortcutManager.listeners.length); - await check(testElements[1]); - }); - - test('not handle by listener bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - testElement.handledResponse = false; - await check(testElement); - await bubbledUp; - }); - - test('when element has focus, shortcut is handled by next', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element>`; - const testElements = - Array.from(document.body.querySelectorAll('find-shortcut-element')); - testElements[0].hasFocus = true; - await check(testElements[2]); - testElements[0].hasFocus = false; - testElements[1].hasFocus = true; - await check(testElements[0]); - testElements[1].hasFocus = false; - testElements[2].hasFocus = true; - await check(testElements[1]); - }); - - test('slash "/" is supported as a keyboard shortcut', async () => { - document.body.innerHTML = '<find-shortcut-element></find-shortcut-element>'; - const testElement = document.body.querySelector('find-shortcut-element'); - testElement.hasFocus = false; - await check(testElement, false, pressSlash); - }); -});
diff --git a/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.ts b/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.ts new file mode 100644 index 0000000..27e9c9c --- /dev/null +++ b/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.ts
@@ -0,0 +1,275 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; + +import {FindShortcutBehavior, FindShortcutManager} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {isMac} from 'chrome://resources/js/cr.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; +import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {assertEquals, assertThrows, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +// clang-format on + +suite('find-shortcut', () => { + let wait: PromiseResolver<{modalContextOpen: boolean, self: HTMLElement}>; + let resolved: boolean; + + function pressCtrlF() { + pressAndReleaseKeyOn( + document.documentElement, 70, isMac ? 'meta' : 'ctrl', 'f'); + } + + function pressSlash() { + pressAndReleaseKeyOn(document.documentElement, 191, '', '/'); + } + + /** + * Checks that the handleFindShortcut method is being called for the + * element reference |expectedSelf| when a find shortcut is invoked. + */ + async function check( + expectedSelf: HTMLElement, expectedModalContextOpen: boolean = false, + pressShortcut: () => void = pressCtrlF) { + wait = new PromiseResolver(); + resolved = false; + pressShortcut(); + const args = await wait.promise; + assertEquals(expectedSelf, args.self); + assertEquals(!!expectedModalContextOpen, args.modalContextOpen); + } + + /** + * Registers for a keydown event to check whether the bubbled up event has + * defaultPrevented set to true, in which case the event was handled. + */ + async function listenOnceAndCheckDefaultPrevented(defaultPrevented: boolean) { + const e = await eventToPromise('keydown', window); + assertEquals(e.defaultPrevented, defaultPrevented); + } + + const FindShortcutManualListenElementBase = + mixinBehaviors([FindShortcutBehavior], PolymerElement) as + {new (): PolymerElement & FindShortcutBehavior}; + + class FindShortcutManualListenElement extends + FindShortcutManualListenElementBase { + static get template() { + return html`<template></template>`; + } + + hasFocus: boolean; + + constructor() { + super(); + this.findShortcutListenOnAttach = false; + this.hasFocus = false; + } + + handleFindShortcut(modalContextOpen: boolean) { + assert(!resolved); + wait.resolve({modalContextOpen, self: this}); + return true; + } + + searchInputHasFocus() { + return this.hasFocus; + } + } + customElements.define( + 'find-shortcut-element-manual-listen', FindShortcutManualListenElement); + + const FindShortcutElementBase = + mixinBehaviors([FindShortcutBehavior], PolymerElement) as + {new (): PolymerElement & FindShortcutBehavior}; + + class FindShortcutElement extends FindShortcutElementBase { + static get template() { + return html`<template></template>`; + } + + handledResponse: boolean; + hasFocus: boolean; + + constructor() { + super(); + this.handledResponse = true; + this.hasFocus = false; + } + + handleFindShortcut(modalContextOpen: boolean) { + assert(!resolved); + wait.resolve({modalContextOpen, self: this}); + return this.handledResponse; + } + + searchInputHasFocus() { + return this.hasFocus; + } + } + customElements.define('find-shortcut-element', FindShortcutElement); + + suiteSetup(() => { + document.body.innerHTML = ''; + }); + + teardown(() => { + document.body.innerHTML = ''; + assertEquals(0, FindShortcutManager.listeners.length); + }); + + test('handled', async () => { + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + await check(testElement); + }); + + test('handled with modal context open', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + const dialog = document.body.querySelector('cr-dialog')!; + dialog.showModal(); + await check(testElement, true); + }); + + test('handled with modal context closed', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + const dialog = document.body.querySelector('cr-dialog')!; + dialog.showModal(); + assertTrue(dialog.open); + const whenCloseFired = eventToPromise('close', dialog); + dialog.close(); + await whenCloseFired; + await check(testElement); + }); + + test('last listener is active', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element>`; + assertEquals(2, FindShortcutManager.listeners.length); + const testElements = + document.body.querySelectorAll<HTMLElement>('find-shortcut-element'); + await check(testElements[1]!); + }); + + test('can remove listeners out of order', async () => { + document.body.innerHTML = ` + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen> + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen>`; + const testElements = + document.body.querySelectorAll<FindShortcutManualListenElement>( + 'find-shortcut-element-manual-listen'); + testElements[0]!.becomeActiveFindShortcutListener(); + testElements[1]!.becomeActiveFindShortcutListener(); + testElements[0]!.removeSelfAsFindShortcutListener(); + await check(testElements[1]!); + testElements[1]!.removeSelfAsFindShortcutListener(); + }); + + test('removing self when not active throws exception', () => { + document.body.innerHTML = ` + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen>`; + const testElement = + document.body.querySelector<FindShortcutManualListenElement>( + 'find-shortcut-element-manual-listen')!; + assertThrows(() => testElement.removeSelfAsFindShortcutListener()); + }); + + test('throw exception when try to become active already a listener', () => { + document.body.innerHTML = ` + <find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + </find-shortcut-element>`; + const testElements = document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element'); + assertThrows(() => testElements[0]!.becomeActiveFindShortcutListener()); + assertThrows(() => testElements[1]!.becomeActiveFindShortcutListener()); + }); + + test('cmd+ctrl+f bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + pressAndReleaseKeyOn(document.documentElement, 70, ['meta', 'ctrl'], 'f'); + await bubbledUp; + }); + + test('find shortcut bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(true); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + await check(testElement); + await bubbledUp; + }); + + test('shortcut with no listeners bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + pressAndReleaseKeyOn( + document.documentElement, 70, isMac ? 'meta' : 'ctrl', 'f'); + await bubbledUp; + }); + + test('inner listener is active when listening on attach', async () => { + document.body.innerHTML = ` + <find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + </find-shortcut-element>`; + const testElements = document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element'); + assertEquals(2, FindShortcutManager.listeners.length); + await check(testElements[1]!); + }); + + test('not handle by listener bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + testElement.handledResponse = false; + await check(testElement); + await bubbledUp; + }); + + test('when element has focus, shortcut is handled by next', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element>`; + const testElements = + Array.from(document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element')); + testElements[0]!.hasFocus = true; + await check(testElements[2]!); + testElements[0]!.hasFocus = false; + testElements[1]!.hasFocus = true; + await check(testElements[0]!); + testElements[1]!.hasFocus = false; + testElements[2]!.hasFocus = true; + await check(testElements[1]!); + }); + + test('slash "/" is supported as a keyboard shortcut', async () => { + document.body.innerHTML = '<find-shortcut-element></find-shortcut-element>'; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + testElement.hasFocus = false; + await check(testElement, false, pressSlash); + }); +});
diff --git a/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.js b/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.js deleted file mode 100644 index c5ebde0..0000000 --- a/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.js +++ /dev/null
@@ -1,261 +0,0 @@ -// 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. - -// clang-format off -import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; - -import {FindShortcutManager, FindShortcutMixin} from 'chrome://resources/cr_elements/find_shortcut_mixin.js'; -import {assert} from 'chrome://resources/js/assert.m.js'; -import {isMac} from 'chrome://resources/js/cr.m.js'; -import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; -import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {eventToPromise} from 'chrome://test/test_util.js'; -// clang-format on - -suite('find-shortcut', () => { - /** - * @type {PromiseResolver<!{modalContextOpen: boolean, self: HTMLElement}>} - */ - let wait; - /** @type {boolean} */ - let resolved; - - function pressCtrlF() { - pressAndReleaseKeyOn(window, 70, isMac ? 'meta' : 'ctrl', 'f'); - } - - function pressSlash() { - pressAndReleaseKeyOn(window, 191, '', '/'); - } - - /** - * Checks that the handleFindShortcut method is being called for the - * element reference |expectedSelf| when a find shortcut is invoked. - * @param {!HTMLElement} expectedSelf - * @param {boolean} expectedModalContextOpen - * @param {function()} pressShortcut - * @return {!Promise} - */ - async function check( - expectedSelf, expectedModalContextOpen = false, - pressShortcut = pressCtrlF) { - wait = new PromiseResolver(); - resolved = false; - pressShortcut(); - const args = await wait.promise; - assertEquals(expectedSelf, args.self); - assertEquals(!!expectedModalContextOpen, args.modalContextOpen); - } - - /** - * Registers for a keydown event to check whether the bubbled up event has - * defaultPrevented set to true, in which case the event was handled. - * @param {boolean} defaultPrevented - * @return {!Promise} - */ - async function listenOnceAndCheckDefaultPrevented(defaultPrevented) { - const e = await eventToPromise('keydown', window); - assertEquals(e.defaultPrevented, defaultPrevented); - } - - suiteSetup(() => { - const FindShortcutManualListenElementBase = - FindShortcutMixin(PolymerElement); - class FindShortcutManualListenElement extends - FindShortcutManualListenElementBase { - static get template() { - return html`<template></template>`; - } - - constructor() { - super(); - this.findShortcutListenOnAttach = false; - this.hasFocus = false; - } - - handleFindShortcut(modalContextOpen) { - assert(!resolved); - wait.resolve({modalContextOpen, self: this}); - return true; - } - - searchInputHasFocus() { - return this.hasFocus; - } - } - customElements.define( - 'find-shortcut-element-manual-listen', FindShortcutManualListenElement); - - const FindShortcutElementBase = FindShortcutMixin(PolymerElement); - class FindShortcutElement extends FindShortcutElementBase { - static get template() { - return html`<template></template>`; - } - - constructor() { - super(); - this.handledResponse = true; - this.hasFocus = false; - } - - handleFindShortcut(modalContextOpen) { - assert(!resolved); - wait.resolve({modalContextOpen, self: this}); - return this.handledResponse; - } - - searchInputHasFocus() { - return this.hasFocus; - } - } - customElements.define('find-shortcut-element', FindShortcutElement); - }); - - teardown(() => { - PolymerTest.clearBody(); - assertEquals(0, FindShortcutManager.listeners.length); - }); - - test('handled', async () => { - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - await check(testElement); - }); - - test('handled with modal context open', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <cr-dialog></cr-dialog>`; - const testElement = document.body.querySelector('find-shortcut-element'); - const dialog = document.body.querySelector('cr-dialog'); - dialog.showModal(); - await check(testElement, true); - }); - - test('handled with modal context closed', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <cr-dialog></cr-dialog>`; - const testElement = document.body.querySelector('find-shortcut-element'); - const dialog = document.body.querySelector('cr-dialog'); - dialog.showModal(); - assertTrue(dialog.open); - const whenCloseFired = eventToPromise('close', dialog); - dialog.close(); - await whenCloseFired; - await check(testElement); - }); - - test('last listener is active', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element>`; - assertEquals(2, FindShortcutManager.listeners.length); - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - await check(testElements[1]); - }); - - test('can remove listeners out of order', async () => { - document.body.innerHTML = ` - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen> - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element-manual-listen'); - testElements[0].becomeActiveFindShortcutListener(); - testElements[1].becomeActiveFindShortcutListener(); - testElements[0].removeSelfAsFindShortcutListener(); - await check(testElements[1]); - testElements[1].removeSelfAsFindShortcutListener(); - }); - - test('removing self when not active throws exception', () => { - document.body.innerHTML = ` - <find-shortcut-element-manual-listen> - </find-shortcut-element-manual-listen>`; - const testElement = - document.body.querySelector('find-shortcut-element-manual-listen'); - assertThrows(() => testElement.removeSelfAsFindShortcutListener()); - }); - - test('throw exception when try to become active already a listener', () => { - document.body.innerHTML = ` - <find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - </find-shortcut-element>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - assertThrows(() => testElements[0].becomeActiveFindShortcutListener()); - assertThrows(() => testElements[1].becomeActiveFindShortcutListener()); - }); - - test('cmd+ctrl+f bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - pressAndReleaseKeyOn(window, 70, ['meta', 'ctrl'], 'f'); - await bubbledUp; - }); - - test('find shortcut bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(true); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - await check(testElement); - await bubbledUp; - }); - - test('shortcut with no listeners bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - pressAndReleaseKeyOn(window, 70, isMac ? 'meta' : 'ctrl', 'f'); - await bubbledUp; - }); - - test('inner listener is active when listening on attach', async () => { - document.body.innerHTML = ` - <find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - </find-shortcut-element>`; - const testElements = - document.body.querySelectorAll('find-shortcut-element'); - assertEquals(2, FindShortcutManager.listeners.length); - await check(testElements[1]); - }); - - test('not handle by listener bubbles up', async () => { - const bubbledUp = listenOnceAndCheckDefaultPrevented(false); - document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; - const testElement = document.body.querySelector('find-shortcut-element'); - testElement.handledResponse = false; - await check(testElement); - await bubbledUp; - }); - - test('when element has focus, shortcut is handled by next', async () => { - document.body.innerHTML = ` - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element> - <find-shortcut-element></find-shortcut-element>`; - const testElements = - Array.from(document.body.querySelectorAll('find-shortcut-element')); - testElements[0].hasFocus = true; - await check(testElements[2]); - testElements[0].hasFocus = false; - testElements[1].hasFocus = true; - await check(testElements[0]); - testElements[1].hasFocus = false; - testElements[2].hasFocus = true; - await check(testElements[1]); - }); - - test('slash "/" is supported as a keyboard shortcut', async () => { - document.body.innerHTML = '<find-shortcut-element></find-shortcut-element>'; - const testElement = document.body.querySelector('find-shortcut-element'); - testElement.hasFocus = false; - await check(testElement, false, pressSlash); - }); -});
diff --git a/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.ts b/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.ts new file mode 100644 index 0000000..0524a01 --- /dev/null +++ b/chrome/test/data/webui/cr_elements/find_shortcut_mixin_test.ts
@@ -0,0 +1,270 @@ +// 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. + +// clang-format off +import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; + +import {FindShortcutManager, FindShortcutMixin} from 'chrome://resources/cr_elements/find_shortcut_mixin.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {isMac} from 'chrome://resources/js/cr.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {assertEquals, assertThrows, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +// clang-format on + +suite('find-shortcut', () => { + let wait: PromiseResolver<{modalContextOpen: boolean, self: HTMLElement}>; + let resolved: boolean; + + function pressCtrlF() { + pressAndReleaseKeyOn( + document.documentElement, 70, isMac ? 'meta' : 'ctrl', 'f'); + } + + function pressSlash() { + pressAndReleaseKeyOn(document.documentElement, 191, '', '/'); + } + + /** + * Checks that the handleFindShortcut method is being called for the + * element reference |expectedSelf| when a find shortcut is invoked. + */ + async function check( + expectedSelf: HTMLElement, expectedModalContextOpen: boolean = false, + pressShortcut: () => void = pressCtrlF) { + wait = new PromiseResolver(); + resolved = false; + pressShortcut(); + const args = await wait.promise; + assertEquals(expectedSelf, args.self); + assertEquals(!!expectedModalContextOpen, args.modalContextOpen); + } + + /** + * Registers for a keydown event to check whether the bubbled up event has + * defaultPrevented set to true, in which case the event was handled. + */ + async function listenOnceAndCheckDefaultPrevented(defaultPrevented: boolean) { + const e = await eventToPromise('keydown', window); + assertEquals(e.defaultPrevented, defaultPrevented); + } + + const FindShortcutManualListenElementBase = FindShortcutMixin(PolymerElement); + + class FindShortcutManualListenElement extends + FindShortcutManualListenElementBase { + static get template() { + return html`<template></template>`; + } + + hasFocus: boolean; + + constructor() { + super(); + this.findShortcutListenOnAttach = false; + this.hasFocus = false; + } + + handleFindShortcut(modalContextOpen: boolean) { + assert(!resolved); + wait.resolve({modalContextOpen, self: this}); + return true; + } + + searchInputHasFocus() { + return this.hasFocus; + } + } + customElements.define( + 'find-shortcut-element-manual-listen', FindShortcutManualListenElement); + + const FindShortcutElementBase = FindShortcutMixin(PolymerElement); + class FindShortcutElement extends FindShortcutElementBase { + static get template() { + return html`<template></template>`; + } + + handledResponse: boolean; + hasFocus: boolean; + + constructor() { + super(); + this.handledResponse = true; + this.hasFocus = false; + } + + handleFindShortcut(modalContextOpen: boolean) { + assert(!resolved); + wait.resolve({modalContextOpen, self: this}); + return this.handledResponse; + } + + searchInputHasFocus() { + return this.hasFocus; + } + } + customElements.define('find-shortcut-element', FindShortcutElement); + + suiteSetup(() => { + document.body.innerHTML = ''; + }); + + teardown(() => { + document.body.innerHTML = ''; + assertEquals(0, FindShortcutManager.listeners.length); + }); + + test('handled', async () => { + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + await check(testElement); + }); + + test('handled with modal context open', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + const dialog = document.body.querySelector('cr-dialog')!; + dialog.showModal(); + await check(testElement, true); + }); + + test('handled with modal context closed', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + const dialog = document.body.querySelector('cr-dialog')!; + dialog.showModal(); + assertTrue(dialog.open); + const whenCloseFired = eventToPromise('close', dialog); + dialog.close(); + await whenCloseFired; + await check(testElement); + }); + + test('last listener is active', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element>`; + assertEquals(2, FindShortcutManager.listeners.length); + const testElements = + document.body.querySelectorAll<HTMLElement>('find-shortcut-element'); + await check(testElements[1]!); + }); + + test('can remove listeners out of order', async () => { + document.body.innerHTML = ` + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen> + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen>`; + const testElements = + document.body.querySelectorAll<FindShortcutManualListenElement>( + 'find-shortcut-element-manual-listen'); + testElements[0]!.becomeActiveFindShortcutListener(); + testElements[1]!.becomeActiveFindShortcutListener(); + testElements[0]!.removeSelfAsFindShortcutListener(); + await check(testElements[1]!); + testElements[1]!.removeSelfAsFindShortcutListener(); + }); + + test('removing self when not active throws exception', () => { + document.body.innerHTML = ` + <find-shortcut-element-manual-listen> + </find-shortcut-element-manual-listen>`; + const testElement = + document.body.querySelector<FindShortcutManualListenElement>( + 'find-shortcut-element-manual-listen')!; + assertThrows(() => testElement.removeSelfAsFindShortcutListener()); + }); + + test('throw exception when try to become active already a listener', () => { + document.body.innerHTML = ` + <find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + </find-shortcut-element>`; + const testElements = document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element'); + assertThrows(() => testElements[0]!.becomeActiveFindShortcutListener()); + assertThrows(() => testElements[1]!.becomeActiveFindShortcutListener()); + }); + + test('cmd+ctrl+f bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + pressAndReleaseKeyOn(document.documentElement, 70, ['meta', 'ctrl'], 'f'); + await bubbledUp; + }); + + test('find shortcut bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(true); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + await check(testElement); + await bubbledUp; + }); + + test('shortcut with no listeners bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + pressAndReleaseKeyOn( + document.documentElement, 70, isMac ? 'meta' : 'ctrl', 'f'); + await bubbledUp; + }); + + test('inner listener is active when listening on attach', async () => { + document.body.innerHTML = ` + <find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + </find-shortcut-element>`; + const testElements = document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element'); + assertEquals(2, FindShortcutManager.listeners.length); + await check(testElements[1]!); + }); + + test('not handle by listener bubbles up', async () => { + const bubbledUp = listenOnceAndCheckDefaultPrevented(false); + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + testElement.handledResponse = false; + await check(testElement); + await bubbledUp; + }); + + test('when element has focus, shortcut is handled by next', async () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element>`; + const testElements = + Array.from(document.body.querySelectorAll<FindShortcutElement>( + 'find-shortcut-element')); + testElements[0]!.hasFocus = true; + await check(testElements[2]!); + testElements[0]!.hasFocus = false; + testElements[1]!.hasFocus = true; + await check(testElements[0]!); + testElements[1]!.hasFocus = false; + testElements[2]!.hasFocus = true; + await check(testElements[1]!); + }); + + test('slash "/" is supported as a keyboard shortcut', async () => { + document.body.innerHTML = '<find-shortcut-element></find-shortcut-element>'; + const testElement = document.body.querySelector<FindShortcutElement>( + 'find-shortcut-element')!; + testElement.hasFocus = false; + await check(testElement, false, pressSlash); + }); +});
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js index 744236ea..3a934b3 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js +++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -9,6 +9,7 @@ GEN('#include "chrome/browser/ui/webui/extensions/' + 'extension_settings_browsertest.h"'); +GEN('#include "chrome/browser/ui/ui_features.h"'); GEN('#include "content/public/test/browser_test.h"'); GEN('#include "build/chromeos_buildflags.h"'); @@ -478,6 +479,20 @@ this.runMochaTest(extension_manager_tests.TestNames.PageTitleUpdate); }); +TEST_F( + 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', + 'NavigateToSitePermissionsFail', function() { + this.runMochaTest( + extension_manager_tests.TestNames.NavigateToSitePermissionsFail); + }); + +TEST_F( + 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', + 'NavigateToSitePermissionsSuccess', function() { + this.runMochaTest( + extension_manager_tests.TestNames.NavigateToSitePermissionsSuccess); + }); + var CrExtensionsManagerTestWithIdQueryParam = class extends CrExtensionsBrowserTestWithInstalledExtension { /** @override */ @@ -723,12 +738,17 @@ /** @override */ testGenPreamble() { GEN(' SetDevModeEnabled(true);'); + // TODO(https://crbug.com/1269161): Update the associated extensions to + // Manifest V3 and stop ignoring deprecated manifest version warnings. + GEN(' SetSilenceDeprecatedManifestVersionWarnings(true);'); GEN(' InstallErrorsExtension();'); } /** @override */ testGenPostamble() { - GEN(' SetDevModeEnabled(false);'); // Return this to default. + // Return settings to default. + GEN(' SetDevModeEnabled(false);'); + GEN(' SetSilenceDeprecatedManifestVersionWarnings(false);'); } };
diff --git a/chrome/test/data/webui/extensions/detail_view_test.js b/chrome/test/data/webui/extensions/detail_view_test.js index 29227b92..510beaed 100644 --- a/chrome/test/data/webui/extensions/detail_view_test.js +++ b/chrome/test/data/webui/extensions/detail_view_test.js
@@ -55,6 +55,7 @@ item.set('inDevMode', false); item.set('incognitoAvailable', true); item.set('showActivityLog', false); + item.set('enableEnhancedSiteControls', false); document.body.appendChild(item); });
diff --git a/chrome/test/data/webui/extensions/manager_test.js b/chrome/test/data/webui/extensions/manager_test.js index 8cabeca8..890627d 100644 --- a/chrome/test/data/webui/extensions/manager_test.js +++ b/chrome/test/data/webui/extensions/manager_test.js
@@ -16,6 +16,10 @@ ItemListVisibility: 'item list visibility', SplitItems: 'split items', PageTitleUpdate: 'updates the title based on current route', + NavigateToSitePermissionsFail: + 'url navigation to site permissions page without flag set', + NavigateToSitePermissionsSuccess: + 'url navigation to site permissions page with flag set', }; function getDataByName(list, name) { @@ -25,7 +29,7 @@ } suite(extension_manager_tests.suiteName, function() { - /** @type {Manager} */ + /** @type {ExtensionsManagerElement} */ let manager; /** @param {string} viewElement */ @@ -139,4 +143,33 @@ flush(); expectEquals('Extensions', document.title); }); + + test( + assert(extension_manager_tests.TestNames.NavigateToSitePermissionsFail), + function() { + expectFalse(manager.enableEnhancedSiteControls); + + // Try to open the site permissions page. + navigation.navigateTo({page: Page.SITE_PERMISSIONS}); + flush(); + + // Should be re-routed to the main page with enableEnhancedSiteControls + // set to false. + assertViewActive('extensions-item-list'); + }); + + test( + assert( + extension_manager_tests.TestNames.NavigateToSitePermissionsSuccess), + function() { + // Set the enableEnhancedSiteControls flag to true. + manager.enableEnhancedSiteControls = true; + flush(); + + // Try to open the site permissions page. The navigation should succeed + // with enableEnhancedSiteControls set to true. + navigation.navigateTo({page: Page.SITE_PERMISSIONS}); + flush(); + assertViewActive('extensions-site-permissions'); + }); });
diff --git a/chrome/test/data/webui/extensions/navigation_helper_test.js b/chrome/test/data/webui/extensions/navigation_helper_test.js index 7fdb318..6f6a3159 100644 --- a/chrome/test/data/webui/extensions/navigation_helper_test.js +++ b/chrome/test/data/webui/extensions/navigation_helper_test.js
@@ -103,6 +103,10 @@ url: 'chrome://extensions/shortcuts', state: {page: Page.SHORTCUTS}, }, + sitePermissions: { + url: 'chrome://extensions/sitePermissions', + state: {page: Page.SITE_PERMISSIONS}, + }, }; // Test url -> state.
diff --git a/chrome/test/data/webui/extensions/runtime_host_permissions_test.js b/chrome/test/data/webui/extensions/runtime_host_permissions_test.js index 9dfbd64..5109109 100644 --- a/chrome/test/data/webui/extensions/runtime_host_permissions_test.js +++ b/chrome/test/data/webui/extensions/runtime_host_permissions_test.js
@@ -21,12 +21,12 @@ const ITEM_ID = 'a'.repeat(32); setup(function() { - loadTimeData.overrideValues({extensionsMenuAccessControlEnabled: false}); document.body.innerHTML = ''; element = document.createElement('extensions-runtime-host-permissions'); delegate = new TestService(); element.delegate = delegate; element.itemId = ITEM_ID; + element.enableEnhancedSiteControls = false; document.body.appendChild(element);
diff --git a/chrome/test/data/webui/extensions/sidebar_test.js b/chrome/test/data/webui/extensions/sidebar_test.js index 3d3cd58..587485b6 100644 --- a/chrome/test/data/webui/extensions/sidebar_test.js +++ b/chrome/test/data/webui/extensions/sidebar_test.js
@@ -27,6 +27,7 @@ setup(function() { document.body.innerHTML = ''; sidebar = document.createElement('extensions-sidebar'); + sidebar.enableEnhancedSiteControls = false; document.body.appendChild(sidebar); }); @@ -67,9 +68,17 @@ function(done) { const boundTestVisible = testVisible.bind(null, sidebar); boundTestVisible('#sections-extensions', true); + + // The site permissions link should not be visible if + // enableEnhancedSiteControls is set to false. + boundTestVisible('#sections-site-permissions', false); boundTestVisible('#sections-shortcuts', true); boundTestVisible('#more-extensions', true); + sidebar.enableEnhancedSiteControls = true; + flush(); + boundTestVisible('#sections-site-permissions', true); + let currentPage; navigation.addListener(newPage => { currentPage = newPage; @@ -81,6 +90,9 @@ sidebar.shadowRoot.querySelector('#sections-extensions').click(); expectDeepEquals(currentPage, {page: Page.LIST}); + sidebar.shadowRoot.querySelector('#sections-site-permissions').click(); + expectDeepEquals(currentPage, {page: Page.SITE_PERMISSIONS}); + // Clicking on the link for the current page should close the dialog. sidebar.addEventListener('close-drawer', () => done()); sidebar.shadowRoot.querySelector('#sections-extensions').click();
diff --git a/chrome/test/data/webui/inline_login/inline_login_browsertest.js b/chrome/test/data/webui/inline_login/inline_login_browsertest.js index 4bbbfb4..22672396 100644 --- a/chrome/test/data/webui/inline_login/inline_login_browsertest.js +++ b/chrome/test/data/webui/inline_login/inline_login_browsertest.js
@@ -52,6 +52,46 @@ }); GEN('#if BUILDFLAG(IS_CHROMEOS_ASH)'); +// TODO(crbug.com/1275568): Merge this test suite with the test above after the +// feature is launched. +// eslint-disable-next-line no-var +var InlineLoginBrowserTestWithArcAccountRestrictionsEnabled = + class extends InlineLoginBrowserTest { + /** @override */ + get featureList() { + return { + enabled: [ + 'chromeos::features::kArcAccountRestrictions', + 'chromeos::features::kLacrosSupport' + ] + }; + } +}; + +TEST_F( + 'InlineLoginBrowserTestWithArcAccountRestrictionsEnabled', 'Initialize', + function() { + this.runMochaTest(inline_login_test.TestNames.Initialize); + }); + +TEST_F( + 'InlineLoginBrowserTestWithArcAccountRestrictionsEnabled', 'WebUICallbacks', + function() { + this.runMochaTest(inline_login_test.TestNames.WebUICallbacks); + }); + +TEST_F( + 'InlineLoginBrowserTestWithArcAccountRestrictionsEnabled', + 'AuthExtHostCallbacks', function() { + this.runMochaTest(inline_login_test.TestNames.AuthExtHostCallbacks); + }); + +TEST_F( + 'InlineLoginBrowserTestWithArcAccountRestrictionsEnabled', 'BackButton', + function() { + this.runMochaTest(inline_login_test.TestNames.BackButton); + }); + // eslint-disable-next-line no-var var InlineLoginWelcomePageBrowserTest = class extends InlineLoginBrowserTest { /** @override */
diff --git a/chrome/test/data/webui/inline_login/inline_login_test.js b/chrome/test/data/webui/inline_login/inline_login_test.js index 97ac2a7..757538a 100644 --- a/chrome/test/data/webui/inline_login/inline_login_test.js +++ b/chrome/test/data/webui/inline_login/inline_login_test.js
@@ -124,7 +124,17 @@ const completeLoginResult = await testBrowserProxy.whenCalled('completeLogin'); assertTrue(inlineLoginComponent.$$('paper-spinner-lite').active); - assertEquals(fakeCredentials, completeLoginResult); + + if (isChromeOS && + loadTimeData.getBoolean('isArcAccountRestrictionsEnabled')) { + const expectedCredentials = { + email: 'example@gmail.com', + isAvailableInArc: false + }; + assertDeepEquals(expectedCredentials, completeLoginResult); + } else { + assertEquals(fakeCredentials, completeLoginResult); + } testAuthenticator.dispatchEvent(new Event('showIncognito')); assertEquals(1, testBrowserProxy.getCallCount('showIncognito'));
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js b/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js index be44b71..511466ea 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js
@@ -56,7 +56,9 @@ function checkToggle(permissionType, policyAffected) { const permissionToggle = getPermissionToggleByType(appDetailView, permissionType); - expectTrue(permissionToggle.$$('cr-toggle').disabled === policyAffected); + expectTrue( + permissionToggle.shadowRoot.querySelector('cr-toggle').disabled === + policyAffected); expectTrue( !!permissionToggle.root.querySelector('#policyIndicator') === policyAffected); @@ -71,6 +73,7 @@ const pinToShelfSetting = appDetailView.$$('#pin-to-shelf-setting') .$$('app-management-toggle-row'); expectTrue(!!pinToShelfSetting.root.querySelector('#policyIndicator')); - expectTrue(pinToShelfSetting.$$('cr-toggle').disabled); + expectTrue( + pinToShelfSetting.shadowRoot.querySelector('cr-toggle').disabled); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/test_util.js b/chrome/test/data/webui/settings/chromeos/app_management/test_util.js index 27ae275..93c73ad9 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/test_util.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/test_util.js
@@ -95,7 +95,7 @@ */ /* #export */ function getPermissionToggleByType(view, permissionType) { return getPermissionItemByType(view, permissionType) - .$$('app-management-toggle-row'); + .shadowRoot.querySelector('app-management-toggle-row'); } /** @@ -104,7 +104,8 @@ * @return {Element} */ /* #export */ function getPermissionCrToggleByType(view, permissionType) { - return getPermissionToggleByType(view, permissionType).$$('cr-toggle'); + return getPermissionToggleByType(view, permissionType) + .shadowRoot.querySelector('cr-toggle'); } /**
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/toggle_row_test.js b/chrome/test/data/webui/settings/chromeos/app_management/toggle_row_test.js index c0289b0..8de441b6 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/toggle_row_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/toggle_row_test.js
@@ -31,13 +31,13 @@ test('Toggle disabled by policy', async () => { toggleRow.setToggle(false); assertFalse(toggleRow.isChecked()); - assertFalse(!!toggleRow.$$('cr-toggle').disabled); - assertFalse(!!toggleRow.$$('cr-policy-indicator')); + assertFalse(!!toggleRow.shadowRoot.querySelector('cr-toggle').disabled); + assertFalse(!!toggleRow.shadowRoot.querySelector('cr-policy-indicator')); toggleRow.managed = true; await test_util.flushTasks(); - assertTrue(!!toggleRow.$$('cr-toggle').disabled); - assertTrue(!!toggleRow.$$('cr-policy-indicator')); + assertTrue(!!toggleRow.shadowRoot.querySelector('cr-toggle').disabled); + assertTrue(!!toggleRow.shadowRoot.querySelector('cr-policy-indicator')); toggleRow.click(); await test_util.flushTasks();
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js index 7ba5fa2..564174ab 100644 --- a/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js +++ b/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js
@@ -9,7 +9,7 @@ // #import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../../chai_assert.js'; // #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; // #import {TestMultideviceBrowserProxy} from './test_multidevice_browser_proxy.m.js'; -// #import {MultiDeviceBrowserProxyImpl, NotificationAccessSetupOperationStatus} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {MultiDeviceBrowserProxyImpl, PermissionsSetupStatus, PhoneHubPermissionsSetupMode} from 'chrome://os-settings/chromeos/os_settings.js'; // clang-format on /** @@ -27,7 +27,7 @@ let buttonContainer = null; /** - * @param {NotificationAccessSetupOperationStatus} status + * @param {PermissionsSetupStatus} status */ function simulateStatusChanged(status) { cr.webUIListenerCallback( @@ -35,6 +35,15 @@ Polymer.dom.flush(); } + /** + * @param {PermissionsSetupStatus} status + */ + function simulateAppsStatusChanged(status) { + cr.webUIListenerCallback('settings.onAppsAccessSetupStatusChanged', status); + Polymer.dom.flush(); + } + + /** @return {boolean} */ function isSetupInstructionsShownSeparately() { return permissionsSetupDialog.shouldShowSetupInstructionsSeparately_; @@ -52,7 +61,9 @@ buttonContainer = assert(permissionsSetupDialog.$$('#buttonContainer')); }); - test('Test success flow', async () => { + test('Test notification setup success flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; assertTrue(isSetupInstructionsShownSeparately()); assertTrue(!!buttonContainer.querySelector('#learnMore')); assertTrue(!!buttonContainer.querySelector('#cancelButton')); @@ -62,25 +73,24 @@ buttonContainer.querySelector('#getStartedButton').click(); assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); + simulateStatusChanged(PermissionsSetupStatus.CONNECTION_REQUESTED); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + simulateStatusChanged(PermissionsSetupStatus.CONNECTING); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + simulateStatusChanged( - NotificationAccessSetupOperationStatus.CONNECTION_REQUESTED); - assertTrue(isSetupInstructionsShownSeparately()); - assertFalse(!!buttonContainer.querySelector('#learnMore')); - assertTrue(!!buttonContainer.querySelector('#cancelButton')); - assertFalse(!!buttonContainer.querySelector('#getStartedButton')); - assertFalse(!!buttonContainer.querySelector('#doneButton')); - assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); - - simulateStatusChanged(NotificationAccessSetupOperationStatus.CONNECTING); - assertTrue(isSetupInstructionsShownSeparately()); - assertFalse(!!buttonContainer.querySelector('#learnMore')); - assertTrue(!!buttonContainer.querySelector('#cancelButton')); - assertFalse(!!buttonContainer.querySelector('#getStartedButton')); - assertFalse(!!buttonContainer.querySelector('#doneButton')); - assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); - - simulateStatusChanged(NotificationAccessSetupOperationStatus - .SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE); + PermissionsSetupStatus.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE); assertTrue(isSetupInstructionsShownSeparately()); assertFalse(!!buttonContainer.querySelector('#learnMore')); assertTrue(!!buttonContainer.querySelector('#cancelButton')); @@ -89,8 +99,7 @@ assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 0); - simulateStatusChanged( - NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY); + simulateStatusChanged(PermissionsSetupStatus.COMPLETED_SUCCESSFULLY); assertFalse(isSetupInstructionsShownSeparately()); assertFalse(!!buttonContainer.querySelector('#learnMore')); assertFalse(!!buttonContainer.querySelector('#cancelButton')); @@ -99,7 +108,7 @@ assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); // The feature becomes enabled when the status becomes - // NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY. + // PermissionsSetupStatus.COMPLETED_SUCCESSFULLY. assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 1); assertTrue(permissionsSetupDialog.$$('#dialog').open); @@ -107,7 +116,9 @@ assertFalse(permissionsSetupDialog.$$('#dialog').open); }); - test('Test cancel during connecting flow', async () => { + test('Test notification setup cancel during connecting flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertTrue(!!buttonContainer.querySelector('#getStartedButton')); assertFalse(!!buttonContainer.querySelector('#doneButton')); @@ -115,7 +126,7 @@ buttonContainer.querySelector('#getStartedButton').click(); assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); - simulateStatusChanged(NotificationAccessSetupOperationStatus.CONNECTING); + simulateStatusChanged(PermissionsSetupStatus.CONNECTING); assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertFalse(!!buttonContainer.querySelector('#getStartedButton')); @@ -128,7 +139,9 @@ assertFalse(permissionsSetupDialog.$$('#dialog').open); }); - test('Test failure during connecting flow', async () => { + test('Test notificaiton setup failure during connecting flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertTrue(!!buttonContainer.querySelector('#getStartedButton')); assertFalse(!!buttonContainer.querySelector('#doneButton')); @@ -136,8 +149,7 @@ buttonContainer.querySelector('#getStartedButton').click(); assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); - simulateStatusChanged( - NotificationAccessSetupOperationStatus.TIMED_OUT_CONNECTING); + simulateStatusChanged(PermissionsSetupStatus.TIMED_OUT_CONNECTING); assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertFalse(!!buttonContainer.querySelector('#getStartedButton')); @@ -154,8 +166,7 @@ assertFalse(!!buttonContainer.querySelector('#doneButton')); assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); - simulateStatusChanged( - NotificationAccessSetupOperationStatus.CONNECTION_DISCONNECTED); + simulateStatusChanged(PermissionsSetupStatus.CONNECTION_DISCONNECTED); assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertFalse(!!buttonContainer.querySelector('#getStartedButton')); @@ -169,6 +180,8 @@ }); test('Test notification access prohibited', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.NOTIFICATION_SETUP_MODE; assertTrue(!!buttonContainer.querySelector('#cancelButton')); assertTrue(!!buttonContainer.querySelector('#getStartedButton')); assertFalse(!!buttonContainer.querySelector('#doneButton')); @@ -178,7 +191,7 @@ assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); simulateStatusChanged( - NotificationAccessSetupOperationStatus.NOTIFICATION_ACCESS_PROHIBITED); + PermissionsSetupStatus.NOTIFICATION_ACCESS_PROHIBITED); assertFalse(!!buttonContainer.querySelector('#cancelButton')); assertFalse(!!buttonContainer.querySelector('#getStartedButton')); @@ -191,7 +204,180 @@ assertFalse(permissionsSetupDialog.$$('#dialog').open); }); + test('Test apps setup success flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.APPS_SETUP_MODE; + assertTrue(isSetupInstructionsShownSeparately()); + assertTrue(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + buttonContainer.querySelector('#getStartedButton').click(); + assertEquals(browserProxy.getCallCount('attemptAppsSetup'), 1); + + simulateAppsStatusChanged(PermissionsSetupStatus.CONNECTION_REQUESTED); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + simulateAppsStatusChanged(PermissionsSetupStatus.CONNECTING); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + simulateAppsStatusChanged( + PermissionsSetupStatus.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 0); + simulateAppsStatusChanged(PermissionsSetupStatus.COMPLETED_SUCCESSFULLY); + assertFalse(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertFalse(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertTrue(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + // The feature becomes enabled when the status becomes + // PermissionsSetupStatus.COMPLETED_SUCCESSFULLY. + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 1); + + assertTrue(permissionsSetupDialog.$$('#dialog').open); + buttonContainer.querySelector('#doneButton').click(); + assertFalse(permissionsSetupDialog.$$('#dialog').open); + }); + + test('Test apps setup cancel during connecting flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.APPS_SETUP_MODE; + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + buttonContainer.querySelector('#getStartedButton').click(); + assertEquals(browserProxy.getCallCount('attemptAppsSetup'), 1); + + simulateAppsStatusChanged(PermissionsSetupStatus.CONNECTING); + + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + buttonContainer.querySelector('#cancelButton').click(); + assertEquals(browserProxy.getCallCount('cancelAppsSetup'), 1); + + assertFalse(permissionsSetupDialog.$$('#dialog').open); + }); + + test('Test apps setup failure during connecting flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.APPS_SETUP_MODE; + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + buttonContainer.querySelector('#getStartedButton').click(); + assertEquals(browserProxy.getCallCount('attemptAppsSetup'), 1); + + simulateAppsStatusChanged(PermissionsSetupStatus.TIMED_OUT_CONNECTING); + + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertTrue(!!buttonContainer.querySelector('#tryAgainButton')); + + buttonContainer.querySelector('#tryAgainButton').click(); + assertEquals(browserProxy.getCallCount('attemptAppsSetup'), 2); + + Polymer.dom.flush(); + + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + simulateAppsStatusChanged(PermissionsSetupStatus.CONNECTION_DISCONNECTED); + + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertTrue(!!buttonContainer.querySelector('#tryAgainButton')); + + buttonContainer.querySelector('#cancelButton').click(); + assertEquals(browserProxy.getCallCount('cancelAppsSetup'), 1); + + assertFalse(permissionsSetupDialog.$$('#dialog').open); + }); + + test('Test notification and apps setup success flow', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE; + assertTrue(isSetupInstructionsShownSeparately()); + assertTrue(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertTrue(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + buttonContainer.querySelector('#getStartedButton').click(); + assertEquals(browserProxy.getCallCount('attemptNotificationSetup'), 1); + + simulateStatusChanged( + PermissionsSetupStatus.SENT_MESSAGE_TO_PHONE_AND_WAITING_FOR_RESPONSE); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 0); + + simulateStatusChanged(PermissionsSetupStatus.COMPLETED_SUCCESSFULLY); + assertTrue(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertTrue(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertFalse(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + // The phone hub notification feature becomes enabled when the status + // becomes PermissionsSetupStatus.COMPLETED_SUCCESSFULLY. + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 1); + assertEquals(browserProxy.getCallCount('attemptAppsSetup'), 1); + + simulateAppsStatusChanged(PermissionsSetupStatus.COMPLETED_SUCCESSFULLY); + assertFalse(isSetupInstructionsShownSeparately()); + assertFalse(!!buttonContainer.querySelector('#learnMore')); + assertFalse(!!buttonContainer.querySelector('#cancelButton')); + assertFalse(!!buttonContainer.querySelector('#getStartedButton')); + assertTrue(!!buttonContainer.querySelector('#doneButton')); + assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + + // The phone hub apps feature becomes enabled when the status + // becomes PermissionsSetupStatus.COMPLETED_SUCCESSFULLY. + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 2); + + assertTrue(permissionsSetupDialog.$$('#dialog').open); + buttonContainer.querySelector('#doneButton').click(); + assertFalse(permissionsSetupDialog.$$('#dialog').open); + }); + + test('Test phone enabled but ChromeOS disabled screen lock', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE; loadTimeData.overrideValues({isEcheAppEnabled: true}); loadTimeData.overrideValues({isPhoneScreenLockEnabled: true}); loadTimeData.overrideValues({isChromeosScreenLockEnabled: false}); @@ -200,6 +386,8 @@ }); test('Test phone and ChromeOS enabled screen lock', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE; loadTimeData.overrideValues({isEcheAppEnabled: true}); loadTimeData.overrideValues({isPhoneScreenLockEnabled: true}); loadTimeData.overrideValues({isChromeosScreenLockEnabled: true}); @@ -208,6 +396,8 @@ }); test('Test phone disabled but ChromeOS enabled screen lock', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE; loadTimeData.overrideValues({isEcheAppEnabled: true}); loadTimeData.overrideValues({isPhoneScreenLockEnabled: false}); loadTimeData.overrideValues({isChromeosScreenLockEnabled: true}); @@ -216,6 +406,8 @@ }); test('Test phone and ChromeOS disabled screen lock', async () => { + permissionsSetupDialog.phonePermissionSetupMode = + PhoneHubPermissionsSetupMode.ALL_PERMISSIONS_SETUP_MODE; loadTimeData.overrideValues({isEcheAppEnabled: true}); loadTimeData.overrideValues({isPhoneScreenLockEnabled: false}); loadTimeData.overrideValues({isChromeosScreenLockEnabled: false});
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_device_detail_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_device_detail_subpage_tests.js index 91af902b..eef514f 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_device_detail_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_device_detail_subpage_tests.js
@@ -9,11 +9,10 @@ // #import {Router, Route, routes} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {eventToPromise} from 'chrome://test/test_util.js'; -// #import {assertTrue, assertEquals, assertFalse} from '../../../chai_assert.js'; +// #import {waitAfterNextRender, eventToPromise} from 'chrome://test/test_util.js'; +// #import {assertTrue, assertEquals, assertFalse, assertNotEquals} from '../../../chai_assert.js'; // #import {createDefaultBluetoothDevice, FakeBluetoothConfig} from 'chrome://test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js'; // #import {setBluetoothConfigForTesting} from 'chrome://resources/cr_components/chromeos/bluetooth/cros_bluetooth_config.js'; -// #import {waitAfterNextRender} from 'chrome://test/test_util.js'; // clang-format on suite('OsBluetoothDeviceDetailPageTest', function() { @@ -159,7 +158,6 @@ assertFalse(!!getManagedIcon()); }); - test('Show change settings row, and navigate to subpages', async function() { init(); bluetoothConfig.setBluetoothEnabledState(/*enabled=*/ true); @@ -205,6 +203,19 @@ settings.Router.getInstance().getCurrentRoute(), settings.routes.POINTERS); + // Navigate back to the detail page. + assertNotEquals( + getChangeMouseSettings(), + bluetoothDeviceDetailPage.shadowRoot.activeElement); + let windowPopstatePromise = test_util.eventToPromise('popstate', window); + settings.Router.getInstance().navigateToPreviousRoute(); + await windowPopstatePromise; + + // Check that |#changeMouseSettings| has been focused. + assertEquals( + getChangeMouseSettings(), + bluetoothDeviceDetailPage.shadowRoot.activeElement); + device1.deviceProperties.deviceType = mojom.DeviceType.kKeyboard; bluetoothConfig.updatePairedDevice(device1); await flushAsync(); @@ -224,6 +235,24 @@ assertEquals( settings.Router.getInstance().getCurrentRoute(), settings.routes.KEYBOARD); + + // Navigate back to the detail page. + assertNotEquals( + getChangeKeyboardSettings(), + bluetoothDeviceDetailPage.shadowRoot.activeElement); + windowPopstatePromise = test_util.eventToPromise('popstate', window); + settings.Router.getInstance().navigateToPreviousRoute(); + await windowPopstatePromise; + + // Check that |#changeKeyboardSettings| has been focused. + assertEquals( + getChangeKeyboardSettings(), + bluetoothDeviceDetailPage.shadowRoot.activeElement); + + // This is needed or other tests will fail. + // TODO(gordonseto): Figure out how to remove this. + getChangeKeyboardSettings().click(); + await flushAsync(); }); test('Device becomes unavailable while viewing page.', async function() { @@ -280,6 +309,8 @@ bluetoothDeviceDetailPage.$$('#bluetoothDeviceNameLabel'); const getBluetoothDeviceBatteryInfo = () => bluetoothDeviceDetailPage.$$('#batteryInfo'); + const getNonAudioOutputDeviceMessage = () => + bluetoothDeviceDetailPage.$$('#nonAudioOutputDeviceMessage'); bluetoothConfig.setBluetoothEnabledState(/*enabled=*/ true); @@ -289,6 +320,7 @@ assertFalse(!!getBluetoothForgetBtn()); assertFalse(!!getBluetoothStateBtn()); assertFalse(!!getBluetoothDeviceBatteryInfo()); + assertFalse(!!getNonAudioOutputDeviceMessage()); const deviceNickname = 'device1'; const device1 = createDefaultBluetoothDevice( @@ -326,6 +358,7 @@ assertEquals( 'os-settings:bluetooth-connected', getBluetoothStatusIcon().icon); assertTrue(!!getBluetoothDeviceBatteryInfo()); + assertFalse(!!getNonAudioOutputDeviceMessage()); // Simulate disconnected state and not audio capable. device1.deviceProperties.connectionState = @@ -348,6 +381,23 @@ getBluetoothForgetBtn().ariaLabel, bluetoothDeviceDetailPage.i18n( 'bluetoothDeviceDetailForgetA11yLabel', deviceNickname)); + assertTrue(!!getNonAudioOutputDeviceMessage()); + assertEquals( + bluetoothDeviceDetailPage.i18n( + 'bluetoothDeviceDetailHIDMessageDisconnected'), + getNonAudioOutputDeviceMessage().textContent.trim()); + + // Simulate connected state and not audio capable. + device1.deviceProperties.connectionState = + mojom.DeviceConnectionState.kConnected; + bluetoothConfig.updatePairedDevice(device1); + await flushAsync(); + + assertTrue(!!getNonAudioOutputDeviceMessage()); + assertEquals( + bluetoothDeviceDetailPage.i18n( + 'bluetoothDeviceDetailHIDMessageConnected'), + getNonAudioOutputDeviceMessage().textContent.trim()); }); test(
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js index 1328221d..ea9416ff 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js
@@ -7,10 +7,12 @@ // #import 'chrome://os-settings/strings.m.js'; +// #import {Router, Route, routes} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertTrue} from '../../../chai_assert.js'; +// #import {assertTrue, assertEquals, assertNotEquals} from '../../../chai_assert.js'; // #import {createDefaultBluetoothDevice, FakeBluetoothConfig} from 'chrome://test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js'; // #import {setBluetoothConfigForTesting} from 'chrome://resources/cr_components/chromeos/bluetooth/cros_bluetooth_config.js'; +// #import {waitAfterNextRender, eventToPromise} from 'chrome://test/test_util.js'; // clang-format on suite('OsBluetoothDevicesSubpageTest', function() { @@ -35,6 +37,12 @@ setBluetoothConfigForTesting(bluetoothConfig); }); + teardown(function() { + bluetoothDevicesSubpage.remove(); + bluetoothDevicesSubpage = null; + settings.Router.getInstance().resetRouteForTesting(); + }); + function init() { bluetoothDevicesSubpage = document.createElement('os-settings-bluetooth-devices-subpage'); @@ -52,6 +60,8 @@ } }; bluetoothConfig.observeSystemProperties(propertiesObserver); + settings.Router.getInstance().navigateTo(settings.routes.BLUETOOTH_DEVICES); + return flushAsync(); } function flushAsync() { @@ -59,8 +69,8 @@ return new Promise(resolve => setTimeout(resolve)); } - test('Base Test', function() { - init(); + test('Base Test', async function() { + await init(); assertTrue(!!bluetoothDevicesSubpage); }); @@ -68,12 +78,12 @@ bluetoothConfig.setSystemState( chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); await flushAsync(); - init(); + await init(); assertTrue(bluetoothDevicesSubpage.$.enableBluetoothToggle.checked); }); test('Toggle button states', async function() { - init(); + await init(); const enableBluetoothToggle = bluetoothDevicesSubpage.$.enableBluetoothToggle; @@ -122,7 +132,7 @@ }); test('Device lists states', async function() { - init(); + await init(); const getNoDeviceText = () => bluetoothDevicesSubpage.shadowRoot.querySelector('#noDevices'); @@ -167,4 +177,78 @@ assertEquals(getDeviceList(/*connected=*/ false).devices.length, 1); assertFalse(!!getNoDeviceText()); }); + + test( + 'Device list items are focused on backward navigation', async function() { + await init(); + + const getDeviceList = (connected) => { + return bluetoothDevicesSubpage.shadowRoot.querySelector( + connected ? '#connectedDeviceList' : '#unconnectedDeviceList'); + }; + const getDeviceListItem = (connected, index) => { + return getDeviceList(connected).shadowRoot.querySelectorAll( + 'os-settings-paired-bluetooth-list-item')[index]; + }; + + const connectedDeviceId = '1'; + const connectedDevice = createDefaultBluetoothDevice( + /*id=*/ connectedDeviceId, /*publicName=*/ 'BeatsX', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected); + const unconnectedDeviceId = '2'; + const unconnectedDevice = createDefaultBluetoothDevice( + /*id=*/ unconnectedDeviceId, /*publicName=*/ 'MX 3', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kNotConnected); + bluetoothConfig.appendToPairedDeviceList([connectedDevice]); + bluetoothConfig.appendToPairedDeviceList([unconnectedDevice]); + await flushAsync(); + + assertTrue(!!getDeviceList(/*connected=*/ true)); + assertEquals(getDeviceList(/*connected=*/ true).devices.length, 1); + assertTrue(!!getDeviceList(/*connected=*/ false)); + assertEquals(getDeviceList(/*connected=*/ false).devices.length, 1); + + // Simulate navigating to the detail page of |connectedDevice|. + let params = new URLSearchParams(); + params.append('id', connectedDeviceId); + settings.Router.getInstance().navigateTo( + settings.routes.BLUETOOTH_DEVICE_DETAIL, params); + await flushAsync(); + + // Navigate backwards. + assertNotEquals( + getDeviceListItem(/*connected=*/ true, /*index=*/ 0), + getDeviceList(/*connected=*/ true).shadowRoot.activeElement); + let windowPopstatePromise = + test_util.eventToPromise('popstate', window); + settings.Router.getInstance().navigateToPreviousRoute(); + await windowPopstatePromise; + + // The first connected device list item should be focused. + assertEquals( + getDeviceListItem(/*connected=*/ true, /*index=*/ 0), + getDeviceList(/*connected=*/ true).shadowRoot.activeElement); + + // Simulate navigating to the detail page of |unconnectedDevice|. + params = new URLSearchParams(); + params.append('id', unconnectedDeviceId); + settings.Router.getInstance().navigateTo( + settings.routes.BLUETOOTH_DEVICE_DETAIL, params); + await flushAsync(); + + // Navigate backwards. + assertNotEquals( + getDeviceListItem(/*connected=*/ false, /*index=*/ 0), + getDeviceList(/*connected=*/ false).shadowRoot.activeElement); + windowPopstatePromise = test_util.eventToPromise('popstate', window); + settings.Router.getInstance().navigateToPreviousRoute(); + await windowPopstatePromise; + + // The first unconnected device list item should be focused. + assertEquals( + getDeviceListItem(/*connected=*/ false, /*index=*/ 0), + getDeviceList(/*connected=*/ false).shadowRoot.activeElement); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js index b69a0f1..0505a09a 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js
@@ -75,11 +75,10 @@ settings.routes.BLUETOOTH_DEVICES); // Navigate back to the top-level page. - await flushAsync(); assertNotEquals(iconButton, bluetoothSummary.shadowRoot.activeElement); + const windowPopstatePromise = test_util.eventToPromise('popstate', window); settings.Router.getInstance().navigateToPreviousRoute(); - await flushAsync(); - await waitAfterNextRender(bluetoothSummary); + await windowPopstatePromise; // Check that |iconButton| has been focused. assertEquals(iconButton, bluetoothSummary.shadowRoot.activeElement);
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 7aaa7106..3e7523f 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -179,6 +179,28 @@ // TODO(crbug.com/1234871) Move this test back into the list of tests below once // Bluetooth revamp is launched. +var OSSettingsOsBluetoothDevicesSubpageV3Test = + class extends OSSettingsV3BrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://os-settings/test_loader.html?module=settings/chromeos/os_bluetooth_devices_subpage_tests.m.js'; + } + + /** @override */ + get featureList() { + return { + enabled: + super.featureList.enabled.concat(['ash::features::kBluetoothRevamp']) + }; + } +}; + +TEST_F('OSSettingsOsBluetoothDevicesSubpageV3Test', 'AllJsTests', () => { + mocha.run(); +}); + +// TODO(crbug.com/1234871) Move this test back into the list of tests below once +// Bluetooth revamp is launched. var OSSettingsOsPairedBluetoothListItemV3Test = class extends OSSettingsV3BrowserTest { /** @override */ @@ -318,7 +340,6 @@ ['NetworkSummary', 'network_summary_test.m.js'], ['NetworkSummaryItem', 'network_summary_item_test.m.js'], ['OncMojoTest', 'onc_mojo_test.m.js'], - ['OsBluetoothDevicesSubpage', 'os_bluetooth_devices_subpage_tests.m.js'], ['OsBluetoothPage', 'os_bluetooth_page_tests.m.js'], ['OsBluetoothPairingDialog', 'os_bluetooth_pairing_dialog_tests.m.js'], ['OsBluetoothSummary', 'os_bluetooth_summary_tests.m.js'],
diff --git a/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js index f9dbdb1..b871dbd 100644 --- a/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.js
@@ -58,6 +58,8 @@ 'getAndroidSmsInfo', 'attemptNotificationSetup', 'cancelNotificationSetup', + 'attemptAppsSetup', + 'cancelAppsSetup', ]); this.data = createFakePageContentData( settings.MultiDeviceSettingsMode.NO_HOST_SET); @@ -126,6 +128,16 @@ this.methodCalled('cancelNotificationSetup'); } + /** @override */ + attemptAppsSetup() { + this.methodCalled('attemptAppsSetup'); + } + + /** @override */ + cancelAppsSetup() { + this.methodCalled('cancelAppsSetup'); + } + /** * @param {settings.MultiDeviceFeature} state */
diff --git a/chrome/test/data/webui/settings/search_engines_page_test.ts b/chrome/test/data/webui/settings/search_engines_page_test.ts index fcfe44d..a62ce73 100644 --- a/chrome/test/data/webui/settings/search_engines_page_test.ts +++ b/chrome/test/data/webui/settings/search_engines_page_test.ts
@@ -7,7 +7,7 @@ import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {CrInputElement, SettingsOmniboxExtensionEntryElement, SettingsSearchEngineDialogElement, SettingsSearchEngineEntryElement, SettingsSearchEnginesPageElement} from 'chrome://settings/lazy_load.js'; +import {CrInputElement, SettingsOmniboxExtensionEntryElement, SettingsSearchEngineDialogElement, SettingsSearchEngineEntryElement, SettingsSearchEnginesListElement, SettingsSearchEnginesPageElement} from 'chrome://settings/lazy_load.js'; import {ExtensionControlBrowserProxyImpl, loadTimeData, SearchEngine, SearchEnginesBrowserProxyImpl, SearchEnginesInfo, SearchEnginesInteractions} from 'chrome://settings/settings.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; @@ -177,6 +177,48 @@ entry.shadowRoot!.querySelector('#url-column')!.textContent); }); + // Test that the <search-engine-entry> is populated according to its + // underlying SearchEngine model. If the #omnibox-active-search-engines flag + // is enabled, show the shortcut column instead of the keyword column. + test('Initialization_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + assertEquals( + searchEngine.displayName, + entry.shadowRoot!.querySelector('#name-column')!.textContent!.trim()); + assertEquals( + searchEngine.keyword, + entry.shadowRoot!.querySelector('#shortcut-column')!.textContent); + assertEquals( + searchEngine.url, + entry.shadowRoot!.querySelector('#url-column')!.textContent); + }); + + // Tests that columns are hidden and shown appropriately. + test('ColumnVisibility_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + + // Test shortcut column visibility. + entry.set('showShortcut', true); + assertFalse( + entry.shadowRoot!.querySelector<HTMLElement>( + '#shortcut-column')!.hidden); + entry.set('showShortcut', false); + assertTrue(entry.shadowRoot!.querySelector<HTMLElement>( + '#shortcut-column')!.hidden); + + // Test query URL column visibility. + entry.set('showQueryUrl', true); + assertFalse( + entry.shadowRoot!.querySelector<HTMLElement>( + '#url-column-padded')!.hidden); + entry.set('showQueryUrl', false); + assertTrue( + entry.shadowRoot!.querySelector<HTMLElement>( + '#url-column-padded')!.hidden); + }); + test('Remove_Enabled', function() { // Open action menu. entry.shadowRoot!.querySelector('cr-icon-button')!.click(); @@ -233,6 +275,29 @@ return promise; }); + // Test that clicking the "edit" menu item fires an edit event. If the + // #omnibox-active-search-engines flag is enabled, the edit button is an icon + // button inline with the Search Engine entry and not in the 3-dot menu. + test('Edit_Enabled_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + + const engine = entry.engine; + const editButton = + entry.shadowRoot!.querySelector<HTMLButtonElement>(`#editIconButton`)!; + assertTrue(!!editButton); + assertFalse(editButton.hidden); + + const promise = eventToPromise('edit-search-engine', entry).then(e => { + assertEquals(engine, e.detail.engine); + assertEquals( + entry.shadowRoot!.querySelector('cr-icon-button'), + e.detail.anchorElement); + }); + editButton.click(); + return promise; + }); + /** * Checks that the given button is hidden for the given search engine. */ @@ -248,6 +313,26 @@ testButtonHidden(createSampleSearchEngine({canBeRemoved: false}), 'delete'); }); + test('Activate_Hidden_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + testButtonHidden( + createSampleSearchEngine({canBeActivated: false}), 'activate'); + }); + + test('Deactivate_Hidden_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + testButtonHidden( + createSampleSearchEngine({canBeDeactivated: false}), 'deactivate'); + }); + + test('Edit_Hidden_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + testButtonHidden( + createSampleSearchEngine({canBeActivated: true}), 'editIconButton'); + }); /** * Checks that the given button is disabled for the given search engine. */ @@ -268,8 +353,15 @@ testButtonDisabled(createSampleSearchEngine({canBeEdited: false}), 'edit'); }); + test('Edit_Disabled_ActiveFlagEnabled', function() { + entry.set('isActiveSearchEnginesFlagEnabled', true); + flush(); + testButtonDisabled( + createSampleSearchEngine({canBeEdited: false}), 'editIconButton'); + }); + // Test that clicking the "activate" button fires an activate event. - test('Activate', async function() { + test('Activate_ActiveFlagEnabled', async function() { entry.set('isActiveSearchEnginesFlagEnabled', true); flush(); entry.engine = createSampleSearchEngine({canBeActivated: true}); @@ -288,7 +380,7 @@ }); // Test that clicking the "Deactivate" button fires a deactivate event. - test('Deactivate', async function() { + test('Deactivate_ActiveFlagEnabled', async function() { entry.set('isActiveSearchEnginesFlagEnabled', true); flush(); entry.engine = createSampleSearchEngine({canBeDeactivated: true}); @@ -462,7 +554,8 @@ test('AddSearchEngineDialog', function() { assertFalse( !!page.shadowRoot!.querySelector('settings-search-engine-dialog')); - const addSearchEngineButton = page.$.addSearchEngine; + const addSearchEngineButton = + page.shadowRoot!.querySelector<HTMLButtonElement>('#addSearchEngine')!; assertTrue(!!addSearchEngineButton); addSearchEngineButton.click(); @@ -556,6 +649,174 @@ }); }); +suite('SearchEnginePageTests_ActiveFlagEnabled', function() { + let page: SettingsSearchEnginesPageElement; + let searchEnginesLists: NodeListOf<SettingsSearchEnginesListElement>; + let browserProxy: TestSearchEnginesBrowserProxy; + + const searchEnginesInfo: SearchEnginesInfo = { + defaults: [ + createSampleSearchEngine({id: 0}), + createSampleSearchEngine({id: 1}), + createSampleSearchEngine({id: 2}), + createSampleSearchEngine({id: 3}), + createSampleSearchEngine({id: 4}), + createSampleSearchEngine({id: 5}), + ], + actives: [createSampleSearchEngine({id: 6})], + others: [ + createSampleSearchEngine({id: 7}), + createSampleSearchEngine({id: 8}), + createSampleSearchEngine({id: 9}), + createSampleSearchEngine({id: 10}), + createSampleSearchEngine({id: 11}), + createSampleSearchEngine({id: 12}), + createSampleSearchEngine({id: 13}), + ], + extensions: [createSampleOmniboxExtension()], + }; + + setup(function() { + browserProxy = new TestSearchEnginesBrowserProxy(); + + // Purposefully pass a clone of |searchEnginesInfo| to avoid any + // mutations on ground truth data. + browserProxy.setSearchEnginesInfo({ + defaults: searchEnginesInfo.defaults.slice(), + actives: searchEnginesInfo.actives.slice(), + others: searchEnginesInfo.others.slice(), + extensions: searchEnginesInfo.extensions.slice(), + }); + loadTimeData.overrideValues({'isActiveSearchEnginesFlagEnabled': true}); + SearchEnginesBrowserProxyImpl.setInstance(browserProxy); + document.body.innerHTML = ''; + page = document.createElement('settings-search-engines-page'); + document.body.appendChild(page); + return browserProxy.whenCalled('getSearchEnginesList'); + }); + + teardown(function() { + page.remove(); + }); + + // Tests that the page is querying and displaying search engine info on + // startup. + test('Initialization', function() { + searchEnginesLists = + page.shadowRoot!.querySelectorAll('settings-search-engines-list'); + assertEquals(3, searchEnginesLists.length); + }); + + test('testDefaultsList', function() { + const defaultsListElement = searchEnginesLists[0]!; + + // The defaults list should only show the name and shortcut columns. + assertFalse( + defaultsListElement.shadowRoot!.querySelector('.name')!.hasAttribute( + 'hidden')); + assertFalse(defaultsListElement.shadowRoot!.querySelector('.shortcut')! + .hasAttribute('hidden')); + assertTrue( + defaultsListElement.shadowRoot!.querySelector('.url')!.hasAttribute( + 'hidden')); + + // The default engines list should not collapse and should show all entries + // in the list by default. + const lists = + defaultsListElement.shadowRoot!.querySelectorAll('dom-repeat')!; + assertEquals(1, lists.length); + const defaultsEntries = lists[0]!.items; + assertEquals(searchEnginesInfo.defaults.length, defaultsEntries!.length); + }); + + test('testActivesList', function() { + const activesListElement = searchEnginesLists[1]!; + + // The actives list should only show the name and shortcut columns. + assertFalse( + activesListElement.shadowRoot!.querySelector('.name')!.hasAttribute( + 'hidden')); + assertFalse( + activesListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute( + 'hidden')); + assertTrue( + activesListElement.shadowRoot!.querySelector('.url')!.hasAttribute( + 'hidden')); + + // With less than `visibleEnginesSize` elements in the list, all elements + // should be visible and the collapsible section should not be present. + const lists = activesListElement.shadowRoot!.querySelectorAll('dom-repeat'); + const visibleEntries = lists[0]!.items; + const collapsedEntries = lists[1]!.items; + assertEquals(searchEnginesInfo.actives.length, visibleEntries!.length); + assertEquals(0, collapsedEntries!.length); + + const expandButton = + activesListElement.shadowRoot!.querySelector('cr-expand-button'); + assertTrue(!!expandButton); + assertTrue(expandButton!.hasAttribute('hidden')); + }); + + test('testOthersList', function() { + const othersListElement = searchEnginesLists[2]!; + + // The others list should only show the name and url columns. + assertFalse( + othersListElement.shadowRoot!.querySelector('.name')!.hasAttribute( + 'hidden')); + assertTrue( + othersListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute( + 'hidden')); + assertFalse(othersListElement.shadowRoot!.querySelector('.url-padded')! + .hasAttribute('hidden')); + + // Any engines greater than `visibleEnginesSize` will be in a second list + // under the collapsible section. The button to expand this section must be + // visible. + const visibleEnginesSize = othersListElement.visibleEnginesSize; + const lists = othersListElement.shadowRoot!.querySelectorAll('dom-repeat'); + const visibleEntries = lists[0]!.items; + const collapsedEntries = lists[1]!.items; + assertEquals(visibleEnginesSize, visibleEntries!.length); + assertEquals( + searchEnginesInfo.others.length - visibleEnginesSize, + collapsedEntries!.length); + + const expandButton = + othersListElement.shadowRoot!.querySelector('cr-expand-button'); + assertTrue(!!expandButton); + assertFalse(expandButton!.hasAttribute('hidden')); + }); + + // Test that the "no other search engines" message is shown/hidden as + // expected. + test('NoSearchEnginesMessages', function() { + webUIListenerCallback('search-engines-changed', { + defaults: [], + actives: [], + others: [], + extensions: [], + }); + + const messageActive = page.shadowRoot!.querySelector('#noActiveEngines'); + assertTrue(!!messageActive); + assertFalse(messageActive!.hasAttribute('hidden')); + + const messageOther = page.shadowRoot!.querySelector('#noOtherEngines'); + assertTrue(!!messageOther); + assertFalse(messageOther!.hasAttribute('hidden')); + + webUIListenerCallback('search-engines-changed', { + defaults: [], + actives: [createSampleSearchEngine()], + others: [createSampleSearchEngine()], + extensions: [], + }); + assertTrue(messageActive!.hasAttribute('hidden')); + assertTrue(messageOther!.hasAttribute('hidden')); + }); +}); + suite('OmniboxExtensionEntryTests', function() { let entry: SettingsOmniboxExtensionEntryElement; let browserProxy: TestExtensionControlBrowserProxy;
diff --git a/chrome/test/webapps/coverage/coverage_cros.tsv b/chrome/test/webapps/coverage/coverage_cros.tsv index 828fe58..e255f48e 100644 --- a/chrome/test/webapps/coverage/coverage_cros.tsv +++ b/chrome/test/webapps/coverage/coverage_cros.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 49%, with partial coverage: 69% +# Full coverage: 44%, with partial coverage: 63% install_create_shortcut_windowed_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_omnibox_icon_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_menu_option_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 @@ -33,19 +33,19 @@ install_menu_option_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 @@ -72,7 +72,7 @@ install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -157,7 +157,7 @@ install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -165,74 +165,74 @@ install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 install_create_shortcut_tabbed_SiteA🌕 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -252,7 +252,7 @@ install_menu_option_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_standalone🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 @@ -330,14 +330,14 @@ install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_menu_option_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_launch_icon_SiteC🌕 check_window_created🌕 -install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌓 check_window_created🌕 +install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 install_create_shortcut_windowed_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_omnibox_icon_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_menu_option_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 @@ -370,12 +370,12 @@ install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_install_icon_not_shown🌑 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_launch_icon_shown🌑 navigate_browser_SiteAFoo🌕 check_install_icon_shown🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_create_shortcut_not_shown🌑 navigate_browser_SiteA🌕 check_app_not_in_list_SiteA🌓 @@ -463,13 +463,13 @@ install_policy_app_windowed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 @@ -483,7 +483,7 @@ install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 check_app_in_list_tabbed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_omnibox_icon_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -526,16 +526,16 @@ install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteC🌕 uninstall_from_list_SiteC🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_tabbed_SiteC🌕 uninstall_from_list_SiteC🌕 check_platform_shortcut_not_exists_SiteC🌑
diff --git a/chrome/test/webapps/coverage/coverage_linux.tsv b/chrome/test/webapps/coverage/coverage_linux.tsv index 0f2ce8b9..6dae7b27 100644 --- a/chrome/test/webapps/coverage/coverage_linux.tsv +++ b/chrome/test/webapps/coverage/coverage_linux.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 52%, with partial coverage: 72% +# Full coverage: 47%, with partial coverage: 67% install_create_shortcut_windowed_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_omnibox_icon_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_menu_option_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 @@ -33,19 +33,19 @@ install_menu_option_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 @@ -95,7 +95,7 @@ install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -180,7 +180,7 @@ install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -188,57 +188,57 @@ install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_menu_option_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 @@ -264,19 +264,19 @@ install_policy_app_tabbed_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -296,7 +296,7 @@ install_menu_option_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_standalone🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 @@ -374,14 +374,14 @@ install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_menu_option_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_launch_icon_SiteC🌕 check_window_created🌕 -install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌓 check_window_created🌕 +install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 install_create_shortcut_windowed_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_omnibox_icon_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_menu_option_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 @@ -414,12 +414,12 @@ install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_install_icon_not_shown🌑 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_launch_icon_shown🌑 navigate_browser_SiteAFoo🌕 check_install_icon_shown🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_create_shortcut_not_shown🌑 navigate_browser_SiteA🌕 check_app_not_in_list_SiteA🌓 @@ -507,13 +507,13 @@ install_policy_app_windowed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 @@ -527,7 +527,7 @@ install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 check_app_in_list_tabbed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_omnibox_icon_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -581,25 +581,25 @@ install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_platform_shortcut_not_exists_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑
diff --git a/chrome/test/webapps/coverage/coverage_mac.tsv b/chrome/test/webapps/coverage/coverage_mac.tsv index 0f2ce8b9..bcdfada 100644 --- a/chrome/test/webapps/coverage/coverage_mac.tsv +++ b/chrome/test/webapps/coverage/coverage_mac.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 52%, with partial coverage: 72% +# Full coverage: 40%, with partial coverage: 57% install_create_shortcut_windowed_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_omnibox_icon_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_menu_option_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 @@ -33,42 +33,42 @@ install_menu_option_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 +install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 install_omnibox_icon_SiteA🌕 check_window_created🌕 install_menu_option_SiteA🌕 check_window_created🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_platform_shortcut_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_platform_shortcut_exists_SiteA🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_platform_shortcut_exists_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_platform_shortcut_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_app_in_list_tabbed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_app_in_list_windowed_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_app_in_list_windowed_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 check_app_in_list_windowed_SiteA🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_app_in_list_windowed_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_app_in_list_windowed_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 check_app_in_list_windowed_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_create_shortcut_windowed_SiteC🌕 switch_profile_clients_Client2🌕 install_locally_SiteC🌓 check_platform_shortcut_exists_SiteC🌑 install_create_shortcut_tabbed_SiteC🌕 switch_profile_clients_Client2🌕 install_locally_SiteC🌓 check_platform_shortcut_exists_SiteC🌑 install_create_shortcut_tabbed_SiteC🌕 switch_profile_clients_Client2🌕 install_locally_SiteC🌓 check_app_in_list_tabbed_SiteC🌓 @@ -95,7 +95,7 @@ install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -134,17 +134,17 @@ install_policy_app_windowed_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteA🌕 check_create_shortcut_not_shown🌑 -install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌕 check_create_shortcut_not_shown🌑 +install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌑 check_create_shortcut_not_shown🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_create_shortcut_not_shown🌑 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_create_shortcut_not_shown🌑 install_menu_option_SiteA🌕 navigate_browser_SiteA🌕 check_create_shortcut_not_shown🌑 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 +install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_menu_option_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_omnibox_icon_SiteA🌕 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_menu_option_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -180,103 +180,103 @@ install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_menu_option_SiteA🌑 check_tab_created🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_menu_option_SiteA🌑 check_tab_created🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_menu_option_SiteA🌑 check_tab_created🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_menu_option_SiteA🌑 check_tab_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_chrome_apps_SiteA🌑 check_tab_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_menu_option_SiteA🌑 check_tab_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_chrome_apps_SiteA🌑 check_tab_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_menu_option_SiteA🌑 check_tab_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_chrome_apps_SiteA🌑 check_tab_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 install_locally_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_tabbed_SiteA🌕 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -285,7 +285,7 @@ install_omnibox_icon_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 @@ -296,7 +296,7 @@ install_menu_option_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_standalone🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 @@ -305,7 +305,7 @@ install_omnibox_icon_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 -install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_display_standalone🌕 +install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 install_policy_app_windowed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_policy_app_windowed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 install_policy_app_windowed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 @@ -341,7 +341,7 @@ install_create_shortcut_windowed_SiteB🌕 launch_from_platform_shortcut_SiteB🌑 check_window_display_minimal🌑 install_omnibox_icon_SiteB🌕 launch_from_menu_option_SiteB🌑 check_window_display_minimal🌑 install_omnibox_icon_SiteB🌕 launch_from_launch_icon_SiteB🌕 check_window_display_minimal🌕 -install_omnibox_icon_SiteB🌕 launch_from_chrome_apps_SiteB🌓 check_window_display_minimal🌕 +install_omnibox_icon_SiteB🌕 launch_from_chrome_apps_SiteB🌑 check_window_display_minimal🌑 install_omnibox_icon_SiteB🌕 launch_from_platform_shortcut_SiteB🌑 check_window_display_minimal🌑 install_policy_app_windowed_no_shortcut_SiteB🌓 launch_from_menu_option_SiteB🌑 check_window_display_minimal🌑 install_policy_app_windowed_no_shortcut_SiteB🌓 launch_from_launch_icon_SiteB🌕 check_window_display_minimal🌕 @@ -370,18 +370,18 @@ install_create_shortcut_windowed_SiteC🌕 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_menu_option_SiteC🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_launch_icon_SiteC🌕 check_window_created🌕 -install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌓 check_window_created🌕 +install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌑 check_window_created🌑 install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_menu_option_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_launch_icon_SiteC🌕 check_window_created🌕 -install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌓 check_window_created🌕 +install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 install_create_shortcut_windowed_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_omnibox_icon_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_menu_option_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 @@ -414,12 +414,12 @@ install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_install_icon_not_shown🌑 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_launch_icon_shown🌑 navigate_browser_SiteAFoo🌕 check_install_icon_shown🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_create_shortcut_not_shown🌑 navigate_browser_SiteA🌕 check_app_not_in_list_SiteA🌓 @@ -507,15 +507,15 @@ install_policy_app_windowed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌑 uninstall_policy_app_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌑 uninstall_policy_app_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 set_app_badge_SiteA🌑 check_app_badge_has_value_SiteA🌑 @@ -527,7 +527,7 @@ install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 check_app_in_list_tabbed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_omnibox_icon_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -535,71 +535,71 @@ install_omnibox_icon_SiteA🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_menu_option_SiteA🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 check_app_in_list_not_locally_installed_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_create_shortcut_windowed_SiteC🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteC🌓 install_create_shortcut_tabbed_SiteC🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteC🌓 install_create_shortcut_windowed_SiteC🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteC🌑 install_create_shortcut_tabbed_SiteC🌕 switch_profile_clients_Client2🌕 check_platform_shortcut_not_exists_SiteC🌑 sync_turn_off🌕 install_create_shortcut_windowed_SiteA🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 sync_turn_off🌕 install_omnibox_icon_SiteA🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 -sync_turn_off🌕 install_menu_option_SiteA🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 +sync_turn_off🌕 install_menu_option_SiteA🌑 sync_turn_on🌑 switch_profile_clients_Client2🌑 check_app_in_list_not_locally_installed_SiteA🌑 sync_turn_off🌕 install_create_shortcut_tabbed_SiteA🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteA🌓 -sync_turn_off🌕 install_create_shortcut_windowed_SiteC🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteC🌓 +sync_turn_off🌕 install_create_shortcut_windowed_SiteC🌑 sync_turn_on🌑 switch_profile_clients_Client2🌑 check_app_in_list_not_locally_installed_SiteC🌑 sync_turn_off🌕 install_create_shortcut_tabbed_SiteC🌕 sync_turn_on🌕 switch_profile_clients_Client2🌕 check_app_in_list_not_locally_installed_SiteC🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_app_in_list_not_locally_installed_SiteA🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_app_in_list_not_locally_installed_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_list_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 sync_turn_off🌑 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_list_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌕 sync_turn_on🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 sync_turn_off🌕 uninstall_from_menu_SiteA🌑 sync_turn_on🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_platform_shortcut_not_exists_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 @@ -609,11 +609,11 @@ install_create_shortcut_windowed_SiteC🌕 uninstall_from_menu_SiteC🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteC🌕 uninstall_from_list_SiteC🌕 check_platform_shortcut_not_exists_SiteC🌑 install_create_shortcut_windowed_SiteC🌕 uninstall_from_menu_SiteC🌕 check_platform_shortcut_not_exists_SiteC🌑 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 switch_profile_clients_Client1🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 switch_profile_clients_Client1🌕 check_app_not_in_list_SiteA🌓 -install_menu_option_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 switch_profile_clients_Client1🌕 check_app_not_in_list_SiteA🌓 +install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 switch_profile_clients_Client1🌑 check_app_not_in_list_SiteA🌑 +install_omnibox_icon_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 switch_profile_clients_Client1🌑 check_app_not_in_list_SiteA🌑 +install_menu_option_SiteA🌕 switch_profile_clients_Client2🌑 uninstall_from_list_SiteA🌑 switch_profile_clients_Client1🌑 check_app_not_in_list_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 uninstall_from_list_SiteA🌕 switch_profile_clients_Client1🌕 check_app_not_in_list_SiteA🌓
diff --git a/chrome/test/webapps/coverage/coverage_win.tsv b/chrome/test/webapps/coverage/coverage_win.tsv index 3aa676fc8..b06fc28 100644 --- a/chrome/test/webapps/coverage/coverage_win.tsv +++ b/chrome/test/webapps/coverage/coverage_win.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 52%, with partial coverage: 72% +# Full coverage: 47%, with partial coverage: 67% install_create_shortcut_windowed_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_omnibox_icon_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 install_menu_option_SiteA🌕 set_app_badge_SiteA🌑 clear_app_badge_SiteA🌑 check_app_badge_empty_SiteA🌑 @@ -33,19 +33,19 @@ install_menu_option_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_tabbed_SiteA🌕 delete_profile🌑 check_platform_shortcut_not_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 check_window_created🌕 @@ -95,7 +95,7 @@ install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌑 check_launch_icon_shown🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -183,7 +183,7 @@ install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_tabbed_SiteA🌕 switch_profile_clients_Client2🌕 install_locally_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -191,57 +191,57 @@ install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_minimal🌕 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_display_minimal_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_color_correct🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_colors_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_color_correct🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_standalone🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_browser_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_menu_option_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_launch_icon_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_chrome_apps_SiteA🌑 check_window_display_minimal🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_display_minimal_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_window_display_minimal🌑 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_menu_option_SiteA🌑 check_tab_created🌑 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_chrome_apps_SiteA🌓 check_tab_created🌕 install_create_shortcut_windowed_SiteA🌕 switch_profile_clients_Client2🌕 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 @@ -267,19 +267,19 @@ install_policy_app_tabbed_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 delete_platform_shortcut_SiteA🌑 create_shortcuts_SiteA🌑 launch_from_platform_shortcut_SiteA🌑 check_tab_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 -install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 +install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_menu_option_SiteA🌑 check_window_created🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_launch_icon_SiteA🌕 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_policy_app_tabbed_no_shortcut_SiteA🌓 set_open_in_window_SiteA🌓 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_created🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_created🌑 @@ -299,7 +299,7 @@ install_menu_option_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_created🌕 install_menu_option_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_created🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 -install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌕 check_window_display_standalone🌕 +install_create_shortcut_windowed_SiteA🌕 launch_from_launch_icon_SiteA🌑 check_window_display_standalone🌑 install_create_shortcut_windowed_SiteA🌕 launch_from_chrome_apps_SiteA🌓 check_window_display_standalone🌕 install_create_shortcut_windowed_SiteA🌕 launch_from_platform_shortcut_SiteA🌑 check_window_display_standalone🌑 install_omnibox_icon_SiteA🌕 launch_from_menu_option_SiteA🌑 check_window_display_standalone🌑 @@ -377,14 +377,14 @@ install_policy_app_windowed_no_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_menu_option_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_launch_icon_SiteC🌕 check_window_created🌕 -install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌓 check_window_created🌕 +install_policy_app_windowed_shortcut_SiteC🌓 launch_from_chrome_apps_SiteC🌑 check_window_created🌑 install_policy_app_windowed_shortcut_SiteC🌓 launch_from_platform_shortcut_SiteC🌑 check_window_created🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 -install_create_shortcut_windowed_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_omnibox_icon_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 -install_menu_option_SiteA🌕 close_pwa🌕 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_app_in_list_icon_correct_SiteA🌑 +install_create_shortcut_windowed_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_omnibox_icon_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 +install_menu_option_SiteA🌕 close_pwa🌑 manifest_update_icons_SiteA🌑 check_platform_shortcut_icon_correct_SiteA🌑 install_create_shortcut_windowed_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_omnibox_icon_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 install_menu_option_SiteAFoo🌕 manifest_update_scope_site_a_foo_to_SiteA🌑 close_pwa🌑 launch_from_platform_shortcut_SiteAFoo🌑 close_pwa🌑 navigate_browser_SiteA🌑 check_install_icon_not_shown🌑 @@ -417,12 +417,12 @@ install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_install_icon_not_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_install_icon_not_shown🌑 install_create_shortcut_windowed_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_omnibox_icon_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_no_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 install_policy_app_windowed_shortcut_SiteA🌓 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 -install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌕 check_launch_icon_shown🌕 +install_menu_option_SiteA🌕 navigate_browser_SiteAFoo🌑 check_launch_icon_shown🌑 navigate_browser_SiteAFoo🌕 check_install_icon_shown🌕 switch_incognito_profile🌑 navigate_browser_SiteA🌑 check_create_shortcut_not_shown🌑 navigate_browser_SiteA🌕 check_app_not_in_list_SiteA🌓 @@ -510,13 +510,13 @@ install_policy_app_windowed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 uninstall_policy_app_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 check_app_not_in_list_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_app_in_list_windowed_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_app_in_list_windowed_SiteA🌓 install_policy_app_tabbed_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 -install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 +install_policy_app_tabbed_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌑 uninstall_policy_app_SiteA🌑 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_shortcut_SiteA🌓 install_menu_option_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 install_policy_app_tabbed_no_shortcut_SiteA🌓 install_omnibox_icon_SiteA🌕 uninstall_policy_app_SiteA🌕 check_platform_shortcut_exists_SiteA🌑 @@ -530,7 +530,7 @@ install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 check_app_in_list_tabbed_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_omnibox_icon_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_menu_option_SiteA🌕 set_open_in_tab_SiteA🌓 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 @@ -584,25 +584,25 @@ install_create_shortcut_tabbed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_app_not_in_list_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_app_not_in_list_SiteA🌓 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_app_not_in_list_SiteA🌓 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_install_icon_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_install_icon_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 navigate_browser_SiteA🌑 check_launch_icon_not_shown🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 navigate_browser_SiteA🌕 check_launch_icon_not_shown🌕 install_create_shortcut_windowed_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_create_shortcut_windowed_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 -install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 +install_omnibox_icon_SiteA🌕 uninstall_from_list_SiteA🌑 check_platform_shortcut_not_exists_SiteA🌑 install_omnibox_icon_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_list_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑 install_menu_option_SiteA🌕 uninstall_from_menu_SiteA🌕 check_platform_shortcut_not_exists_SiteA🌑
diff --git a/chrome/tools/build/PRESUBMIT.py b/chrome/tools/build/PRESUBMIT.py index de30406..6f7af4bc 100644 --- a/chrome/tools/build/PRESUBMIT.py +++ b/chrome/tools/build/PRESUBMIT.py
@@ -9,7 +9,7 @@ """ USE_PYTHON3 = True -_PLATFORMS = ['chromeos'] +_PLATFORMS = ['chromeos', 'win'] def _CheckChange(input_api, output_api): results = []
diff --git a/chrome/tools/build/README.md b/chrome/tools/build/README.md index 3681b2498..d9f40d8 100644 --- a/chrome/tools/build/README.md +++ b/chrome/tools/build/README.md
@@ -1,6 +1,7 @@ -'FILES.cfg' for each platform is now obsolete (crbug/1260176). New config files -for archiving build artifacts are located in src/infra/archive_config for dev -builders and in src-internal/testing/buildbot/archive for official builders. +'FILES.cfg' for each platform is now obsolete with respect to archiving +(crbug/1260176). New config files for archiving build artifacts are located in +src/infra/archive_config for dev builders and in +src-internal/testing/buildbot/archive for official builders. For more information on how these files are used, refer to the proto file within the archive module: https://chromium.googlesource.com/chromium/tools/build.git/+/HEAD/recipes/recipe_modules/archive/properties.proto
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg new file mode 100644 index 0000000..d8546442 --- /dev/null +++ b/chrome/tools/build/win/FILES.cfg
@@ -0,0 +1,995 @@ +# -*- python -*- +# ex: set syntax=python: + +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# NOTE: This file is now obsolete for 'dev' and 'official' builders with +# respect to archiving. The new configs can be found in the json files within +# infra/archive_config for dev builders and +# src-internal/testing/buildbot/archive for official builders. crbug/1260176 + +# This is a buildbot configuration file containing a tagged list of files +# processed by the stage/archive scripts. The known tags are: +# +# filename: Name of the file in the build output directory. +# arch: List of CPU architectures for which this file should be processed +# Leave this unspecified to process for all architectures. +# Acceptable values are 64bit, 32bit and arm. +# buildtype: List of build types for which this file should be processed. +# archive: The name of the archive file to store filename in. If not specified, +# filename is added to the default archive (e.g. platform.zip). If +# archive == filename, filename is archived directly, not zipped. +# direct_archive: Force a file to be archived as-is, bypassing zip creation. +# NOTE: This flag will not apply if more than one file has the +# same 'archive' name, which will create a zip of all the +# files instead. +# filegroup: List of named groups to which this file belongs. +# default: Legacy "default archive". TODO(mmoss): These should +# be updated to specify an 'archive' name and then this +# filegroup and the related archive_utils.ParseLegacyList() +# should go away. +# symsrc: Files to upload to the symbol server. +# optional: List of buildtypes for which the file might not exist, and it's not +# considered an error. + +FILES = [ + { + 'filename': 'browser_tests.exe', + 'buildtype': ['official'], + 'archive': 'browser_tests.exe', + 'optional': ['official'], + }, + { + 'filename': 'sync_integration_tests.exe', + 'buildtype': ['official'], + 'archive': 'sync_integration_tests.exe', + 'optional': ['official'], + }, + { + 'filename': 'chrome.exe', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'nacl64.exe', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'chrome.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'chrome_child.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + 'optional': ['official'], + }, + { + 'filename': 'chrome_elf.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'eventlog_provider.dll', + 'buildtype': ['official'], + 'filegroup': ['default'], + }, + { + 'filename': '*.manifest', + 'buildtype': ['official'], + 'filegroup': ['default'], + }, + { + 'filename': 'chrome_100_percent.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'chrome_200_percent.pak', + 'buildtype': ['official'], + 'optional': ['official'], + }, + { + 'filename': 'First Run', + 'buildtype': ['official'], + }, + { + 'filename': 'icudtl.dat', + 'buildtype': ['official'], + 'optional': ['official'], + }, + { + 'filename': 'icudt.dll', + 'buildtype': ['official'], + 'optional': ['official'], + }, + { + 'filename': 'mojo_core.dll', + 'buildtype': ['official'], + 'optional': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'v8_context_snapshot.bin', + 'buildtype': ['official'], + 'optional': ['official'], + }, + { + 'filename': 'locales/ar.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/bg.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/bn.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ca.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/cs.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/da.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/de.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/el.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/en-GB.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/en-US.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/es-419.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/es.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/et.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/fi.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/fil.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/fr.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/gu.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/he.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/hi.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/hr.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/hu.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/id.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/it.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ja.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/kn.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ko.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/lt.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/lv.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ml.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/mr.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ms.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/nb.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/nl.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/pl.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/pt-BR.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/pt-PT.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ro.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ru.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/sk.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/sl.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/sr.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/sv.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/ta.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/te.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/th.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/tr.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/uk.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/vi.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/zh-CN.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'locales/zh-TW.pak', + 'buildtype': ['official'], + }, + { + 'filename': 'policy_templates.zip', + 'buildtype': ['official'], + 'archive': 'policy_templates.zip', + }, + { + 'filename': 'resources.pak', + 'buildtype': ['official'], + }, + # PNaCl translator (archive only, component updater used for shipping). + { + 'filename': 'pnacl', + 'buildtype': ['official'], + 'archive': 'pnacl.zip', + }, + # Widevine CDM files: + { + 'filename': 'WidevineCdm/manifest.json', + 'buildtype': ['official'], + }, + { + 'filename': 'WidevineCdm/LICENSE', + 'buildtype': ['official'], + }, + { + 'filename': 'WidevineCdm/_platform_specific/win_x86/widevinecdm.dll', + 'arch': ['32bit'], + 'buildtype': ['official'], + }, + { + 'filename': 'WidevineCdm/_platform_specific/win_x86/widevinecdm.dll.sig', + 'arch': ['32bit'], + 'buildtype': ['official'], + }, + { + 'filename': 'WidevineCdm/_platform_specific/win_x64/widevinecdm.dll', + 'arch': ['64bit'], + 'buildtype': ['official'], + }, + { + 'filename': 'WidevineCdm/_platform_specific/win_x64/widevinecdm.dll.sig', + 'arch': ['64bit'], + 'buildtype': ['official'], + }, + # ANGLE files: + { + 'filename': 'D3DCompiler_47.dll', + 'buildtype': ['official'], + }, + { + 'filename': 'libEGL.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'libGLESv2.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'vulkan-1.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + # SwiftShader files: + { + 'filename': 'swiftshader/libEGL.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'swiftshader/libGLESv2.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'vk_swiftshader.dll', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'vk_swiftshader_icd.json', + 'buildtype': ['official'], + }, + # Native Client plugin files: + { + 'filename': 'nacl_irt_x86_32.nexe', + 'arch': ['32bit'], + 'buildtype': ['official'], + }, + { + 'filename': 'nacl_irt_x86_64.nexe', + 'buildtype': ['official'], + }, + # Remoting files: + { + 'filename': 'chromoting.msi', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'archive': 'remoting-host.msi', + 'direct_archive': 1, + 'optional': ['dev'], + }, + { + 'filename': 'remoting-me2me-host-win.zip', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'archive': 'remoting-me2me-host-win.zip', + 'direct_archive': 1, + 'optional': ['dev'], + }, + { + 'filename': 'remoting-me2me-host-win-unsupported.zip', + 'arch': ['64bit'], + 'buildtype': ['official'], + 'archive': 'remoting-me2me-host-win-unsupported.zip', + 'direct_archive': 1, + 'optional': ['dev'], + }, + { + 'filename': 'remote_assistance_host.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remote_assistance_host.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + { + 'filename': 'remote_assistance_host_uiaccess.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remote_assistance_host_uiaccess.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + { + 'filename': 'remote_security_key.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remote_security_key.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + { + 'filename': 'remoting_core.dll', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remoting_core.dll.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'optional': ['official'], + }, + { + 'filename': 'remoting_desktop.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remoting_desktop.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'optional': ['official'], + }, + { + 'filename': 'remoting_host.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remoting_host.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + { + 'filename': 'remoting_native_messaging_host.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remoting_native_messaging_host.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + { + 'filename': 'remoting_start_host.exe', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'remoting_start_host.exe.pdb', + 'buildtype': ['official'], + 'archive': 'remoting-win32.zip', + }, + # Credential Provider: + { + 'filename': 'gcp_setup.exe', + 'buildtype': ['official'], + 'optional': ['official'], + 'filegroup': ['symsrc'], + }, + { + 'filename': 'gcp_setup.exe.pdb', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'gaia1_0.dll', + 'buildtype': ['official'], + 'optional': ['official'], + 'filegroup': ['symsrc'], + }, + { + 'filename': 'gaia1_0.dll.pdb', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'gcp_installer.exe', + 'buildtype': ['official'], + 'archive': 'gcp_installer.exe', + 'filegroup': ['symsrc'], + }, + # Cloud Print files: + { + 'filename': 'gcp_portmon.dll', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'gcp_portmon.dll.pdb', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + 'optional': ['official'], + }, + { + 'filename': 'gcp_portmon64.dll', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'gcp_driver.inf', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + }, + { + 'filename': 'gcp_driver.gpd', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + }, + { + 'filename': 'virtual_driver_setup.exe', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'virtual_driver_setup.exe.pdb', + 'buildtype': ['official'], + 'archive': 'cloud_print.zip', + }, + # Test binaries for external QA: + { + 'filename': 'interactive_ui_tests.exe', + 'buildtype': ['official'], + 'optional': ['official'], + }, + # Notification helper files: + { + 'filename': 'notification_helper.exe', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'notification_helper.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + # Installer files (official build only): + { + 'filename': 'setup.exe', + 'buildtype': ['official'], + 'archive': 'setup.exe', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'mini_installer.exe', + 'buildtype': ['official'], + 'archive': 'mini_installer.exe', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'chrome.packed.7z', + 'buildtype': ['official'], + 'archive': 'chrome.packed.7z', + }, + { + 'filename': 'mini_installer_exe_version.rc', + 'buildtype': ['official'], + 'archive': 'mini_installer_exe_version.rc', + }, + { + 'filename': 'courgette.exe', + 'buildtype': ['official'], + 'archive': 'courgette.exe', + }, + { + 'filename': 'courgette64.exe', + 'buildtype': ['official'], + 'archive': 'courgette64.exe', + }, + { + 'filename': 'zucchini.exe', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'zucchini.exe', + }, + { + 'filename': 'zucchini.exe.pdb', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'chrome.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'chrome_child.dll.pdb', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'chrome_elf.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'chrome.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'eventlog_provider.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'libEGL.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'libGLESv2.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'vulkan-1.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'mojo_core.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'swiftshader/libEGL.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'swiftshader/libGLESv2.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'vk_swiftshader.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'mini_installer.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'nacl64.exe.pdb', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'setup.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + # Updater files: + { + 'filename': 'updater.zip', + 'buildtype': ['official'], + 'optional': ['official'], + 'archive': 'updater.zip' + }, + # Partner API files. + { + 'filename': 'gcapi.h', + 'buildtype': ['official'], + 'archive': 'gcapi.zip', + }, + { + 'filename': 'gcapi_dll.dll', + 'buildtype': ['official'], + 'archive': 'gcapi.zip', + 'filegroup': ['symsrc'], + }, + { + 'filename': 'gcapi_dll.dll.lib', + 'buildtype': ['official'], + 'archive': 'gcapi.zip', + }, + { + 'filename': 'gcapi_dll.dll.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + { + 'filename': 'nacl_irt_x86_32.nexe.debug', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'archive': 'chrome-win32-nacl-irt-syms.zip', + }, + { + 'filename': 'nacl_irt_x86_64.nexe.debug', + 'buildtype': ['official'], + 'archive': 'chrome-win32-nacl-irt-syms.zip', + }, + # Metrics metadata files: + { + 'filename': 'actions.xml', + 'buildtype': ['official'], + 'archive': 'metrics-metadata.zip', + 'optional': ['official'], + }, + { + 'filename': 'histograms.xml', + 'buildtype': ['official'], + 'archive': 'metrics-metadata.zip', + 'optional': ['official'], + }, + { + 'filename': 'ukm.xml', + 'buildtype': ['official'], + 'archive': 'metrics-metadata.zip', + 'optional': ['official'], + }, + # MEI Preload files: + { + 'filename': 'MEIPreload/manifest.json', + 'buildtype': ['official'], + }, + { + 'filename': 'MEIPreload/preloaded_data.pb', + 'buildtype': ['official'], + }, + # ChromeDriver binary: + { + 'filename': 'chromedriver.exe', + 'arch': ['32bit'], + 'buildtype': ['official'], + 'archive': 'chromedriver_win32.zip', + 'optional': ['official'], + 'filegroup': ['symsrc'], + }, + { + 'filename': 'chromedriver.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chromedriver_win32-syms.zip', + 'optional': ['official'], + }, + # Elevation service files: + { + 'filename': 'elevation_service.exe', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'elevation_service.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + # Bookmark apps shortcut target: + { + 'filename': 'chrome_proxy.exe', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'chrome_proxy.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + # DevTools front-end (internal) files: + { + 'filename': 'gen/third_party/devtools-frontend-internal/devtools-frontend/front_end', + 'buildtype': ['official'], + 'archive': 'devtools-frontend.zip', + }, + # Policy cloud documentation source files: + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_de-DE.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_de-DE.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_en-US.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_en-US.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_es-419.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_es-419.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_es-ES.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_es-ES.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_fr-FR.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_fr-FR.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_id-ID.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_id-ID.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_it-IT.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_it-IT.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_ja-JP.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_ja-JP.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_ko-KR.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_ko-KR.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_nl-NL.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_nl-NL.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_pt-BR.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_pt-BR.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_ru-RU.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_ru-RU.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_th-TH.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_th-TH.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_tr-TR.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_tr-TR.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_uk-UA.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_uk-UA.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_vi-VN.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_vi-VN.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_zh-CN.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_zh-CN.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + { + 'filename': 'gen/chrome/app/policy/translations/policy_templates_zh-TW.json', + 'buildtype': ['official'], + 'archive': 'policy_templates_zh-TW.json', + 'direct_archive': 1, + 'optional': ['official'], + }, + # Progressive Web App launcher executable: + { + 'filename': 'chrome_pwa_launcher.exe', + 'buildtype': ['official'], + 'filegroup': ['default', 'symsrc'], + }, + { + 'filename': 'chrome_pwa_launcher.exe.pdb', + 'buildtype': ['official'], + 'archive': 'chrome-win32-syms.zip', + }, + # Hyphenation dictionaries: + { + 'filename': 'hyphens-data.zip', + 'buildtype': ['official'], + 'archive': 'hyphens-data.zip', + }, +]
diff --git a/chrome/updater/app/server/mac/service_delegate.mm b/chrome/updater/app/server/mac/service_delegate.mm index 4d44536..c171698f 100644 --- a/chrome/updater/app/server/mac/service_delegate.mm +++ b/chrome/updater/app/server/mac/service_delegate.mm
@@ -6,6 +6,8 @@ #import <Foundation/Foundation.h> +#include <sys/types.h> +#include <unistd.h> #include <utility> #include <vector> @@ -24,6 +26,7 @@ #import "chrome/updater/app/server/mac/server.h" #import "chrome/updater/app/server/mac/service_protocol.h" #import "chrome/updater/app/server/mac/update_service_wrappers.h" +#include "chrome/updater/constants.h" #include "chrome/updater/mac/setup/setup.h" #import "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/update_service.h" @@ -44,7 +47,7 @@ @end @implementation CRUUpdateServiceXPCImpl { - updater::UpdateService* _service; + scoped_refptr<updater::UpdateService> _service; scoped_refptr<updater::AppServerMac> _appServer; scoped_refptr<base::SequencedTaskRunner> _callbackRunner; } @@ -115,12 +118,10 @@ base::scoped_nsobject<CRUUpdateStateStateWrapper> updateStateStateWrapper( [[CRUUpdateStateStateWrapper alloc] - initWithUpdateStateState:state.state], - base::scoped_policy::RETAIN); + initWithUpdateStateState:state.state]); base::scoped_nsobject<CRUErrorCategoryWrapper> errorCategoryWrapper( [[CRUErrorCategoryWrapper alloc] - initWithErrorCategory:state.error_category], - base::scoped_policy::RETAIN); + initWithErrorCategory:state.error_category]); base::scoped_nsobject<CRUUpdateStateWrapper> updateStateWrapper( [[CRUUpdateStateWrapper alloc] @@ -148,6 +149,7 @@ (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate updateState:(id<CRUUpdateStateObserving>)updateState reply:(void (^_Nonnull)(int rc))reply { + // This function may be called by any user. auto cb = base::BindOnce(base::RetainBlock(^(updater::UpdateService::Result error) { VLOG(0) << "Update complete: error = " << error; @@ -164,12 +166,10 @@ base::scoped_nsobject<CRUUpdateStateStateWrapper> updateStateStateWrapper( [[CRUUpdateStateStateWrapper alloc] - initWithUpdateStateState:state.state], - base::scoped_policy::RETAIN); + initWithUpdateStateState:state.state]); base::scoped_nsobject<CRUErrorCategoryWrapper> errorCategoryWrapper( [[CRUErrorCategoryWrapper alloc] - initWithErrorCategory:state.error_category], - base::scoped_policy::RETAIN); + initWithErrorCategory:state.error_category]); base::scoped_nsobject<CRUUpdateStateWrapper> updateStateWrapper( [[CRUUpdateStateWrapper alloc] @@ -231,8 +231,7 @@ ^(const std::vector<updater::UpdateService::AppState>& states) { if (reply) { base::scoped_nsobject<CRUAppStatesWrapper> appStatesWrapper( - [[CRUAppStatesWrapper alloc] initWithAppStates:states], - base::scoped_policy::RETAIN); + [[CRUAppStatesWrapper alloc] initWithAppStates:states]); reply(appStatesWrapper); } @@ -246,6 +245,91 @@ } @end +// CRUUpdateServiceXPCFilterUnprivileged is an implementation of UpdateService +// that rejects sensitive operations (which can only be performed by privileged +// clients). It only accepts operations that are safe for any user on the +// system (even an attacker) to call. +@interface CRUUpdateServiceXPCFilterUnprivileged : NSObject <CRUUpdateServicing> + +- (instancetype)init NS_UNAVAILABLE; + +// Designated initializers. +- (instancetype)initWithService: + (base::scoped_nsobject<CRUUpdateServiceXPCImpl>)service + NS_DESIGNATED_INITIALIZER; + +@end + +@implementation CRUUpdateServiceXPCFilterUnprivileged { + base::scoped_nsobject<CRUUpdateServiceXPCImpl> _service; +} + +- (instancetype)initWithService: + (base::scoped_nsobject<CRUUpdateServiceXPCImpl>)service { + if (self = [super init]) { + _service = service; + } + return self; +} + +#pragma mark CRUUpdateServicing +- (void)getVersionWithReply:(void (^_Nonnull)(NSString* version))reply { + // This function may be called by any user. + [_service getVersionWithReply:reply]; +} + +- (void)runPeriodicTasksWithReply:(void (^)(void))reply { + // This function may only be called by the same user. + VLOG(1) << "Rejecting cross-user attempt to call " << __func__; + if (reply) + reply(); +} + +- (void)checkForUpdatesWithUpdateState:(id<CRUUpdateStateObserving>)updateState + reply:(void (^_Nonnull)(int rc))reply { + // This function may only be called by the same user. + VLOG(1) << "Rejecting cross-user attempt to call " << __func__; + if (reply) + reply(updater::kPermissionDeniedError); +} + +- (void)checkForUpdateWithAppID:(NSString* _Nonnull)appID + priority:(CRUPriorityWrapper* _Nonnull)priority + policySameVersionUpdate: + (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate + updateState:(id<CRUUpdateStateObserving>)updateState + reply:(void (^_Nonnull)(int rc))reply { + // This function may be called by any user. + [_service checkForUpdateWithAppID:appID + priority:priority + policySameVersionUpdate:policySameVersionUpdate + updateState:updateState + reply:reply]; +} + +- (void)registerForUpdatesWithAppId:(NSString* _Nullable)appId + brandCode:(NSString* _Nullable)brandCode + brandPath:(NSString* _Nullable)brandPath + tag:(NSString* _Nullable)ap + version:(NSString* _Nullable)version + existenceCheckerPath:(NSString* _Nullable)existenceCheckerPath + reply:(void (^_Nonnull)(int rc))reply { + // This function may only be called by the same user. + VLOG(1) << "Rejecting cross-user attempt to call " << __func__; + if (reply) + reply(updater::kPermissionDeniedError); +} + +- (void)getAppStatesWithReply:(void (^_Nonnull)(CRUAppStatesWrapper*))reply { + // This function may only be called by the same user. + VLOG(1) << "Rejecting cross-user attempt to call " << __func__; + if (reply) { + reply(base::scoped_nsobject<CRUAppStatesWrapper>( + [[CRUAppStatesWrapper alloc] initWithAppStates:{}])); + } +} +@end + @interface CRUUpdateServiceInternalXPCImpl : NSObject <CRUUpdateServicingInternal> @@ -253,7 +337,8 @@ // Designated initializers. - (instancetype) - initWithUpdateServiceInternal:(updater::UpdateServiceInternal*)service + initWithUpdateServiceInternal: + (scoped_refptr<updater::UpdateServiceInternal>)service appServer: (scoped_refptr<updater::AppServerMac>)appServer callbackRunner: @@ -263,13 +348,14 @@ @end @implementation CRUUpdateServiceInternalXPCImpl { - updater::UpdateServiceInternal* _service; + scoped_refptr<updater::UpdateServiceInternal> _service; scoped_refptr<updater::AppServerMac> _appServer; scoped_refptr<base::SequencedTaskRunner> _callbackRunner; } - (instancetype) - initWithUpdateServiceInternal:(updater::UpdateServiceInternal*)service + initWithUpdateServiceInternal: + (scoped_refptr<updater::UpdateServiceInternal>)service appServer: (scoped_refptr<updater::AppServerMac>)appServer callbackRunner:(scoped_refptr<base::SequencedTaskRunner>) @@ -334,17 +420,21 @@ - (BOOL)listener:(NSXPCListener*)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection { - // Check to see if the other side of the connection is "okay"; - // if not, invalidate newConnection and return NO. - newConnection.exportedInterface = updater::GetXPCUpdateServicingInterface(); - base::scoped_nsobject<CRUUpdateServiceXPCImpl> object( + base::scoped_nsobject<CRUUpdateServiceXPCImpl> impl( [[CRUUpdateServiceXPCImpl alloc] initWithUpdateService:_service.get() appServer:_appServer callbackRunner:_callbackRunner.get()]); - newConnection.exportedObject = object.get(); + if (newConnection.effectiveUserIdentifier == geteuid()) { + newConnection.exportedObject = impl.get(); + } else { + // Other users get an unprivileged implementation. + base::scoped_nsobject<CRUUpdateServiceXPCFilterUnprivileged> unprivileged( + [[CRUUpdateServiceXPCFilterUnprivileged alloc] initWithService:impl]); + newConnection.exportedObject = unprivileged.get(); + } [newConnection resume]; return YES; } @@ -372,8 +462,13 @@ - (BOOL)listener:(NSXPCListener*)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection { - // Check to see if the other side of the connection is "okay"; - // if not, invalidate newConnection and return NO. + // Reject connections from other users. + if (newConnection.effectiveUserIdentifier != geteuid()) { + VLOG(1) << "Rejecting UpdateServiceInternal XPC connection from EUID " + << newConnection.effectiveUserIdentifier << ", required " + << geteuid() << "."; + return NO; + } newConnection.exportedInterface = updater::GetXPCUpdateServicingInternalInterface();
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h index 1d82fcd..f462a70b 100644 --- a/chrome/updater/constants.h +++ b/chrome/updater/constants.h
@@ -230,6 +230,9 @@ // The file downloaded to a temporary location could not be moved. constexpr int kErrorFailedToMoveDownloadedFile = 5; +// A connection was rejected due to insufficient permissions. +constexpr int kPermissionDeniedError = 403; + constexpr double kInitialDelay = 60; constexpr int kServerKeepAliveSeconds = 10;
diff --git a/chrome/updater/mac/signing/README.md b/chrome/updater/mac/signing/README.md new file mode 100644 index 0000000..ebf8b1e --- /dev/null +++ b/chrome/updater/mac/signing/README.md
@@ -0,0 +1,8 @@ +# Testing +1. Create a self-signed certificate, e.g. with identity `myid`. +2. `autoninja -C out/MyOutDir chrome/updater` +3. ``` + out/MyOutDir/Updater\ Packaging/sign_updater.py --identity myid \ + --development --input out/MyOutDir --output MySignedOutputDir \ + --no-notarize --development + ```
diff --git a/chrome/updater/mac/signing/parts.py b/chrome/updater/mac/signing/parts.py index bc03b3d..dc6a0f1 100644 --- a/chrome/updater/mac/signing/parts.py +++ b/chrome/updater/mac/signing/parts.py
@@ -26,9 +26,24 @@ ks_bundle = ( '{0.app_product}.app/Contents/Helpers/{0.keystone_app_name}.bundle'. format(config)) + ks_agent_app = ( + ks_bundle + + '/Contents/Resources/{0.keystone_app_name}Agent.app'.format(config)) # Innermost parts come first. return [ + CodeSignedProduct( # Keystone Agent app bundle plist + ks_agent_app + '/Contents/MacOS/Info.plist', + config.keystone_app_name + 'Agent', + identifier_requirement=False, + options=CodeSignOptions.FULL_HARDENED_RUNTIME_OPTIONS, + verify_options=VerifyOptions.DEEP + VerifyOptions.STRICT), + CodeSignedProduct( # Keystone Agent app bundle + ks_agent_app, + config.keystone_app_name + 'Agent', + identifier_requirement=False, + options=CodeSignOptions.FULL_HARDENED_RUNTIME_OPTIONS, + verify_options=VerifyOptions.DEEP + VerifyOptions.STRICT), CodeSignedProduct( # Keystone's ksadmin ks_bundle + '/Contents/Helpers/ksadmin', 'ksadmin',
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 29090b6..8a9464d 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -60,7 +60,7 @@ virtual void UpdateAll() const = 0; virtual void PrintLog() const = 0; virtual base::FilePath GetDifferentUserPath() const = 0; - virtual void WaitForServerExit() const = 0; + virtual void WaitForUpdaterExit() const = 0; #if defined(OS_WIN) virtual void ExpectInterfacesRegistered() const = 0; virtual void ExpectLegacyUpdate3WebSucceeds(
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index 16ebb5f..b016a44 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -146,8 +146,8 @@ RunCommand("register_app", {Param("app_id", app_id)}); } - void WaitForServerExit() const override { - updater::test::WaitForServerExit(updater_scope_); + void WaitForUpdaterExit() const override { + updater::test::WaitForUpdaterExit(updater_scope_); } #if defined(OS_WIN)
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index cc1997a..c70a01d5 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -135,8 +135,8 @@ updater::test::RegisterApp(updater_scope_, app_id); } - void WaitForServerExit() const override { - updater::test::WaitForServerExit(updater_scope_); + void WaitForUpdaterExit() const override { + updater::test::WaitForUpdaterExit(updater_scope_); } #if defined(OS_WIN)
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 7bf75d3d..ba86247f 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -120,6 +120,7 @@ PrintLog(); CopyLog(); test_commands_->Uninstall(); + WaitForUpdaterExit(); } void ExpectCandidateUninstalled() { @@ -211,7 +212,7 @@ return test_commands_->GetDifferentUserPath(); } - void WaitForServerExit() { test_commands_->WaitForServerExit(); } + void WaitForUpdaterExit() { test_commands_->WaitForUpdaterExit(); } void SetUpTestService() { #if defined(OS_WIN) @@ -265,7 +266,7 @@ TEST_F(IntegrationTest, InstallUninstall) { Install(); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectInstalled(); ExpectVersionActive(kUpdaterVersion); ExpectActiveUpdater(); @@ -281,16 +282,12 @@ TEST_F(IntegrationTest, SelfUninstallOutdatedUpdater) { Install(); ExpectInstalled(); - SleepFor(2); + WaitForUpdaterExit(); SetupFakeUpdaterHigherVersion(); ExpectVersionNotActive(kUpdaterVersion); RunWake(0); - - // The mac server will remain active for 10 seconds after it replies to the - // wake client, then shut down and uninstall itself. Sleep to wait for this - // to happen. - SleepFor(11); + WaitForUpdaterExit(); ExpectCandidateUninstalled(); // The candidate uninstall should not have altered global prefs. @@ -306,7 +303,7 @@ ExpectRegistrationEvent(&test_server, kUpdaterAppId); Install(); ExpectInstalled(); - WaitForServerExit(); + WaitForUpdaterExit(); SetupFakeUpdaterLowerVersion(); ExpectVersionNotActive(kUpdaterVersion); @@ -315,7 +312,7 @@ base::Version("0.2")); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); // This instance is now qualified and should activate itself and check itself // for updates on the next check. @@ -324,7 +321,7 @@ base::StringPrintf(".*%s.*", kUpdaterAppId))}, ")]}'\n"); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectVersionActive(kUpdaterVersion); Uninstall(); @@ -341,7 +338,7 @@ base::Version(kUpdaterVersion), next_version); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectAppVersion(kUpdaterAppId, next_version); Uninstall(); @@ -404,7 +401,7 @@ base::Version v2("2"); ExpectUpdateSequence(&test_server, kAppId, v1, v2); Update(kAppId); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectAppVersion(kAppId, v2); Uninstall(); @@ -499,7 +496,7 @@ // Running the uninstall command does not uninstall this instance of the // updater right after installing it (not enough server starts). RunUninstallCmdLine(); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectInstalled(); // TODO(crbug.com/1270520) - use a switch that can uninstall immediately if @@ -508,7 +505,7 @@ // Uninstall the idle updater. RunUninstallCmdLine(); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectClean(); } #endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -519,14 +516,14 @@ RegisterApp("test1"); RegisterApp("test2"); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectVersionActive(kUpdaterVersion); ExpectActiveUpdater(); SetExistenceCheckerPath("test1", base::FilePath(FILE_PATH_LITERAL("NONE"))); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectInstalled(); ExpectAppUnregisteredExistenceCheckerPath("test1"); @@ -535,12 +532,11 @@ TEST_F(IntegrationTest, UninstallIfMaxServerWakesBeforeRegistrationExceeded) { Install(); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectInstalled(); SetServerStarts(24); RunWake(0); - WaitForServerExit(); - SleepFor(2); + WaitForUpdaterExit(); ExpectClean(); } @@ -548,17 +544,16 @@ Install(); RegisterApp("test1"); ExpectInstalled(); - WaitForServerExit(); + WaitForUpdaterExit(); SetServerStarts(24); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectInstalled(); ExpectVersionActive(kUpdaterVersion); ExpectActiveUpdater(); SetExistenceCheckerPath("test1", base::FilePath(FILE_PATH_LITERAL("NONE"))); RunWake(0); - WaitForServerExit(); - SleepFor(2); + WaitForUpdaterExit(); ExpectClean(); } @@ -577,7 +572,7 @@ SetExistenceCheckerPath("test1", GetDifferentUserPath()); RunWake(0); - WaitForServerExit(); + WaitForUpdaterExit(); ExpectAppUnregisteredExistenceCheckerPath("test1");
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index 9ca5207..06e90b0 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -313,18 +313,6 @@ return process.WaitForExitWithTimeout(base::Seconds(45), exit_code); } -void SleepFor(int seconds) { - VLOG(2) << "Sleeping " << seconds << " seconds..."; - base::WaitableEvent sleep(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - base::ThreadPool::PostDelayedTask( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&sleep)), - base::Seconds(seconds)); - sleep.Wait(); - VLOG(2) << "Sleep complete."; -} - bool WaitFor(base::RepeatingCallback<bool()> predicate) { base::TimeTicks deadline = base::TimeTicks::Now() + TestTimeouts::action_max_timeout();
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index dc8c38b..7e59378 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -51,11 +51,6 @@ // Copies the logs to a location where they can be retrieved by ResultDB. void CopyLog(const base::FilePath& src_dir); -// Sleeps for the given number of seconds. This should be avoided, but in some -// cases surrounding uninstall it is necessary since the processes can exit -// prior to completing the actual uninstallation. -void SleepFor(int seconds); - // Waits for a given predicate to become true, testing it by polling. Returns // true if the predicate becomes true before a timeout, otherwise returns false. bool WaitFor(base::RepeatingCallback<bool()> predicate); @@ -143,7 +138,7 @@ void RegisterApp(UpdaterScope scope, const std::string& app_id); -void WaitForServerExit(UpdaterScope scope); +void WaitForUpdaterExit(UpdaterScope scope); #if defined(OS_WIN) void ExpectInterfacesRegistered(UpdaterScope scope);
diff --git a/chrome/updater/test/integration_tests_linux.cc b/chrome/updater/test/integration_tests_linux.cc index d4fb5b6..6850c64 100644 --- a/chrome/updater/test/integration_tests_linux.cc +++ b/chrome/updater/test/integration_tests_linux.cc
@@ -27,7 +27,7 @@ return absl::nullopt; } -void WaitForServerExit(UpdaterScope scope) { +void WaitForUpdaterExit(UpdaterScope scope) { NOTREACHED(); }
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm index 89aa572b..4ff2314 100644 --- a/chrome/updater/test/integration_tests_mac.mm +++ b/chrome/updater/test/integration_tests_mac.mm
@@ -300,7 +300,7 @@ EXPECT_FALSE(base::PathIsWritable(*path)); } -void WaitForServerExit(UpdaterScope /*scope*/) { +void WaitForUpdaterExit(UpdaterScope /*scope*/) { ASSERT_TRUE(WaitFor(base::BindRepeating([]() { std::string ps_stdout; EXPECT_TRUE(base::GetAppOutput({"ps", "ax", "-o", "command"}, &ps_stdout));
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc index e7bbeacb..54f4bb4 100644 --- a/chrome/updater/test/integration_tests_win.cc +++ b/chrome/updater/test/integration_tests_win.cc
@@ -290,8 +290,13 @@ // Returns true is any updater process is found running in any session in the // system, regardless of its path. bool IsUpdaterRunning() { - ProcessFilterName filter(kUpdaterProcessName); - return base::ProcessIterator(&filter).NextProcessEntry(); + return IsProcessRunning(kUpdaterProcessName); +} + +void SleepFor(int seconds) { + VLOG(2) << "Sleeping " << seconds << " seconds..."; + base::WaitableEvent().TimedWait(base::Seconds(seconds)); + VLOG(2) << "Sleep complete."; } } // namespace @@ -414,6 +419,7 @@ // Uninstallation involves a race with the uninstall.cmd script and the // process exit. Sleep to allow the script to complete its work. + // TODO(crbug.com/1217765): Figure out a way to replace this. SleepFor(5); } @@ -450,7 +456,7 @@ // Waits for all updater processes to end, including the server process holding // the prefs lock. -void WaitForServerExit(UpdaterScope /*scope*/) { +void WaitForUpdaterExit(UpdaterScope /*scope*/) { WaitFor(base::BindRepeating([]() { return !IsUpdaterRunning(); })); }
diff --git a/chrome/updater/win/net/network_fetcher.cc b/chrome/updater/win/net/network_fetcher.cc index c206b30..41d3268 100644 --- a/chrome/updater/win/net/network_fetcher.cc +++ b/chrome/updater/win/net/network_fetcher.cc
@@ -190,7 +190,7 @@ base::Unretained(this))); } -void NetworkFetcher::PostRequestComplete() { +void NetworkFetcher::PostRequestComplete(int /*response_code*/) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Attempt to get some response headers. Not all headers may be present so @@ -215,7 +215,7 @@ base::SysWideToUTF8(x_cup_server_proof), x_retry_after_sec); } -void NetworkFetcher::DownloadToFileComplete() { +void NetworkFetcher::DownloadToFileComplete(int /*response_code*/) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::move(download_to_file_complete_callback_) .Run(winhttp_network_fetcher_->GetNetError(),
diff --git a/chrome/updater/win/net/network_fetcher.h b/chrome/updater/win/net/network_fetcher.h index 8d82c3f..bb1dc67 100644 --- a/chrome/updater/win/net/network_fetcher.h +++ b/chrome/updater/win/net/network_fetcher.h
@@ -65,8 +65,8 @@ private: SEQUENCE_CHECKER(sequence_checker_); - void PostRequestComplete(); - void DownloadToFileComplete(); + void PostRequestComplete(int response_code); + void DownloadToFileComplete(int response_code); scoped_refptr<winhttp::NetworkFetcher> winhttp_network_fetcher_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/CastSysInfoAndroid.java b/chromecast/base/java/src/org/chromium/chromecast/base/CastSysInfoAndroid.java index bacc13d..083885c81 100644 --- a/chromecast/base/java/src/org/chromium/chromecast/base/CastSysInfoAndroid.java +++ b/chromecast/base/java/src/org/chromium/chromecast/base/CastSysInfoAndroid.java
@@ -30,10 +30,8 @@ String serialNumber = Build.SERIAL; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { Context context = ContextUtils.getApplicationContext(); - if (ContextCompat.checkSelfPermission(context, READ_PRIVILEGED_PHONE_STATE_PERMISSION) - == PackageManager.PERMISSION_GRANTED) { - serialNumber = Build.getSerial(); - } + int permissionCheck = ContextCompat.checkSelfPermission(context, READ_PRIVILEGED_PHONE_STATE_PERMISSION); + assert permissionCheck== PackageManager.PERMISSION_GRANTED : "Should not be granted READ_PRIVILEGED_PHONE_STATE_PERMISSION"; } if (!Build.UNKNOWN.equals(serialNumber)) return serialNumber; return CastSerialGenerator.getGeneratedSerial();
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index c1af2705..5098a506 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -898,6 +898,7 @@ void CastContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { if (render_frame_id == MSG_ROUTING_NONE) { LOG(ERROR) << "Service worker not supported.";
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 447562d3..f4bf309 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -250,6 +250,7 @@ void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) override; void OnNetworkServiceCreated( network::mojom::NetworkService* network_service) override;
diff --git a/chromecast/cast_core/runtime/browser/message_port_service.cc b/chromecast/cast_core/runtime/browser/message_port_service.cc index 529e582..e96b6bf 100644 --- a/chromecast/cast_core/runtime/browser/message_port_service.cc +++ b/chromecast/cast_core/runtime/browser/message_port_service.cc
@@ -22,6 +22,7 @@ void MessagePortService::HandleMessage(const cast::web::Message& message, cast::web::MessagePortStatus* response) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); uint32_t channel_id = message.channel().channel_id(); auto entry = ports_.find(channel_id); if (entry == ports_.end()) { @@ -40,11 +41,12 @@ bool MessagePortService::ConnectToPort( base::StringPiece port_name, std::unique_ptr<cast_api_bindings::MessagePort> port) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DLOG(INFO) << "MessagePortService connecting to port '" << port_name << "' as channel " << next_outgoing_channel_id_; cast::web::MessagePortDescriptor port_descriptor; - port_descriptor.mutable_channel()->set_channel_id( - next_outgoing_channel_id_++); + uint32_t channel_id = next_outgoing_channel_id_++; + port_descriptor.mutable_channel()->set_channel_id(channel_id); port_descriptor.mutable_peer_status()->set_status( cast::web::MessagePortStatus_Status_STARTED); port_descriptor.set_sequence_number(0); @@ -52,13 +54,18 @@ cast::bindings::ConnectRequest connect_request; connect_request.set_port_name(std::string(port_name)); *connect_request.mutable_port() = port_descriptor; - new AsyncConnect(connect_request, std::move(port), core_app_stub_, grpc_cq_, + auto result = ports_.emplace( + channel_id, MakeMessagePortHandler(channel_id, std::move(port))); + DCHECK(result.second); + + new AsyncConnect(connect_request, core_app_stub_, grpc_cq_, weak_factory_.GetWeakPtr()); return true; } uint32_t MessagePortService::RegisterOutgoingPort( std::unique_ptr<cast_api_bindings::MessagePort> port) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); uint32_t channel_id = next_outgoing_channel_id_++; ports_.emplace(channel_id, MakeMessagePortHandler(channel_id, std::move(port))); @@ -68,12 +75,14 @@ void MessagePortService::RegisterIncomingPort( uint32_t channel_id, std::unique_ptr<cast_api_bindings::MessagePort> port) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto result = ports_.emplace( channel_id, MakeMessagePortHandler(channel_id, std::move(port))); DCHECK(result.second); } void MessagePortService::Remove(uint32_t channel_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ports_.erase(channel_id); } @@ -86,27 +95,19 @@ return port_handler; } -void MessagePortService::OnConnectComplete( - bool ok, - uint32_t channel_id, - std::unique_ptr<cast_api_bindings::MessagePort> port) { - if (ok) { - DLOG(INFO) << "CoreApplicationService::Connect succeeded"; - auto result = ports_.emplace( - channel_id, MakeMessagePortHandler(channel_id, std::move(port))); - DCHECK(result.second); +void MessagePortService::OnConnectComplete(bool ok, uint32_t channel_id) { + if (!ok) { + DLOG(INFO) << "CoreApplicationService::Connect failed"; + Remove(channel_id); } } MessagePortService::AsyncConnect::AsyncConnect( const cast::bindings::ConnectRequest& request, - std::unique_ptr<cast_api_bindings::MessagePort> port, cast::v2::CoreApplicationService::Stub* core_app_stub, grpc::CompletionQueue* cq, base::WeakPtr<MessagePortService> service) - : service_(service), - port_(std::move(port)), - channel_id_(request.port().channel().channel_id()) { + : service_(service), channel_id_(request.port().channel().channel_id()) { response_reader_ = core_app_stub->PrepareAsyncConnect(&context_, request, cq); response_reader_->StartCall(); response_reader_->Finish(&response_, &status_, static_cast<GRPC*>(this)); @@ -116,8 +117,7 @@ void MessagePortService::AsyncConnect::StepGRPC(grpc::Status status) { if (service_) { - service_->OnConnectComplete(status_.ok() && status.ok(), channel_id_, - std::move(port_)); + service_->OnConnectComplete(status_.ok(), channel_id_); } delete this; }
diff --git a/chromecast/cast_core/runtime/browser/message_port_service.h b/chromecast/cast_core/runtime/browser/message_port_service.h index 572452e..859e473 100644 --- a/chromecast/cast_core/runtime/browser/message_port_service.h +++ b/chromecast/cast_core/runtime/browser/message_port_service.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" #include "chromecast/cast_core/runtime/browser/grpc/grpc_method.h" #include "components/cast/message_port/message_port.h" #include "third_party/cast_core/public/src/proto/v2/core_application_service.grpc.pb.h" @@ -61,7 +62,6 @@ class AsyncConnect final : public GrpcCall { public: AsyncConnect(const cast::bindings::ConnectRequest& request, - std::unique_ptr<cast_api_bindings::MessagePort> port, cast::v2::CoreApplicationService::Stub* core_app_stub, grpc::CompletionQueue* cq, base::WeakPtr<MessagePortService> service); @@ -76,7 +76,6 @@ grpc::ClientAsyncResponseReader<cast::bindings::ConnectResponse>> response_reader_; - std::unique_ptr<cast_api_bindings::MessagePort> port_; uint32_t channel_id_; }; @@ -85,9 +84,7 @@ std::unique_ptr<cast_api_bindings::MessagePort> port); // Callback invoked when AsyncConnect gets a gRPC result. - void OnConnectComplete(bool ok, - uint32_t channel_id, - std::unique_ptr<cast_api_bindings::MessagePort> port); + void OnConnectComplete(bool ok, uint32_t channel_id); CreatePairCallback create_pair_; @@ -98,6 +95,7 @@ // NOTE: Keyed by channel_id of cast::web::MessageChannelDescriptor. base::flat_map<uint32_t, std::unique_ptr<MessagePortHandler>> ports_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<MessagePortService> weak_factory_{this}; };
diff --git a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc index 9fec374..59306a0 100644 --- a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc +++ b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
@@ -9,7 +9,6 @@ #include "components/cast/message_port/platform_message_port.h" #include "components/cast_streaming/browser/public/receiver_session.h" #include "components/cast_streaming/public/cast_streaming_url.h" -#include "components/cast_streaming/public/constants.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -20,6 +19,7 @@ namespace chromecast { namespace { +const char kCastTransportBindingName[] = "cast.__platform__.cast_transport"; const char kMediaCapabilitiesBindingName[] = "cast.__platform__.canDisplayType"; const char kStreamingPageUrlTemplate[] = @@ -84,8 +84,8 @@ std::unique_ptr<cast_api_bindings::MessagePort> server_port; std::unique_ptr<cast_api_bindings::MessagePort> client_port; cast_api_bindings::CreatePlatformMessagePortPair(&client_port, &server_port); - message_port_service_->ConnectToPort( - cast_streaming::kCastTransportBindingName, std::move(client_port)); + message_port_service_->ConnectToPort(kCastTransportBindingName, + std::move(client_port)); // Allow for capturing of the renderer controls mojo pipe. Observe(cast_web_contents);
diff --git a/chromecast/media/audio/cma_audio_output.cc b/chromecast/media/audio/cma_audio_output.cc index 9df3cd6e..76d42b0 100644 --- a/chromecast/media/audio/cma_audio_output.cc +++ b/chromecast/media/audio/cma_audio_output.cc
@@ -83,7 +83,12 @@ auto cma_backend_task_runner = std::make_unique<TaskRunnerImpl>(); MediaPipelineDeviceParams device_params( - MediaPipelineDeviceParams::kModeIgnorePts, + // If AUDIO_PREFETCH is enabled, we're able to push audio ahead of + // realtime. Set the sync mode to kModeSyncPts to allow cma backend to + // buffer the early pushed data, instead of dropping them. + audio_params_.effects() & ::media::AudioParameters::AUDIO_PREFETCH + ? MediaPipelineDeviceParams::kModeSyncPts + : MediaPipelineDeviceParams::kModeIgnorePts, MediaPipelineDeviceParams::kAudioStreamNormal, cma_backend_task_runner.get(), GetContentType(device_id), device_id); device_params.session_id = application_session_id;
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 51d632e..6029b9a 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2248,6 +2248,9 @@ <message name="IDS_SHIMLESS_RMA_FINALIZE_FAILED_NON_BLOCKING" translateable="false" desc="Message to display when finalization failed, but RMA can continue."> Failed, non blocking. </message> + <message name="IDS_SHIMLESS_RMA_FINALIZE_FAILED_RETRY_BUTTON_LABEL" translateable="false" desc="The label for the button to retry finalization."> + Retry finalization + </message> <!-- Device provisioning page --> <message name="IDS_SHIMLESS_RMA_PROVISIONING_TITLE" translateable="false" desc="Title for the device provisioning page. Provisioning is when component specific data is set e.g. erasing fingerprint data from the thumb reader or regenerating the device stable secret before returning the device to a new owner."> Provisioning the device... @@ -2415,6 +2418,12 @@ <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_SKU_WARNING" translateable="false" desc="The text warning explaining when the device's SKU should be changed."> The SKU should only be changed if the new component(s) are different from the ones they replaced. For example, a touchscreen replacing a non-touchscreen, or memory being upgraded from 8GB to 16GB. </message> + <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_DRAM_PART_NUMBER_LABEL" translateable="false" desc="The label for the text input showing the device's dram part number."> + DRAM part number + </message> + <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_DRAM_PART_NUMBER_PLACEHOLDER_LABEL" translateable="false" desc="The placeholder label for the text input box for the device's dram part number."> + Enter DRAM part number + </message> <!-- RO firmware reimaging page --> <message name="IDS_SHIMLESS_RMA_FIRMWARE_UPDATE_TITLE" translateable="false" desc="The title for the page when reimaging is in progress."> Install firmware image
diff --git a/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.cc b/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.cc index 54c7e325..9e0a1e8 100644 --- a/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.cc +++ b/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.cc
@@ -6,8 +6,6 @@ #include "base/check_op.h" -namespace ash { - namespace { QuickAnswersController* g_instance = nullptr; } @@ -25,4 +23,3 @@ QuickAnswersController* QuickAnswersController::Get() { return g_instance; } -} // namespace ash
diff --git a/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.h b/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.h index 8f9c366..2e69647 100644 --- a/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.h +++ b/chromeos/components/quick_answers/public/cpp/controller/quick_answers_controller.h
@@ -9,8 +9,6 @@ #include "ui/gfx/geometry/rect.h" -namespace ash { - namespace quick_answers { class QuickAnswersClient; class QuickAnswersDelegate; @@ -71,6 +69,4 @@ virtual QuickAnswersVisibility GetVisibilityForTesting() const = 0; }; -} // namespace ash - #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_CONTROLLER_QUICK_ANSWERS_CONTROLLER_H_
diff --git a/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.cc b/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.cc index 0473fcd..5482d72 100644 --- a/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.cc +++ b/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.cc
@@ -6,7 +6,6 @@ #include "components/prefs/pref_registry_simple.h" -namespace ash { namespace quick_answers { namespace prefs { @@ -63,4 +62,3 @@ } // namespace prefs } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h b/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h index b37cdd3c..c70d717 100644 --- a/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h +++ b/chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h
@@ -7,7 +7,6 @@ class PrefRegistrySimple; -namespace ash { namespace quick_answers { namespace prefs { @@ -38,6 +37,5 @@ } // namespace prefs } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_QUICK_ANSWERS_PREFS_H_
diff --git a/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc b/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc index f9d55e7..998b946 100644 --- a/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc +++ b/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc
@@ -15,8 +15,6 @@ #include "third_party/icu/source/common/unicode/locid.h" #include "ui/base/l10n/l10n_util.h" -namespace ash { - namespace { using quick_answers::prefs::ConsentStatus; @@ -201,7 +199,7 @@ bool QuickAnswersState::IsSettingsEnforced() { return pref_change_registrar_->prefs()->IsManagedPreference( - ash::quick_answers::prefs::kQuickAnswersEnabled); + quick_answers::prefs::kQuickAnswersEnabled); } void QuickAnswersState::InitializeObserver( @@ -279,5 +277,3 @@ is_eligible_ = IsQuickAnswersAllowedForLocale( resolved_locale, icu::Locale::getDefault().getName()); } - -} // namespace ash
diff --git a/chromeos/components/quick_answers/public/cpp/quick_answers_state.h b/chromeos/components/quick_answers/public/cpp/quick_answers_state.h index 1499d6a..ce7a174 100644 --- a/chromeos/components/quick_answers/public/cpp/quick_answers_state.h +++ b/chromeos/components/quick_answers/public/cpp/quick_answers_state.h
@@ -16,8 +16,6 @@ class PrefChangeRegistrar; class PrefService; -namespace ash { - // The consent will appear up to a total of 6 times. constexpr int kConsentImpressionCap = 6; // The consent need to show for at least 1 second to be counted. @@ -127,6 +125,4 @@ base::ObserverList<QuickAnswersStateObserver> observers_; }; -} // namespace ash - #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_QUICK_ANSWERS_STATE_H_
diff --git a/chromeos/components/quick_answers/quick_answers_client.cc b/chromeos/components/quick_answers/quick_answers_client.cc index 79cf2c18..95794a8 100644 --- a/chromeos/components/quick_answers/quick_answers_client.cc +++ b/chromeos/components/quick_answers/quick_answers_client.cc
@@ -12,7 +12,6 @@ #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -namespace ash { namespace quick_answers { namespace { @@ -128,7 +127,7 @@ delegate_->OnRequestPreprocessFinished(processed_request); - if (ash::QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { + if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { RecordIntentType(intent_info.intent_type); if (intent_info.intent_type == IntentType::kUnknown) { // Don't fetch answer if no intent is generated. @@ -154,4 +153,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/quick_answers_client.h b/chromeos/components/quick_answers/quick_answers_client.h index be31c727..ea1c0bb 100644 --- a/chromeos/components/quick_answers/quick_answers_client.h +++ b/chromeos/components/quick_answers/quick_answers_client.h
@@ -17,7 +17,6 @@ class SharedURLLoaderFactory; } // namespace network -namespace ash { namespace quick_answers { struct QuickAnswer; @@ -145,6 +144,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_QUICK_ANSWERS_CLIENT_H_
diff --git a/chromeos/components/quick_answers/quick_answers_client_unittest.cc b/chromeos/components/quick_answers/quick_answers_client_unittest.cc index ad9e5b6..76d6450 100644 --- a/chromeos/components/quick_answers/quick_answers_client_unittest.cc +++ b/chromeos/components/quick_answers/quick_answers_client_unittest.cc
@@ -21,7 +21,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -266,4 +265,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/quick_answers_model.cc b/chromeos/components/quick_answers/quick_answers_model.cc index c6bf9f1..1ef91f0 100644 --- a/chromeos/components/quick_answers/quick_answers_model.cc +++ b/chromeos/components/quick_answers/quick_answers_model.cc
@@ -4,7 +4,6 @@ #include "chromeos/components/quick_answers/quick_answers_model.h" -namespace ash { namespace quick_answers { QuickAnswer::QuickAnswer() = default; @@ -34,4 +33,3 @@ QuickAnswersRequest::~QuickAnswersRequest() = default; } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/quick_answers_model.h b/chromeos/components/quick_answers/quick_answers_model.h index 313941ff..951d5c5b 100644 --- a/chromeos/components/quick_answers/quick_answers_model.h +++ b/chromeos/components/quick_answers/quick_answers_model.h
@@ -13,7 +13,6 @@ #include "ui/gfx/image/image.h" #include "url/gurl.h" -namespace ash { namespace quick_answers { // Interaction with the consent-view (used for logging). @@ -211,6 +210,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_QUICK_ANSWERS_MODEL_H_
diff --git a/chromeos/components/quick_answers/result_loader.cc b/chromeos/components/quick_answers/result_loader.cc index 92e0553..dcb4314 100644 --- a/chromeos/components/quick_answers/result_loader.cc +++ b/chromeos/components/quick_answers/result_loader.cc
@@ -13,7 +13,6 @@ #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/url_response_head.mojom.h" -namespace ash { namespace quick_answers { namespace { @@ -115,4 +114,3 @@ delegate_->OnQuickAnswerReceived(std::move(quick_answer)); } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/result_loader.h b/chromeos/components/quick_answers/result_loader.h index 7abec8e..899b5e79 100644 --- a/chromeos/components/quick_answers/result_loader.h +++ b/chromeos/components/quick_answers/result_loader.h
@@ -19,7 +19,6 @@ struct ResourceRequest; } // namespace network -namespace ash { namespace quick_answers { enum class IntentType; @@ -115,6 +114,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_RESULT_LOADER_H_
diff --git a/chromeos/components/quick_answers/search_result_loader.cc b/chromeos/components/quick_answers/search_result_loader.cc index bebe90c..bc98c67a 100644 --- a/chromeos/components/quick_answers/search_result_loader.cc +++ b/chromeos/components/quick_answers/search_result_loader.cc
@@ -16,7 +16,6 @@ #include "services/network/public/cpp/simple_url_loader.h" #include "url/gurl.h" -namespace ash { namespace quick_answers { namespace { @@ -87,11 +86,11 @@ void SearchResultLoader::BuildRequest( const PreprocessedOutput& preprocessed_output, BuildRequestCallback callback) const { - GURL url = GURL(assistant::kKnowledgeApiEndpoint); + GURL url = GURL(ash::assistant::kKnowledgeApiEndpoint); // Add encoded request payload. url = net::AppendOrReplaceQueryParameter( - url, assistant::kPayloadParamName, + url, ash::assistant::kPayloadParamName, BuildSearchRequestPayload(preprocessed_output.query)); auto resource_request = std::make_unique<network::ResourceRequest>(); @@ -109,4 +108,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_loader.h b/chromeos/components/quick_answers/search_result_loader.h index 824bdbb..102b849 100644 --- a/chromeos/components/quick_answers/search_result_loader.h +++ b/chromeos/components/quick_answers/search_result_loader.h
@@ -16,7 +16,6 @@ class SharedURLLoaderFactory; } // namespace network -namespace ash { namespace quick_answers { class SearchResultLoader : public ResultLoader { @@ -42,6 +41,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_LOADER_H_
diff --git a/chromeos/components/quick_answers/search_result_loader_unittest.cc b/chromeos/components/quick_answers/search_result_loader_unittest.cc index 057b37c0..28782b2 100644 --- a/chromeos/components/quick_answers/search_result_loader_unittest.cc +++ b/chromeos/components/quick_answers/search_result_loader_unittest.cc
@@ -19,7 +19,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -89,7 +88,7 @@ loader_->Fetch(PreprocessRequest(IntentInfo("23cm", IntentType::kUnknown))); test_url_loader_factory_.SimulateResponseForPendingRequest( - assistant::kKnowledgeApiEndpoint, kValidResponse, net::HTTP_OK, + ash::assistant::kKnowledgeApiEndpoint, kValidResponse, net::HTTP_OK, network::TestURLLoaderFactory::ResponseMatchFlags::kUrlMatchPrefix); base::RunLoop().RunUntilIdle(); } @@ -100,7 +99,7 @@ loader_->Fetch(PreprocessRequest(IntentInfo("23cm", IntentType::kUnknown))); test_url_loader_factory_.SimulateResponseForPendingRequest( - assistant::kKnowledgeApiEndpoint, std::string(), net::HTTP_NOT_FOUND, + ash::assistant::kKnowledgeApiEndpoint, std::string(), net::HTTP_NOT_FOUND, network::TestURLLoaderFactory::ResponseMatchFlags::kUrlMatchPrefix); base::RunLoop().RunUntilIdle(); } @@ -111,11 +110,10 @@ loader_->Fetch(PreprocessRequest(IntentInfo("23cm", IntentType::kUnknown))); test_url_loader_factory_.SimulateResponseForPendingRequest( - assistant::kKnowledgeApiEndpoint, std::string(), net::HTTP_OK, + ash::assistant::kKnowledgeApiEndpoint, std::string(), net::HTTP_OK, network::TestURLLoaderFactory::ResponseMatchFlags::kUrlMatchPrefix); base::RunLoop().RunUntilIdle(); } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.cc b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.cc index f18a6eaf..3621a9c7 100644 --- a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.cc +++ b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.cc
@@ -11,7 +11,6 @@ #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" #include "url/gurl.h" -namespace ash { namespace quick_answers { namespace { @@ -134,4 +133,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h index 973d33a6..549572f 100644 --- a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h +++ b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h
@@ -12,7 +12,6 @@ class Value; } // namespace base -namespace ash { namespace quick_answers { class DefinitionResultParser : public ResultParser { @@ -30,6 +29,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_DEFINITION_RESULT_PARSER_H_
diff --git a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser_unittest.cc b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser_unittest.cc index 35d38406..0c47a5d 100644 --- a/chromeos/components/quick_answers/search_result_parsers/definition_result_parser_unittest.cc +++ b/chromeos/components/quick_answers/search_result_parsers/definition_result_parser_unittest.cc
@@ -12,7 +12,6 @@ #include "chromeos/components/quick_answers/test/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { using base::Value; @@ -132,4 +131,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.cc b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.cc index dd021a3..8f18494 100644 --- a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.cc +++ b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.cc
@@ -11,7 +11,6 @@ #include "base/values.h" #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" -namespace ash { namespace quick_answers { namespace { @@ -62,4 +61,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.h b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.h index 659786c1..48c27c9 100644 --- a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.h +++ b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.h
@@ -11,7 +11,6 @@ class Value; } // namespace base -namespace ash { namespace quick_answers { class KpEntityResultParser : public ResultParser { @@ -21,6 +20,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_KP_ENTITY_RESULT_PARSER_H_
diff --git a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser_unittest.cc b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser_unittest.cc index a5fa3fa8..1cc4018 100644 --- a/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser_unittest.cc +++ b/chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser_unittest.cc
@@ -12,7 +12,6 @@ #include "chromeos/components/quick_answers/test/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { using base::Value; @@ -136,4 +135,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/result_parser.cc b/chromeos/components/quick_answers/search_result_parsers/result_parser.cc index e873006d..5abebf6 100644 --- a/chromeos/components/quick_answers/search_result_parsers/result_parser.cc +++ b/chromeos/components/quick_answers/search_result_parsers/result_parser.cc
@@ -10,7 +10,6 @@ #include "chromeos/components/quick_answers/search_result_parsers/kp_entity_result_parser.h" #include "chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.h" -namespace ash { namespace quick_answers { namespace { using base::Value; @@ -57,4 +56,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/result_parser.h b/chromeos/components/quick_answers/search_result_parsers/result_parser.h index 96955f51..30681c0 100644 --- a/chromeos/components/quick_answers/search_result_parsers/result_parser.h +++ b/chromeos/components/quick_answers/search_result_parsers/result_parser.h
@@ -14,7 +14,6 @@ class Value; } // namespace base -namespace ash { namespace quick_answers { // Parser interface. @@ -41,6 +40,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_RESULT_PARSER_H_
diff --git a/chromeos/components/quick_answers/search_result_parsers/result_parser_unittest.cc b/chromeos/components/quick_answers/search_result_parsers/result_parser_unittest.cc index b4f90f7..9a6d5be 100644 --- a/chromeos/components/quick_answers/search_result_parsers/result_parser_unittest.cc +++ b/chromeos/components/quick_answers/search_result_parsers/result_parser_unittest.cc
@@ -10,7 +10,6 @@ #include "chromeos/components/quick_answers/quick_answers_model.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { class ResultParserFactoryTest : public testing::Test { @@ -37,4 +36,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/search_response_parser.cc b/chromeos/components/quick_answers/search_result_parsers/search_response_parser.cc index 5ea609a..a2a017aa 100644 --- a/chromeos/components/quick_answers/search_result_parsers/search_response_parser.cc +++ b/chromeos/components/quick_answers/search_result_parsers/search_response_parser.cc
@@ -10,7 +10,6 @@ #include "base/values.h" #include "chromeos/components/quick_answers/search_result_parsers/result_parser.h" -namespace ash { namespace quick_answers { namespace { @@ -92,4 +91,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/search_response_parser.h b/chromeos/components/quick_answers/search_result_parsers/search_response_parser.h index 4247d91..adf613d 100644 --- a/chromeos/components/quick_answers/search_result_parsers/search_response_parser.h +++ b/chromeos/components/quick_answers/search_result_parsers/search_response_parser.h
@@ -15,7 +15,6 @@ class Value; } // namespace base -namespace ash { namespace quick_answers { struct QuickAnswer; @@ -47,6 +46,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_SEARCH_RESPONSE_PARSER_H_
diff --git a/chromeos/components/quick_answers/search_result_parsers/search_response_parser_unittest.cc b/chromeos/components/quick_answers/search_result_parsers/search_response_parser_unittest.cc index 6c9bec3..fa292d3 100644 --- a/chromeos/components/quick_answers/search_result_parsers/search_response_parser_unittest.cc +++ b/chromeos/components/quick_answers/search_result_parsers/search_response_parser_unittest.cc
@@ -14,7 +14,6 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { class SearchResponseParserTest : public testing::Test { @@ -151,4 +150,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.cc b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.cc index 79249fc16..30a5ba5 100644 --- a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.cc +++ b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.cc
@@ -12,7 +12,6 @@ #include "chromeos/components/quick_answers/utils/unit_conversion_constants.h" #include "chromeos/components/quick_answers/utils/unit_converter.h" -namespace ash { namespace quick_answers { namespace { @@ -70,4 +69,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.h b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.h index 795e8d68..67c96740 100644 --- a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.h +++ b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser.h
@@ -11,7 +11,6 @@ class Value; } // namespace base -namespace ash { namespace quick_answers { class UnitConversionResultParser : public ResultParser { @@ -21,6 +20,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_UNIT_CONVERSION_RESULT_PARSER_H_
diff --git a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser_unittest.cc b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser_unittest.cc index 5e0065a..3e4ba69 100644 --- a/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser_unittest.cc +++ b/chromeos/components/quick_answers/search_result_parsers/unit_conversion_result_parser_unittest.cc
@@ -14,7 +14,6 @@ #include "chromeos/components/quick_answers/utils/unit_conversion_constants.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -217,4 +216,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/test/quick_answers_test_base.cc b/chromeos/components/quick_answers/test/quick_answers_test_base.cc index d768cfa..5ba9e0e 100644 --- a/chromeos/components/quick_answers/test/quick_answers_test_base.cc +++ b/chromeos/components/quick_answers/test/quick_answers_test_base.cc
@@ -4,8 +4,6 @@ #include "chromeos/components/quick_answers/test/quick_answers_test_base.h" -namespace ash { - QuickAnswersTestBase::QuickAnswersTestBase() = default; QuickAnswersTestBase::~QuickAnswersTestBase() = default; @@ -21,5 +19,3 @@ quick_answers_state_.reset(); testing::Test::TearDown(); } - -} // namespace ash
diff --git a/chromeos/components/quick_answers/test/quick_answers_test_base.h b/chromeos/components/quick_answers/test/quick_answers_test_base.h index eb2a3984..e8b949f 100644 --- a/chromeos/components/quick_answers/test/quick_answers_test_base.h +++ b/chromeos/components/quick_answers/test/quick_answers_test_base.h
@@ -10,8 +10,6 @@ #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { - // Helper class for Quick Answers related tests. class QuickAnswersTestBase : public testing::Test { public: @@ -30,6 +28,4 @@ std::unique_ptr<QuickAnswersState> quick_answers_state_; }; -} // namespace ash - #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_TEST_QUICK_ANSWERS_TEST_BASE_H_
diff --git a/chromeos/components/quick_answers/test/test_helpers.cc b/chromeos/components/quick_answers/test/test_helpers.cc index a27573d..c0b2ce5a 100644 --- a/chromeos/components/quick_answers/test/test_helpers.cc +++ b/chromeos/components/quick_answers/test/test_helpers.cc
@@ -4,7 +4,6 @@ #include "chromeos/components/quick_answers/test/test_helpers.h" -namespace ash { namespace quick_answers { std::string GetQuickAnswerTextForTesting( @@ -32,4 +31,3 @@ MockResultLoaderDelegate::~MockResultLoaderDelegate() = default; } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/test/test_helpers.h b/chromeos/components/quick_answers/test/test_helpers.h index 1a8a02da..5c73e739 100644 --- a/chromeos/components/quick_answers/test/test_helpers.h +++ b/chromeos/components/quick_answers/test/test_helpers.h
@@ -11,7 +11,6 @@ #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" #include "testing/gmock/include/gmock/gmock.h" -namespace ash { namespace quick_answers { std::string GetQuickAnswerTextForTesting( @@ -62,6 +61,5 @@ } } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_TEST_TEST_HELPERS_H_
diff --git a/chromeos/components/quick_answers/translation_response_parser.cc b/chromeos/components/quick_answers/translation_response_parser.cc index 3cd7e297..6f193c31 100644 --- a/chromeos/components/quick_answers/translation_response_parser.cc +++ b/chromeos/components/quick_answers/translation_response_parser.cc
@@ -11,7 +11,6 @@ #include "chromeos/components/quick_answers/search_result_parsers/result_parser.h" #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" -namespace ash { namespace quick_answers { TranslationResponseParser::TranslationResponseParser( @@ -71,4 +70,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/translation_response_parser.h b/chromeos/components/quick_answers/translation_response_parser.h index 0a89cd7b..e968fa8 100644 --- a/chromeos/components/quick_answers/translation_response_parser.h +++ b/chromeos/components/quick_answers/translation_response_parser.h
@@ -12,7 +12,6 @@ #include "base/memory/weak_ptr.h" #include "services/data_decoder/public/cpp/data_decoder.h" -namespace ash { namespace quick_answers { struct QuickAnswer; @@ -48,6 +47,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_TRANSLATION_RESPONSE_PARSER_H_
diff --git a/chromeos/components/quick_answers/translation_response_parser_unittest.cc b/chromeos/components/quick_answers/translation_response_parser_unittest.cc index 5bfb795..91bbdb9 100644 --- a/chromeos/components/quick_answers/translation_response_parser_unittest.cc +++ b/chromeos/components/quick_answers/translation_response_parser_unittest.cc
@@ -14,7 +14,6 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { class TranslationResponseParserTest : public testing::Test { @@ -121,4 +120,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/translation_result_loader.cc b/chromeos/components/quick_answers/translation_result_loader.cc index 1f9957e3..2ee6821 100644 --- a/chromeos/components/quick_answers/translation_result_loader.cc +++ b/chromeos/components/quick_answers/translation_result_loader.cc
@@ -18,7 +18,6 @@ #include "ui/base/resource/resource_bundle.h" #include "url/gurl.h" -namespace ash { namespace quick_answers { namespace { @@ -104,4 +103,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/translation_result_loader.h b/chromeos/components/quick_answers/translation_result_loader.h index 55f38e3..30b67c66 100644 --- a/chromeos/components/quick_answers/translation_result_loader.h +++ b/chromeos/components/quick_answers/translation_result_loader.h
@@ -16,7 +16,6 @@ class SharedURLLoaderFactory; } // namespace network -namespace ash { namespace quick_answers { class TranslationResultLoader : public ResultLoader { @@ -47,6 +46,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_TRANSLATION_RESULT_LOADER_H_
diff --git a/chromeos/components/quick_answers/translation_result_loader_unittest.cc b/chromeos/components/quick_answers/translation_result_loader_unittest.cc index 1139d54..ceea7e3 100644 --- a/chromeos/components/quick_answers/translation_result_loader_unittest.cc +++ b/chromeos/components/quick_answers/translation_result_loader_unittest.cc
@@ -20,7 +20,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -129,4 +128,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/understanding/intent_generator.cc b/chromeos/components/quick_answers/understanding/intent_generator.cc index 5451fca..ee69830 100644 --- a/chromeos/components/quick_answers/understanding/intent_generator.cc +++ b/chromeos/components/quick_answers/understanding/intent_generator.cc
@@ -18,7 +18,6 @@ #include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" #include "ui/base/l10n/l10n_util.h" -namespace ash { namespace quick_answers { namespace { @@ -137,7 +136,7 @@ } void IntentGenerator::GenerateIntent(const QuickAnswersRequest& request) { - if (ash::QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { + if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { // Load text classifier. chromeos::machine_learning::ServiceConnection::GetInstance() ->GetMachineLearningService() @@ -192,9 +191,9 @@ if (it != intent_type_map.end()) { // Skip the entity if the corresponding intent type is disabled. bool definition_disabled = - !ash::QuickAnswersState::Get()->definition_enabled(); + !QuickAnswersState::Get()->definition_enabled(); bool unit_conversion_disabled = - !ash::QuickAnswersState::Get()->unit_conversion_enabled(); + !QuickAnswersState::Get()->unit_conversion_enabled(); if ((it->second == IntentType::kDictionary && definition_disabled) || (it->second == IntentType::kUnit && unit_conversion_disabled)) { // Fallback to language detection for generating translation intent. @@ -222,7 +221,7 @@ const QuickAnswersRequest& request) { DCHECK(complete_callback_); - if (!ash::QuickAnswersState::Get()->translation_enabled() || + if (!QuickAnswersState::Get()->translation_enabled() || chromeos::features::IsQuickAnswersV2TranslationDisabled()) { std::move(complete_callback_) .Run(IntentInfo(request.selected_text, IntentType::kUnknown)); @@ -271,4 +270,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/understanding/intent_generator.h b/chromeos/components/quick_answers/understanding/intent_generator.h index 4ffbc09..1e3fbc7 100644 --- a/chromeos/components/quick_answers/understanding/intent_generator.h +++ b/chromeos/components/quick_answers/understanding/intent_generator.h
@@ -16,7 +16,6 @@ #include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace ash { namespace quick_answers { struct QuickAnswersRequest; @@ -68,6 +67,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UNDERSTANDING_INTENT_GENERATOR_H_
diff --git a/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc b/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc index f20863f..59e1f2a 100644 --- a/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc +++ b/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc
@@ -19,7 +19,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -487,4 +486,3 @@ EXPECT_EQ("the unfathomable reaches of space", intent_info_.intent_text); } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/language_detector.cc b/chromeos/components/quick_answers/utils/language_detector.cc index 2c950d6..919aee4 100644 --- a/chromeos/components/quick_answers/utils/language_detector.cc +++ b/chromeos/components/quick_answers/utils/language_detector.cc
@@ -8,7 +8,6 @@ #include "base/metrics/field_trial_params.h" #include "ui/base/l10n/l10n_util.h" -namespace ash { namespace quick_answers { namespace { @@ -76,4 +75,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/language_detector.h b/chromeos/components/quick_answers/utils/language_detector.h index e22d724c..33f82fe 100644 --- a/chromeos/components/quick_answers/utils/language_detector.h +++ b/chromeos/components/quick_answers/utils/language_detector.h
@@ -13,7 +13,6 @@ #include "chromeos/services/machine_learning/public/mojom/text_classifier.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace ash { namespace quick_answers { // Utility class for language detection. @@ -57,6 +56,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UTILS_LANGUAGE_DETECTOR_H_
diff --git a/chromeos/components/quick_answers/utils/language_detector_unittest.cc b/chromeos/components/quick_answers/utils/language_detector_unittest.cc index 6d98396..e484858 100644 --- a/chromeos/components/quick_answers/utils/language_detector_unittest.cc +++ b/chromeos/components/quick_answers/utils/language_detector_unittest.cc
@@ -17,7 +17,6 @@ #include "chromeos/services/machine_learning/public/mojom/text_classifier.mojom.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -172,4 +171,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/quick_answers_metrics.cc b/chromeos/components/quick_answers/utils/quick_answers_metrics.cc index 40553f12..26b58f6 100644 --- a/chromeos/components/quick_answers/utils/quick_answers_metrics.cc +++ b/chromeos/components/quick_answers/utils/quick_answers_metrics.cc
@@ -9,7 +9,6 @@ #include "base/strings/stringprintf.h" #include "base/time/time.h" -namespace ash { namespace quick_answers { namespace { @@ -123,4 +122,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/quick_answers_metrics.h b/chromeos/components/quick_answers/utils/quick_answers_metrics.h index a2c79d8..4e34f92 100644 --- a/chromeos/components/quick_answers/utils/quick_answers_metrics.h +++ b/chromeos/components/quick_answers/utils/quick_answers_metrics.h
@@ -11,7 +11,6 @@ class TimeDelta; } // namespace base -namespace ash { namespace quick_answers { // Record the status of loading quick answers with status and duration. @@ -42,6 +41,5 @@ void RecordNetworkError(IntentType intent_type); } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UTILS_QUICK_ANSWERS_METRICS_H_
diff --git a/chromeos/components/quick_answers/utils/quick_answers_utils.cc b/chromeos/components/quick_answers/utils/quick_answers_utils.cc index f3c2c34..195d964 100644 --- a/chromeos/components/quick_answers/utils/quick_answers_utils.cc +++ b/chromeos/components/quick_answers/utils/quick_answers_utils.cc
@@ -11,7 +11,6 @@ #include "net/base/escape.h" #include "ui/base/l10n/l10n_util.h" -namespace ash { namespace quick_answers { namespace { @@ -95,4 +94,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/quick_answers_utils.h b/chromeos/components/quick_answers/utils/quick_answers_utils.h index 929d100..2fb43a2 100644 --- a/chromeos/components/quick_answers/utils/quick_answers_utils.h +++ b/chromeos/components/quick_answers/utils/quick_answers_utils.h
@@ -8,7 +8,6 @@ #include "chromeos/components/quick_answers/quick_answers_model.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace ash { namespace quick_answers { const PreprocessedOutput PreprocessRequest(const IntentInfo& intent_info); @@ -42,6 +41,5 @@ absl::optional<double> GetRatio(const double value1, const double value2); } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UTILS_QUICK_ANSWERS_UTILS_H_
diff --git a/chromeos/components/quick_answers/utils/unit_conversion_constants.cc b/chromeos/components/quick_answers/utils/unit_conversion_constants.cc index 90a787b..593e8d0 100644 --- a/chromeos/components/quick_answers/utils/unit_conversion_constants.cc +++ b/chromeos/components/quick_answers/utils/unit_conversion_constants.cc
@@ -9,7 +9,6 @@ #include "chromeos/strings/grit/chromeos_strings.h" #include "ui/base/l10n/l10n_util.h" -namespace ash { namespace quick_answers { const char kRuleSetPath[] = "unitConversionResult.conversions"; @@ -41,4 +40,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/unit_conversion_constants.h b/chromeos/components/quick_answers/utils/unit_conversion_constants.h index 6076f29..060becdb0 100644 --- a/chromeos/components/quick_answers/utils/unit_conversion_constants.h +++ b/chromeos/components/quick_answers/utils/unit_conversion_constants.h
@@ -7,7 +7,6 @@ #include <string> -namespace ash { namespace quick_answers { extern const char kRuleSetPath[]; @@ -25,6 +24,5 @@ std::string GetUnitDisplayText(const std::string& name); } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UTILS_UNIT_CONVERSION_CONSTANTS_H_
diff --git a/chromeos/components/quick_answers/utils/unit_converter.cc b/chromeos/components/quick_answers/utils/unit_converter.cc index 2439b5d..07dc4b1 100644 --- a/chromeos/components/quick_answers/utils/unit_converter.cc +++ b/chromeos/components/quick_answers/utils/unit_converter.cc
@@ -11,7 +11,6 @@ #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" #include "chromeos/components/quick_answers/utils/unit_conversion_constants.h" -namespace ash { namespace quick_answers { namespace { @@ -106,4 +105,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/components/quick_answers/utils/unit_converter.h b/chromeos/components/quick_answers/utils/unit_converter.h index 6bc00d23..05c1df1 100644 --- a/chromeos/components/quick_answers/utils/unit_converter.h +++ b/chromeos/components/quick_answers/utils/unit_converter.h
@@ -9,7 +9,6 @@ #include "base/values.h" -namespace ash { namespace quick_answers { // Utility class for unit conversion. @@ -46,6 +45,5 @@ }; } // namespace quick_answers -} // namespace ash #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_UTILS_UNIT_CONVERTER_H_
diff --git a/chromeos/components/quick_answers/utils/unit_converter_unittest.cc b/chromeos/components/quick_answers/utils/unit_converter_unittest.cc index abb1cde..a9e6727 100644 --- a/chromeos/components/quick_answers/utils/unit_converter_unittest.cc +++ b/chromeos/components/quick_answers/utils/unit_converter_unittest.cc
@@ -13,7 +13,6 @@ #include "chromeos/components/quick_answers/utils/unit_conversion_constants.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { namespace quick_answers { namespace { @@ -244,4 +243,3 @@ } } // namespace quick_answers -} // namespace ash
diff --git a/chromeos/crosapi/mojom/account_manager.mojom b/chromeos/crosapi/mojom/account_manager.mojom index 73082f4..cacf91ea 100644 --- a/chromeos/crosapi/mojom/account_manager.mojom +++ b/chromeos/crosapi/mojom/account_manager.mojom
@@ -78,6 +78,13 @@ InvalidGaiaCredentialsReason invalid_gaia_credentials_reason@3; }; +// See components/account_manager_core/account_addition_options.h +[Stable] +struct AccountAdditionOptions { + bool is_available_in_arc@0; + bool show_arc_availability_picker@1; +}; + [Stable] struct AccountAdditionResult { // The result of account addition request. @@ -148,7 +155,7 @@ // ARC++ uses components/arc/mojom/auth.mojom to talk to the Chrome OS Account // Manager. // -// Next version: 8 +// Next version: 9 // Next method id: 9 [Stable, Uuid="85b9a674-9d8e-497f-98d5-22c8dca6f2b8"] interface AccountManager { @@ -174,7 +181,9 @@ // Launches account addition dialog and returns `result` with the added // account. [MinVersion = 3] - ShowAddAccountDialog@3() => (AccountAdditionResult result); + ShowAddAccountDialog@3( + [MinVersion=8] AccountAdditionOptions? add_account_options) => + (AccountAdditionResult result); // Launches account reauthentication dialog for provided `email`. [MinVersion = 3]
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn index ac47de7f..51ca0c84 100644 --- a/chromeos/dbus/BUILD.gn +++ b/chromeos/dbus/BUILD.gn
@@ -29,6 +29,7 @@ ":plugin_vm_service_proto", ":vm_applications_apps_proto", ":vm_disk_management_proto", + ":vm_launch_proto", ":vm_permission_service_proto", ":vm_sk_forwarding_proto", "//base", @@ -231,6 +232,12 @@ proto_out_dir = "chromeos/dbus/vm_disk_management" } +proto_library("vm_launch_proto") { + sources = [ "//third_party/cros_system_api/dbus/vm_launch/launch.proto" ] + + proto_out_dir = "chromeos/dbus/vm_launch" +} + proto_library("vm_sk_forwarding_proto") { sources = [ "//third_party/cros_system_api/dbus/vm_sk_forwarding/sk_forwarding.proto",
diff --git a/chromeos/dbus/fwupd/fwupd_client.cc b/chromeos/dbus/fwupd/fwupd_client.cc index 9409a6b..9bcd331 100644 --- a/chromeos/dbus/fwupd/fwupd_client.cc +++ b/chromeos/dbus/fwupd/fwupd_client.cc
@@ -156,9 +156,10 @@ void RequestUpdatesCallback(const std::string& device_id, dbus::Response* response, dbus::ErrorResponse* error_response) { + bool can_parse = true; if (!response) { LOG(ERROR) << "No Dbus response received from fwupd."; - return; + can_parse = false; } dbus::MessageReader reader(response); @@ -166,17 +167,18 @@ if (!reader.PopArray(&array_reader)) { LOG(ERROR) << "Failed to parse string from DBus Signal"; - return; + can_parse = false; } FwupdUpdateList updates; - while (array_reader.HasMoreData()) { + while (can_parse && array_reader.HasMoreData()) { // Parse update description. std::unique_ptr<base::DictionaryValue> dict = PopStringToStringDictionary(&array_reader); if (!dict) { LOG(ERROR) << "Failed to parse the update description."; - return; + // Ran into an error, exit early. + break; } const auto* version = dict->FindKey("Version");
diff --git a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc index 4f9bae8..c7f5f0fd 100644 --- a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc +++ b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc
@@ -393,7 +393,10 @@ return; ScanJobState& state = it->second; - DCHECK(!state.cancel_callback.is_null()); + if (state.cancel_callback.is_null()) { + LOG(ERROR) << "No callback active to cancel job " << scan_uuid; + return; + } if (!response) { LOG(ERROR) << "Failed to obtain CancelScanResponse"; std::move(state.cancel_callback).Run(false);
diff --git a/chromeos/dbus/userdataauth/BUILD.gn b/chromeos/dbus/userdataauth/BUILD.gn index f559243..3fb704b 100644 --- a/chromeos/dbus/userdataauth/BUILD.gn +++ b/chromeos/dbus/userdataauth/BUILD.gn
@@ -52,6 +52,7 @@ sources = [ "//third_party/cros_system_api/dbus/cryptohome/UserDataAuth.proto", + "//third_party/cros_system_api/dbus/cryptohome/auth_factor.proto", "//third_party/cros_system_api/dbus/cryptohome/fido.proto", ]
diff --git a/chromeos/memory/userspace_swap/userfaultfd.h b/chromeos/memory/userspace_swap/userfaultfd.h index b42355bd..03b727e6 100644 --- a/chromeos/memory/userspace_swap/userfaultfd.h +++ b/chromeos/memory/userspace_swap/userfaultfd.h
@@ -11,6 +11,7 @@ #include "base/files/file_descriptor_watcher_posix.h" #include "base/files/scoped_file.h" #include "base/synchronization/lock.h" +#include "base/threading/platform_thread.h" #include "chromeos/chromeos_export.h" struct uffd_msg;
diff --git a/chromeos/network/BUILD.gn b/chromeos/network/BUILD.gn index 69e1b61..a8b091b 100644 --- a/chromeos/network/BUILD.gn +++ b/chromeos/network/BUILD.gn
@@ -341,5 +341,6 @@ deps = [ ":network", "//base", + "//chromeos/components/onc:onc", ] }
diff --git a/chromeos/network/metrics/network_metrics_helper.cc b/chromeos/network/metrics/network_metrics_helper.cc index 0291b1e..799caea 100644 --- a/chromeos/network/metrics/network_metrics_helper.cc +++ b/chromeos/network/metrics/network_metrics_helper.cc
@@ -6,6 +6,7 @@ #include "base/metrics/histogram_functions.h" #include "base/notreached.h" +#include "base/strings/strcat.h" #include "chromeos/network/metrics/connection_results.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" @@ -23,43 +24,65 @@ const char kDisconnectionsWithoutUserActionSuffix[] = ".DisconnectionsWithoutUserAction"; +const char kEnableTechnologyResultSuffix[] = ".EnabledState.Enable.Result"; +const char kDisableTechnologyResultSuffix[] = ".EnabledState.Disable.Result"; + +const char kCellular[] = "Cellular"; +const char kCellularESim[] = "Cellular.ESim"; +const char kCellularPSim[] = "Cellular.PSim"; + +const char kEthernet[] = "Ethernet"; +const char kEthernetEap[] = "Ethernet.Eap"; +const char kEthernetNoEap[] = "Ethernet.NoEap"; + +const char kTether[] = "Tether"; + +const char kVPN[] = "VPN"; +const char kVPNBuiltIn[] = "VPN.TypeBuiltIn"; +const char kVPNThirdParty[] = "VPN.TypeThirdParty"; + const char kWifi[] = "WiFi"; const char kWifiOpen[] = "WiFi.SecurityOpen"; const char kWifiPasswordProtected[] = "WiFi.SecurityPasswordProtected"; -const char kTether[] = "Tether"; - chromeos::NetworkStateHandler* GetNetworkStateHandler() { return NetworkHandler::Get()->network_state_handler(); } +const absl::optional<const std::string> GetTechnologyTypeSuffix( + const std::string& technology) { + // Note that Tether is a fake technology that does not correspond to shill + // technology type. + if (technology == shill::kTypeWifi) + return kWifi; + else if (technology == shill::kTypeEthernet) + return kEthernet; + else if (technology == shill::kTypeCellular) + return kCellular; + else if (technology == shill::kTypeVPN) + return kVPN; + return absl::nullopt; +} + const std::vector<std::string> GetCellularNetworkTypeHistogams( const NetworkState* network_state) { - const std::string kCellularPrefix = "Cellular"; - const std::string kESimInfix = ".ESim"; - const std::string kPSimInfix = ".PSim"; - - std::vector<std::string> cellular_histograms{kCellularPrefix}; + std::vector<std::string> cellular_histograms{kCellular}; if (network_state->eid().empty()) - cellular_histograms.emplace_back(kCellularPrefix + kPSimInfix); + cellular_histograms.emplace_back(kCellularPSim); else - cellular_histograms.emplace_back(kCellularPrefix + kESimInfix); + cellular_histograms.emplace_back(kCellularESim); return cellular_histograms; } const std::vector<std::string> GetEthernetNetworkTypeHistograms( const NetworkState* network_state) { - const std::string kEthernetPrefix = "Ethernet"; - const std::string kEapInfix = ".Eap"; - const std::string kNoEapInfix = ".NoEap"; - - std::vector<std::string> ethernet_histograms{kEthernetPrefix}; + std::vector<std::string> ethernet_histograms{kEthernet}; if (GetNetworkStateHandler()->GetEAPForEthernet(network_state->path(), /*connected_only=*/true)) { - ethernet_histograms.emplace_back(kEthernetPrefix + kEapInfix); + ethernet_histograms.emplace_back(kEthernetEap); } else { - ethernet_histograms.emplace_back(kEthernetPrefix + kNoEapInfix); + ethernet_histograms.emplace_back(kEthernetNoEap); } return ethernet_histograms; @@ -86,24 +109,20 @@ const std::vector<std::string> GetVpnNetworkTypeHistograms( const NetworkState* network_state) { - const std::string kVpnPrefix = "VPN"; - const std::string kBuiltInInfix = ".TypeBuiltIn"; - const std::string kThirdPartyInfix = ".TypeThirdParty"; - const std::string& vpn_provider_type = network_state->GetVpnProviderType(); if (vpn_provider_type.empty()) return {}; - std::vector<std::string> vpn_histograms{kVpnPrefix}; + std::vector<std::string> vpn_histograms{kVPN}; if (vpn_provider_type == shill::kProviderThirdPartyVpn || vpn_provider_type == shill::kProviderArcVpn) { - vpn_histograms.emplace_back(kVpnPrefix + kThirdPartyInfix); + vpn_histograms.emplace_back(kVPNThirdParty); } else if (vpn_provider_type == shill::kProviderL2tpIpsec || vpn_provider_type == shill::kProviderOpenVpn || vpn_provider_type == shill::kProviderWireGuard) { - vpn_histograms.emplace_back(kVpnPrefix + kBuiltInInfix); + vpn_histograms.emplace_back(kVPNBuiltIn); } else { NOTREACHED(); } @@ -153,7 +172,8 @@ for (const auto& network_type : GetNetworkTypeHistogramNames(network_state)) { base::UmaHistogramEnumeration( - kNetworkMetricsPrefix + network_type + kAllConnectionResultSuffix, + base::StrCat( + {kNetworkMetricsPrefix, network_type, kAllConnectionResultSuffix}), connect_result); } } @@ -174,9 +194,10 @@ : UserInitiatedConnectResult::kSuccess; for (const auto& network_type : GetNetworkTypeHistogramNames(network_state)) { - base::UmaHistogramEnumeration(kNetworkMetricsPrefix + network_type + - kUserInitiatedConnectionResultSuffix, - connect_result); + base::UmaHistogramEnumeration( + base::StrCat({kNetworkMetricsPrefix, network_type, + kUserInitiatedConnectionResultSuffix}), + connect_result); } } @@ -196,6 +217,35 @@ } } +void NetworkMetricsHelper::LogEnableTechnologyResult( + const std::string& technology, + bool success) { + absl::optional<const std::string> suffix = + GetTechnologyTypeSuffix(technology); + + if (!suffix) + return; + + base::UmaHistogramBoolean(base::StrCat({kNetworkMetricsPrefix, *suffix, + kEnableTechnologyResultSuffix}), + success); +} + +// static +void NetworkMetricsHelper::LogDisableTechnologyResult( + const std::string& technology, + bool success) { + absl::optional<const std::string> suffix = + GetTechnologyTypeSuffix(technology); + + if (!suffix) + return; + + base::UmaHistogramBoolean(base::StrCat({kNetworkMetricsPrefix, *suffix, + kDisableTechnologyResultSuffix}), + success); +} + NetworkMetricsHelper::NetworkMetricsHelper() = default; NetworkMetricsHelper::~NetworkMetricsHelper() = default;
diff --git a/chromeos/network/metrics/network_metrics_helper.h b/chromeos/network/metrics/network_metrics_helper.h index 41825ae..d8f398f 100644 --- a/chromeos/network/metrics/network_metrics_helper.h +++ b/chromeos/network/metrics/network_metrics_helper.h
@@ -45,6 +45,16 @@ static void LogConnectionStateResult(const std::string& guid, ConnectionState status); + // Logs result of an attempt to enable a shill associated network technology + // type. + static void LogEnableTechnologyResult(const std::string& technology, + bool success); + + // Logs result of an attempt to disable a shill associated network technology + // type. + static void LogDisableTechnologyResult(const std::string& technology, + bool success); + NetworkMetricsHelper(); ~NetworkMetricsHelper(); };
diff --git a/chromeos/network/metrics/network_metrics_helper_unittest.cc b/chromeos/network/metrics/network_metrics_helper_unittest.cc index 8faf925..126ee9c 100644 --- a/chromeos/network/metrics/network_metrics_helper_unittest.cc +++ b/chromeos/network/metrics/network_metrics_helper_unittest.cc
@@ -119,6 +119,26 @@ const char kEthernetNoEapConnectionStateHistogram[] = "Network.Ash.Ethernet.NoEap.DisconnectionsWithoutUserAction"; +// LogEnableTechnologyResult() histograms. +const char kEnableWifiResultHistogram[] = + "Network.Ash.WiFi.EnabledState.Enable.Result"; +const char kEnableEthernetResultHistogram[] = + "Network.Ash.Ethernet.EnabledState.Enable.Result"; +const char kEnableCellularResultHistogram[] = + "Network.Ash.Cellular.EnabledState.Enable.Result"; +const char kEnableVpnResultHistogram[] = + "Network.Ash.VPN.EnabledState.Enable.Result"; + +// LogDisableTechnologyResult() histograms. +const char kDisableWifiResultHistogram[] = + "Network.Ash.WiFi.EnabledState.Disable.Result"; +const char kDisableEthernetResultHistogram[] = + "Network.Ash.Ethernet.EnabledState.Disable.Result"; +const char kDisableCellularResultHistogram[] = + "Network.Ash.Cellular.EnabledState.Disable.Result"; +const char kDisableVpnResultHistogram[] = + "Network.Ash.VPN.EnabledState.Disable.Result"; + const char kTestGuid[] = "test_guid"; const char kTestServicePath[] = "/service/network"; const char kTestServicePath1[] = "/service/network1"; @@ -166,6 +186,40 @@ TestingPrefServiceSimple local_state_; }; +TEST_F(NetworkMetricsHelperTest, EnableDisableTechnology) { + NetworkMetricsHelper::LogEnableTechnologyResult(shill::kTypeWifi, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kEnableWifiResultHistogram, 1); + + NetworkMetricsHelper::LogEnableTechnologyResult(shill::kTypeEthernet, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kEnableEthernetResultHistogram, 1); + + NetworkMetricsHelper::LogEnableTechnologyResult(shill::kTypeCellular, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kEnableCellularResultHistogram, 1); + + NetworkMetricsHelper::LogEnableTechnologyResult(shill::kTypeVPN, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kEnableVpnResultHistogram, 1); + + NetworkMetricsHelper::LogDisableTechnologyResult(shill::kTypeWifi, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kDisableWifiResultHistogram, 1); + + NetworkMetricsHelper::LogDisableTechnologyResult(shill::kTypeEthernet, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kDisableEthernetResultHistogram, 1); + + NetworkMetricsHelper::LogDisableTechnologyResult(shill::kTypeCellular, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kDisableCellularResultHistogram, 1); + + NetworkMetricsHelper::LogDisableTechnologyResult(shill::kTypeVPN, + /*success=*/true); + histogram_tester_->ExpectTotalCount(kDisableVpnResultHistogram, 1); +} + TEST_F(NetworkMetricsHelperTest, CellularESim) { shill_service_client_->AddService(kTestServicePath, kTestGuid, kTestName, shill::kTypeCellular, shill::kStateIdle,
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc index 0295110..6c9bc9e 100644 --- a/chromeos/network/shill_property_handler.cc +++ b/chromeos/network/shill_property_handler.cc
@@ -21,6 +21,7 @@ #include "chromeos/dbus/shill/shill_manager_client.h" #include "chromeos/dbus/shill/shill_profile_client.h" #include "chromeos/dbus/shill/shill_service_client.h" +#include "chromeos/network/metrics/network_metrics_helper.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state.h" #include "dbus/object_path.h" @@ -165,12 +166,16 @@ std::move(error_callback), "", "prohibited_technologies", "Ignored: Attempt to enable prohibited network technology " + technology); + NetworkMetricsHelper::LogEnableTechnologyResult(technology, + /*success=*/false); return; } enabling_technologies_.insert(technology); disabling_technologies_.erase(technology); shill_manager_->EnableTechnology( - technology, base::DoNothing(), + technology, + base::BindOnce(&NetworkMetricsHelper::LogEnableTechnologyResult, + technology, /*success=*/true), base::BindOnce(&ShillPropertyHandler::EnableTechnologyFailed, AsWeakPtr(), technology, std::move(error_callback))); } else { @@ -178,7 +183,9 @@ enabling_technologies_.erase(technology); disabling_technologies_.insert(technology); shill_manager_->DisableTechnology( - technology, base::DoNothing(), + technology, + base::BindOnce(&NetworkMetricsHelper::LogDisableTechnologyResult, + technology, /*success=*/true), base::BindOnce(&ShillPropertyHandler::DisableTechnologyFailed, AsWeakPtr(), technology, std::move(error_callback))); } @@ -554,6 +561,8 @@ network_handler::ErrorCallback error_callback, const std::string& dbus_error_name, const std::string& dbus_error_message) { + NetworkMetricsHelper::LogEnableTechnologyResult(technology, + /*success=*/false); enabling_technologies_.erase(technology); network_handler::ShillErrorCallbackFunction( "EnableTechnology Failed", technology, std::move(error_callback), @@ -566,6 +575,8 @@ network_handler::ErrorCallback error_callback, const std::string& dbus_error_name, const std::string& dbus_error_message) { + NetworkMetricsHelper::LogDisableTechnologyResult(technology, + /*success=*/false); disabling_technologies_.erase(technology); network_handler::ShillErrorCallbackFunction( "DisableTechnology Failed", technology, std::move(error_callback),
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc index 091113d..2e5b519 100644 --- a/chromeos/network/shill_property_handler_unittest.cc +++ b/chromeos/network/shill_property_handler_unittest.cc
@@ -15,6 +15,7 @@ #include "base/callback_helpers.h" #include "base/logging.h" #include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/values.h" #include "chromeos/dbus/shill/shill_clients.h" @@ -32,6 +33,13 @@ namespace { const char kStubWiFi1[] = "stub_wifi1"; +const char kEnableWifiResultHistogram[] = + "Network.Ash.WiFi.EnabledState.Enable.Result"; +const char kDisableWiFiResultHistogram[] = + "Network.Ash.WiFi.EnabledState.Disable.Result"; + +const char kEnableEthernetResultHistogram[] = + "Network.Ash.Ethernet.EnabledState.Enable.Result"; void ErrorCallbackFunction(const std::string& error_name, const std::string& error_message) { @@ -198,6 +206,7 @@ ASSERT_TRUE(profile_test_); SetupShillPropertyHandler(); base::RunLoop().RunUntilIdle(); + histogram_tester_ = std::make_unique<base::HistogramTester>(); } void TearDown() override { @@ -280,6 +289,7 @@ base::test::SingleThreadTaskEnvironment task_environment_; std::unique_ptr<TestListener> listener_; std::unique_ptr<internal::ShillPropertyHandler> shill_property_handler_; + std::unique_ptr<base::HistogramTester> histogram_tester_; ShillManagerClient::TestInterface* manager_test_; ShillDeviceClient::TestInterface* device_test_; ShillServiceClient::TestInterface* service_test_; @@ -376,6 +386,8 @@ shill::kTypeWifi, /*enabled=*/false, base::DoNothing()); EXPECT_TRUE(shill_property_handler_->IsTechnologyDisabling(shill::kTypeWifi)); base::RunLoop().RunUntilIdle(); + histogram_tester_->ExpectTotalCount(kDisableWiFiResultHistogram, 1); + histogram_tester_->ExpectBucketCount(kDisableWiFiResultHistogram, true, 1); EXPECT_EQ(1, listener_->technology_list_updates()); EXPECT_FALSE( shill_property_handler_->IsTechnologyDisabling(shill::kTypeWifi)); @@ -389,10 +401,11 @@ EXPECT_FALSE( shill_property_handler_->IsTechnologyDisabling(shill::kTypeWifi)); base::RunLoop().RunUntilIdle(); + histogram_tester_->ExpectTotalCount(kEnableWifiResultHistogram, 1); + histogram_tester_->ExpectBucketCount(kEnableWifiResultHistogram, true, 1); EXPECT_EQ(1, listener_->technology_list_updates()); EXPECT_TRUE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi)); EXPECT_FALSE(shill_property_handler_->IsTechnologyEnabling(shill::kTypeWifi)); - EXPECT_EQ(0, listener_->errors()); } @@ -567,6 +580,9 @@ shill_property_handler_->SetTechnologyEnabled( shill::kTypeEthernet, true, network_handler::ErrorCallback()); base::RunLoop().RunUntilIdle(); + histogram_tester_->ExpectTotalCount(kEnableEthernetResultHistogram, 1); + histogram_tester_->ExpectBucketCount(kEnableEthernetResultHistogram, false, + 1); EXPECT_FALSE( shill_property_handler_->IsTechnologyEnabled(shill::kTypeEthernet)); @@ -576,6 +592,8 @@ shill_property_handler_->SetTechnologyEnabled( shill::kTypeEthernet, true, network_handler::ErrorCallback()); base::RunLoop().RunUntilIdle(); + histogram_tester_->ExpectTotalCount(kEnableEthernetResultHistogram, 2); + histogram_tester_->ExpectBucketCount(kEnableEthernetResultHistogram, true, 1); EXPECT_TRUE( shill_property_handler_->IsTechnologyEnabled(shill::kTypeEthernet)); }
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc index 4cd03c5..cc172e1 100644 --- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc +++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc
@@ -75,14 +75,14 @@ NOTIMPLEMENTED(); } -void FakeServiceConnectionImpl::CreateGraphExecutorWithOptions( +void FakeServiceConnectionImpl::CreateGraphExecutor( mojom::GraphExecutorOptionsPtr options, mojo::PendingReceiver<mojom::GraphExecutor> receiver, - mojom::Model::CreateGraphExecutorWithOptionsCallback callback) { - ScheduleCall(base::BindOnce( - &FakeServiceConnectionImpl::HandleCreateGraphExecutorWithOptionsCall, - base::Unretained(this), std::move(options), std::move(receiver), - std::move(callback))); + mojom::Model::CreateGraphExecutorCallback callback) { + ScheduleCall( + base::BindOnce(&FakeServiceConnectionImpl::HandleCreateGraphExecutorCall, + base::Unretained(this), std::move(options), + std::move(receiver), std::move(callback))); } void FakeServiceConnectionImpl::LoadTextClassifier( @@ -261,10 +261,10 @@ std::move(callback).Run(load_model_result_); } -void FakeServiceConnectionImpl::HandleCreateGraphExecutorWithOptionsCall( +void FakeServiceConnectionImpl::HandleCreateGraphExecutorCall( mojom::GraphExecutorOptionsPtr options, mojo::PendingReceiver<mojom::GraphExecutor> receiver, - mojom::Model::CreateGraphExecutorWithOptionsCallback callback) { + mojom::Model::CreateGraphExecutorCallback callback) { if (create_graph_executor_result_ == mojom::CreateGraphExecutorResult::OK) graph_receivers_.Add(this, std::move(receiver));
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h index fd8b007..7ec45cf7 100644 --- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h +++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h
@@ -133,10 +133,10 @@ // mojom::Model: void REMOVED_0(mojo::PendingReceiver<mojom::GraphExecutor> receiver, mojom::Model::REMOVED_0Callback callback) override; - void CreateGraphExecutorWithOptions( + void CreateGraphExecutor( mojom::GraphExecutorOptionsPtr options, mojo::PendingReceiver<mojom::GraphExecutor> receiver, - mojom::Model::CreateGraphExecutorWithOptionsCallback callback) override; + mojom::Model::CreateGraphExecutorCallback callback) override; // mojom::GraphExecutor: // Execute() will return the tensor set by SetOutputValue() as the output. @@ -278,10 +278,10 @@ void HandleLoadFlatBufferModelCall( mojo::PendingReceiver<mojom::Model> receiver, mojom::MachineLearningService::LoadFlatBufferModelCallback callback); - void HandleCreateGraphExecutorWithOptionsCall( + void HandleCreateGraphExecutorCall( mojom::GraphExecutorOptionsPtr options, mojo::PendingReceiver<mojom::GraphExecutor> receiver, - mojom::Model::CreateGraphExecutorWithOptionsCallback callback); + mojom::Model::CreateGraphExecutorCallback callback); void HandleExecuteCall(mojom::GraphExecutor::ExecuteCallback callback); void HandleLoadTextClassifierCall( mojo::PendingReceiver<mojom::TextClassifier> receiver,
diff --git a/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc index 45e7f191..89d3ef4 100644 --- a/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc +++ b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc
@@ -277,7 +277,7 @@ callback_done = false; mojo::Remote<mojom::GraphExecutor> graph; run_loop.reset(new base::RunLoop); - model->CreateGraphExecutorWithOptions( + model->CreateGraphExecutor( mojom::GraphExecutorOptions::New(), graph.BindNewPipeAndPassReceiver(), base::BindOnce( [](bool* callback_done, mojom::CreateGraphExecutorResult result) { @@ -347,7 +347,7 @@ callback_done = false; mojo::Remote<mojom::GraphExecutor> graph; run_loop.reset(new base::RunLoop); - model->CreateGraphExecutorWithOptions( + model->CreateGraphExecutor( mojom::GraphExecutorOptions::New(), graph.BindNewPipeAndPassReceiver(), base::BindOnce( [](bool* callback_done, mojom::CreateGraphExecutorResult result) {
diff --git a/chromeos/services/machine_learning/public/mojom/model.mojom b/chromeos/services/machine_learning/public/mojom/model.mojom index d80e30c..b0f6a78 100644 --- a/chromeos/services/machine_learning/public/mojom/model.mojom +++ b/chromeos/services/machine_learning/public/mojom/model.mojom
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Next MinVersion: 2 + // Datatypes and interfaces of models for the Machine Learning API. // NOTE: This mojom exists in two places and must be kept in sync: @@ -31,15 +33,17 @@ // Test ML model. TEST_MODEL = 1, // The Smart Dim (20181115) ML model. - SMART_DIM_20181115 = 2, + UNSUPPORTED_SMART_DIM_20181115 = 2, // The Smart Dim (20190221) ML model. - SMART_DIM_20190221 = 3, + UNSUPPORTED_SMART_DIM_20190221 = 3, // The Top Cat (20190722) ML model. UNSUPPORTED_TOP_CAT_20190722 = 4, // The Smart Dim (20190521) ML model. SMART_DIM_20190521 = 5, // The Search Ranker (20190923) ML model. SEARCH_RANKER_20190923 = 6, + // The Adaptive Charging (20211105) ML model. + [MinVersion=1] ADAPTIVE_CHARGING_20211105 = 7, }; // Options for creating the executor. Options are used for testing and @@ -47,6 +51,7 @@ [Stable] struct GraphExecutorOptions { bool use_nnapi = false; + [MinVersion=1] bool use_gpu = false; }; // These values are persisted to logs. Entries should not be renumbered and @@ -58,6 +63,10 @@ MEMORY_ALLOCATION_ERROR = 2, NNAPI_UNAVAILABLE = 3, NNAPI_USE_ERROR = 4, + [MinVersion=1] GPU_UNAVAILABLE = 5, + [MinVersion=1] GPU_USE_ERROR = 6, + [MinVersion=1] DELEGATE_CONFIG_ERROR = 7, + [MinVersion=1] NOT_FULLY_DELEGABLE = 8, }; // Model specification for builtin models. @@ -94,14 +103,17 @@ // Next ordinal: 2 [Stable] interface Model { -// Deprecated messages: + // Deprecated messages: REMOVED_0@0(pending_receiver<GraphExecutor> receiver) => (CreateGraphExecutorResult result); - // This function is temporary. We plan to rationalize this interface and - // sync it with the interfaces at chromeos/service/machine_learning. - // See crbug/1081597. - CreateGraphExecutorWithOptions@1(GraphExecutorOptions options, - pending_receiver<GraphExecutor> receiver) => + // Creates a new GraphExecutor with the specified `options` and binds it to + // `receiver`. The GraphExecutor can be used to repeatedly evaluate this + // `Model`. + // * A Model can have more than one GraphExecutor. + // * Releasing this GraphExecutor frees the associated memory (but + // doesn't free the Model unless its pipe is also closed). + CreateGraphExecutor@1(GraphExecutorOptions options, + pending_receiver<GraphExecutor> receiver) => (CreateGraphExecutorResult result); };
diff --git a/chromeos/strings/chromeos_strings_eu.xtb b/chromeos/strings/chromeos_strings_eu.xtb index a8ca6db..c92931b 100644 --- a/chromeos/strings/chromeos_strings_eu.xtb +++ b/chromeos/strings/chromeos_strings_eu.xtb
@@ -252,7 +252,7 @@ <translation id="4731797938093519117">Gurasoen sarbidea</translation> <translation id="473775607612524610">Eguneratu</translation> <translation id="4744944742468440486">Zure hautapenarekin erlazionatutako informazioa</translation> -<translation id="475869545581454722">Chrome OS-eko pasahitza eguneratu egin da</translation> +<translation id="475869545581454722">Chrome OS-ko pasahitza eguneratu egin da</translation> <translation id="4773299976671772492">Gelditu egin da</translation> <translation id="4782311465517282004">Eskuratu definizioak, itzulpenak edo unitate-bihurketak testua eskuineko botoiarekin sakatzean edo sakatuta edukitzean</translation> <translation id="4794140124556169553">Baliteke PUZaren proba bat egiteak sistemaren errendimenduan eragina izatea</translation>
diff --git a/components/BUILD.gn b/components/BUILD.gn index 19dc0ad..43fe2ef 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -780,7 +780,7 @@ if (is_android) { sources += [ - "autofill_assistant/browser/js_flow_executor_unittest.cc", + "autofill_assistant/browser/js_flow_executor_impl_unittest.cc", "autofill_assistant/browser/mock_script_executor_delegate.cc", "autofill_assistant/browser/mock_script_executor_delegate.h", "autofill_assistant/browser/web/web_controller_browsertest.cc",
diff --git a/components/account_manager_core/BUILD.gn b/components/account_manager_core/BUILD.gn index dc11587..c342842 100644 --- a/components/account_manager_core/BUILD.gn +++ b/components/account_manager_core/BUILD.gn
@@ -12,6 +12,7 @@ sources = [ "account.cc", "account.h", + "account_addition_options.h", "account_addition_result.cc", "account_addition_result.h", "account_manager_facade.cc",
diff --git a/components/account_manager_core/account_addition_options.h b/components/account_manager_core/account_addition_options.h new file mode 100644 index 0000000..2d18d855 --- /dev/null +++ b/components/account_manager_core/account_addition_options.h
@@ -0,0 +1,24 @@ +// 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_ACCOUNT_MANAGER_CORE_ACCOUNT_ADDITION_OPTIONS_H_ +#define COMPONENTS_ACCOUNT_MANAGER_CORE_ACCOUNT_ADDITION_OPTIONS_H_ + +#include "base/component_export.h" + +namespace account_manager { + +// Options passed to the account addition request. +struct COMPONENT_EXPORT(ACCOUNT_MANAGER_CORE) AccountAdditionOptions { + // The default value for ARC availability for the account to be added. + bool is_available_in_arc = false; + // Whether the account picker that allows to change ARC availability should be + // shown. When set to `true` - the ARC availability toggle in account addition + // flow will be hidden. + bool show_arc_availability_picker = false; +}; + +} // namespace account_manager + +#endif // COMPONENTS_ACCOUNT_MANAGER_CORE_ACCOUNT_ADDITION_OPTIONS_H_
diff --git a/components/account_manager_core/account_manager_facade_impl.cc b/components/account_manager_core/account_manager_facade_impl.cc index 58b8336..7fa4512 100644 --- a/components/account_manager_core/account_manager_facade_impl.cc +++ b/components/account_manager_core/account_manager_facade_impl.cc
@@ -69,6 +69,36 @@ std::move(callback).Run(maybe_error.value()); } +// Returns whether an account should be available in ARC after it's added +// in-session. +bool GetIsAvailableInArcBySource( + AccountManagerFacade::AccountAdditionSource source) { + switch (source) { + // Accounts added from Ash should be available in ARC. + case AccountManagerFacade::AccountAdditionSource::kSettingsAddAccountButton: + case AccountManagerFacade::AccountAdditionSource:: + kAccountManagerMigrationWelcomeScreen: + case AccountManagerFacade::AccountAdditionSource::kArc: + case AccountManagerFacade::AccountAdditionSource::kOnboarding: + return true; + // Accounts added from the browser should not be available in ARC. + case AccountManagerFacade::AccountAdditionSource::kPrintPreviewDialog: + case AccountManagerFacade::AccountAdditionSource::kChromeProfileCreation: + case AccountManagerFacade::AccountAdditionSource::kOgbAddAccount: + return false; + // These are reauthentication cases. ARC visibility shouldn't change for + // reauthentication. + case AccountManagerFacade::AccountAdditionSource::kContentAreaReauth: + case AccountManagerFacade::AccountAdditionSource:: + kSettingsReauthAccountButton: + case AccountManagerFacade::AccountAdditionSource:: + kAvatarBubbleReauthAccountButton: + case AccountManagerFacade::AccountAdditionSource::kChromeExtensionReauth: + NOTREACHED(); + return false; + } +} + } // namespace // Fetches access tokens over the Mojo remote to `AccountManager`. @@ -293,7 +323,14 @@ base::UmaHistogramEnumeration(kAccountAdditionSource, source); + crosapi::mojom::AccountAdditionOptionsPtr options = + crosapi::mojom::AccountAdditionOptions::New(); + options->is_available_in_arc = GetIsAvailableInArcBySource(source); + options->show_arc_availability_picker = + (source == AccountManagerFacade::AccountAdditionSource::kArc); + account_manager_remote_->ShowAddAccountDialog( + std::move(options), base::BindOnce(&AccountManagerFacadeImpl::OnShowAddAccountDialogFinished, weak_factory_.GetWeakPtr(), std::move(callback))); }
diff --git a/components/account_manager_core/account_manager_facade_impl.h b/components/account_manager_core/account_manager_facade_impl.h index 51025f1d1..40987e5 100644 --- a/components/account_manager_core/account_manager_facade_impl.h +++ b/components/account_manager_core/account_manager_facade_impl.h
@@ -83,6 +83,15 @@ ShowAddAccountDialogUMA); FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, ShowReauthAccountDialogCallsMojo); + FRIEND_TEST_ALL_PREFIXES( + AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromAsh); + FRIEND_TEST_ALL_PREFIXES( + AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromLacros); + FRIEND_TEST_ALL_PREFIXES( + AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromArc); FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, ShowReauthAccountDialogUMA); FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest,
diff --git a/components/account_manager_core/account_manager_facade_impl_unittest.cc b/components/account_manager_core/account_manager_facade_impl_unittest.cc index c140834..f805edc8 100644 --- a/components/account_manager_core/account_manager_facade_impl_unittest.cc +++ b/components/account_manager_core/account_manager_facade_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "chromeos/crosapi/mojom/account_manager.mojom.h" #include "components/account_manager_core/account.h" +#include "components/account_manager_core/account_addition_options.h" #include "components/account_manager_core/account_addition_result.h" #include "components/account_manager_core/account_manager_facade.h" #include "components/account_manager_core/account_manager_test_util.h" @@ -157,8 +158,10 @@ ToMojoGoogleServiceAuthError(GoogleServiceAuthError::AuthErrorNone())); } - void ShowAddAccountDialog(ShowAddAccountDialogCallback callback) override { + void ShowAddAccountDialog(crosapi::mojom::AccountAdditionOptionsPtr options, + ShowAddAccountDialogCallback callback) override { show_add_account_dialog_calls_++; + show_add_account_dialog_options_ = FromMojoAccountAdditionOptions(options); std::move(callback).Run( account_manager::ToMojoAccountAdditionResult(*add_account_result_)); } @@ -228,6 +231,11 @@ return show_add_account_dialog_calls_; } + absl::optional<account_manager::AccountAdditionOptions> + show_add_account_dialog_options() const { + return show_add_account_dialog_options_; + } + int show_reauth_account_dialog_calls() const { return show_reauth_account_dialog_calls_; } @@ -238,6 +246,8 @@ private: int show_add_account_dialog_calls_ = 0; + absl::optional<account_manager::AccountAdditionOptions> + show_add_account_dialog_options_; int show_reauth_account_dialog_calls_ = 0; int show_manage_accounts_settings_calls_ = 0; bool is_initialized_ = false; @@ -436,6 +446,68 @@ EXPECT_EQ(1, account_manager().show_add_account_dialog_calls()); } +TEST_F(AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromAsh) { + std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = + CreateFacade(); + account_manager().SetAccountAdditionResult( + account_manager::AccountAdditionResult::FromStatus( + account_manager::AccountAdditionResult::Status::kUnexpectedResponse)); + EXPECT_EQ(0, account_manager().show_add_account_dialog_calls()); + account_manager_facade->ShowAddAccountDialog( + account_manager::AccountManagerFacade::AccountAdditionSource:: + kSettingsAddAccountButton); + account_manager_facade->FlushMojoForTesting(); + EXPECT_EQ(1, account_manager().show_add_account_dialog_calls()); + EXPECT_TRUE(account_manager().show_add_account_dialog_options().has_value()); + EXPECT_TRUE( + account_manager().show_add_account_dialog_options()->is_available_in_arc); + EXPECT_FALSE(account_manager() + .show_add_account_dialog_options() + ->show_arc_availability_picker); +} + +TEST_F(AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromLacros) { + std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = + CreateFacade(); + account_manager().SetAccountAdditionResult( + account_manager::AccountAdditionResult::FromStatus( + account_manager::AccountAdditionResult::Status::kUnexpectedResponse)); + EXPECT_EQ(0, account_manager().show_add_account_dialog_calls()); + account_manager_facade->ShowAddAccountDialog( + account_manager::AccountManagerFacade::AccountAdditionSource:: + kOgbAddAccount); + account_manager_facade->FlushMojoForTesting(); + EXPECT_EQ(1, account_manager().show_add_account_dialog_calls()); + EXPECT_TRUE(account_manager().show_add_account_dialog_options().has_value()); + EXPECT_FALSE( + account_manager().show_add_account_dialog_options()->is_available_in_arc); + EXPECT_FALSE(account_manager() + .show_add_account_dialog_options() + ->show_arc_availability_picker); +} + +TEST_F(AccountManagerFacadeImplTest, + ShowAddAccountDialogSetsCorrectOptionsForAdditionFromArc) { + std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = + CreateFacade(); + account_manager().SetAccountAdditionResult( + account_manager::AccountAdditionResult::FromStatus( + account_manager::AccountAdditionResult::Status::kUnexpectedResponse)); + EXPECT_EQ(0, account_manager().show_add_account_dialog_calls()); + account_manager_facade->ShowAddAccountDialog( + account_manager::AccountManagerFacade::AccountAdditionSource::kArc); + account_manager_facade->FlushMojoForTesting(); + EXPECT_EQ(1, account_manager().show_add_account_dialog_calls()); + EXPECT_TRUE(account_manager().show_add_account_dialog_options().has_value()); + EXPECT_TRUE( + account_manager().show_add_account_dialog_options()->is_available_in_arc); + EXPECT_TRUE(account_manager() + .show_add_account_dialog_options() + ->show_arc_availability_picker); +} + TEST_F(AccountManagerFacadeImplTest, ShowAddAccountDialogUMA) { base::HistogramTester tester; std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade =
diff --git a/components/account_manager_core/account_manager_util.cc b/components/account_manager_core/account_manager_util.cc index 560cf9f8..895d3d2 100644 --- a/components/account_manager_core/account_manager_util.cc +++ b/components/account_manager_core/account_manager_util.cc
@@ -6,6 +6,7 @@ #include "absl/types/optional.h" #include "components/account_manager_core/account.h" +#include "components/account_manager_core/account_addition_options.h" #include "components/account_manager_core/account_addition_result.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -306,4 +307,18 @@ return mojo_result; } +absl::optional<account_manager::AccountAdditionOptions> +FromMojoAccountAdditionOptions( + const crosapi::mojom::AccountAdditionOptionsPtr& mojo_options) { + if (!mojo_options) + return absl::nullopt; + + account_manager::AccountAdditionOptions result; + result.is_available_in_arc = mojo_options->is_available_in_arc; + result.show_arc_availability_picker = + mojo_options->show_arc_availability_picker; + + return result; +} + } // namespace account_manager
diff --git a/components/account_manager_core/account_manager_util.h b/components/account_manager_core/account_manager_util.h index 690d6969..c6ef0f42 100644 --- a/components/account_manager_core/account_manager_util.h +++ b/components/account_manager_core/account_manager_util.h
@@ -7,6 +7,7 @@ #include "chromeos/crosapi/mojom/account_manager.mojom.h" #include "components/account_manager_core/account.h" +#include "components/account_manager_core/account_addition_options.h" #include "components/account_manager_core/account_addition_result.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -60,6 +61,11 @@ COMPONENT_EXPORT(ACCOUNT_MANAGER_CORE) crosapi::mojom::AccountAdditionResultPtr ToMojoAccountAdditionResult( account_manager::AccountAdditionResult result); + +COMPONENT_EXPORT(ACCOUNT_MANAGER_CORE) +absl::optional<account_manager::AccountAdditionOptions> +FromMojoAccountAdditionOptions( + const crosapi::mojom::AccountAdditionOptionsPtr& mojo_options); } // namespace account_manager #endif // COMPONENTS_ACCOUNT_MANAGER_CORE_ACCOUNT_MANAGER_UTIL_H_
diff --git a/components/account_manager_core/chromeos/account_manager_mojo_service.cc b/components/account_manager_core/chromeos/account_manager_mojo_service.cc index c078f94..46a2ed7 100644 --- a/components/account_manager_core/chromeos/account_manager_mojo_service.cc +++ b/components/account_manager_core/chromeos/account_manager_mojo_service.cc
@@ -108,6 +108,7 @@ } void AccountManagerMojoService::ShowAddAccountDialog( + crosapi::mojom::AccountAdditionOptionsPtr options, ShowAddAccountDialogCallback callback) { DCHECK(account_manager_ui_); if (account_manager_ui_->IsDialogShown()) {
diff --git a/components/account_manager_core/chromeos/account_manager_mojo_service.h b/components/account_manager_core/chromeos/account_manager_mojo_service.h index a3b1abd..107e2e8 100644 --- a/components/account_manager_core/chromeos/account_manager_mojo_service.h +++ b/components/account_manager_core/chromeos/account_manager_mojo_service.h
@@ -55,7 +55,8 @@ void GetPersistentErrorForAccount( mojom::AccountKeyPtr mojo_account_key, GetPersistentErrorForAccountCallback callback) override; - void ShowAddAccountDialog(ShowAddAccountDialogCallback callback) override; + void ShowAddAccountDialog(mojom::AccountAdditionOptionsPtr options, + ShowAddAccountDialogCallback callback) override; void ShowReauthAccountDialog(const std::string& email, base::OnceClosure closure) override; void ShowManageAccountsSettings() override;
diff --git a/components/account_manager_core/chromeos/account_manager_mojo_service_unittest.cc b/components/account_manager_core/chromeos/account_manager_mojo_service_unittest.cc index 06fcff7..ee9c466 100644 --- a/components/account_manager_core/chromeos/account_manager_mojo_service_unittest.cc +++ b/components/account_manager_core/chromeos/account_manager_mojo_service_unittest.cc
@@ -189,15 +189,17 @@ mojom::AccountAdditionResultPtr ShowAddAccountDialog( base::OnceClosure quit_closure) { auto add_account_result = mojom::AccountAdditionResult::New(); - account_manager_mojo_service_->ShowAddAccountDialog(base::BindOnce( - [](base::OnceClosure quit_closure, - mojom::AccountAdditionResultPtr* add_account_result, - mojom::AccountAdditionResultPtr result) { - (*add_account_result)->status = result->status; - (*add_account_result)->account = std::move(result->account); - std::move(quit_closure).Run(); - }, - std::move(quit_closure), &add_account_result)); + account_manager_mojo_service_->ShowAddAccountDialog( + crosapi::mojom::AccountAdditionOptions::New(), + base::BindOnce( + [](base::OnceClosure quit_closure, + mojom::AccountAdditionResultPtr* add_account_result, + mojom::AccountAdditionResultPtr result) { + (*add_account_result)->status = result->status; + (*add_account_result)->account = std::move(result->account); + std::move(quit_closure).Run(); + }, + std::move(quit_closure), &add_account_result)); return add_account_result; } @@ -369,7 +371,7 @@ GetFakeAccountManagerUI()->SetIsDialogShown(true); mojom::AccountAdditionResultPtr account_addition_result; account_manager_async_waiter()->ShowAddAccountDialog( - &account_addition_result); + crosapi::mojom::AccountAdditionOptions::New(), &account_addition_result); // Check status. EXPECT_EQ(mojom::AccountAdditionResult::Status::kAlreadyInProgress,
diff --git a/components/app_restore/app_restore_utils.cc b/components/app_restore/app_restore_utils.cc index 68ced6d..5b6ee00 100644 --- a/components/app_restore/app_restore_utils.cc +++ b/components/app_restore/app_restore_utils.cc
@@ -19,6 +19,8 @@ namespace app_restore { namespace { +const char kCrxAppPrefix[] = "_crx_"; + // Always use the full restore ARC data if ARC apps for desks templates is not // enabled. bool ShouldUseFullRestoreArcData() { @@ -184,4 +186,11 @@ session_id); } +std::string GetAppIdFromAppName(const std::string& app_name) { + std::string prefix(kCrxAppPrefix); + if (app_name.substr(0, prefix.length()) != prefix) + return std::string(); + return app_name.substr(prefix.length()); +} + } // namespace app_restore
diff --git a/components/app_restore/app_restore_utils.h b/components/app_restore/app_restore_utils.h index 2e493c82f..e5ba89a 100644 --- a/components/app_restore/app_restore_utils.h +++ b/components/app_restore/app_restore_utils.h
@@ -60,6 +60,10 @@ COMPONENT_EXPORT(APP_RESTORE) int32_t GetArcRestoreWindowIdForSessionId(int32_t session_id); +// Remove the "_crx_" prefix from a given `app_name` to get the app id. +COMPONENT_EXPORT(APP_RESTORE) +std::string GetAppIdFromAppName(const std::string& app_name); + } // namespace app_restore #endif // COMPONENTS_APP_RESTORE_APP_RESTORE_UTILS_H_
diff --git a/components/app_restore/full_restore_save_handler.cc b/components/app_restore/full_restore_save_handler.cc index b0021fa..627ada8 100644 --- a/components/app_restore/full_restore_save_handler.cc +++ b/components/app_restore/full_restore_save_handler.cc
@@ -37,15 +37,6 @@ // Delay starting `save_timer_` during the system startup phase. constexpr base::TimeDelta kWaitDelay = base::Seconds(120); -const char kCrxAppPrefix[] = "_crx_"; - -std::string GetAppIdFromAppName(const std::string& app_name) { - std::string prefix(kCrxAppPrefix); - if (app_name.substr(0, prefix.length()) != prefix) - return std::string(); - return app_name.substr(prefix.length()); -} - } // namespace FullRestoreSaveHandler* FullRestoreSaveHandler::GetInstance() { @@ -155,7 +146,8 @@ std::string* browser_app_name = window->GetProperty(app_restore::kBrowserAppNameKey); if (browser_app_name) { - std::string app_id = GetAppIdFromAppName(*browser_app_name); + std::string app_id = + app_restore::GetAppIdFromAppName(*browser_app_name); auto it = profile_path_to_app_registry_cache_.find(active_profile_path_); if (it != profile_path_to_app_registry_cache_.end() && it->second && @@ -334,6 +326,20 @@ ModifyWindowInfo(window_id, window_info); } +void FullRestoreSaveHandler::OnLacrosChromeAppWindowAdded( + const std::string& app_id, + const std::string& window_id) { + if (lacros_save_handler_) + lacros_save_handler_->OnAppWindowAdded(app_id, window_id); +} + +void FullRestoreSaveHandler::OnLacrosChromeAppWindowRemoved( + const std::string& app_id, + const std::string& window_id) { + if (lacros_save_handler_) + lacros_save_handler_->OnAppWindowRemoved(app_id, window_id); +} + void FullRestoreSaveHandler::Flush(const base::FilePath& profile_path) { if (save_running_.find(profile_path) != save_running_.end()) return;
diff --git a/components/app_restore/full_restore_save_handler.h b/components/app_restore/full_restore_save_handler.h index 5036788..a4782cfa 100644 --- a/components/app_restore/full_restore_save_handler.h +++ b/components/app_restore/full_restore_save_handler.h
@@ -110,6 +110,18 @@ // Saves |window_info| to |profile_path_to_restore_data_|. void SaveWindowInfo(const app_restore::WindowInfo& window_info); + // Invoked when an Chrome app Lacros window is created. `app_id` is the + // AppService id, and `window_id` is the wayland app_id property for the + // window. + void OnLacrosChromeAppWindowAdded(const std::string& app_id, + const std::string& window_id); + + // Invoked when an Chrome app Lacros window is removed. `app_id` is the + // AppService id, and `window_id` is the wayland app_id property for the + // window. + void OnLacrosChromeAppWindowRemoved(const std::string& app_id, + const std::string& window_id); + // Flushes the full restore file in |profile_path| with the current restore // data. void Flush(const base::FilePath& profile_path);
diff --git a/components/app_restore/full_restore_utils.cc b/components/app_restore/full_restore_utils.cc index cd3fa4df..79b74af 100644 --- a/components/app_restore/full_restore_utils.cc +++ b/components/app_restore/full_restore_utils.cc
@@ -75,4 +75,22 @@ return FullRestoreSaveHandler::GetInstance()->GetAppId(window); } +void OnLacrosChromeAppWindowAdded(const std::string& app_id, + const std::string& window_id) { + if (!full_restore::features::IsFullRestoreForLacrosEnabled()) + return; + + FullRestoreSaveHandler::GetInstance()->OnLacrosChromeAppWindowAdded( + app_id, window_id); +} + +void OnLacrosChromeAppWindowRemoved(const std::string& app_id, + const std::string& window_id) { + if (!full_restore::features::IsFullRestoreForLacrosEnabled()) + return; + + FullRestoreSaveHandler::GetInstance()->OnLacrosChromeAppWindowRemoved( + app_id, window_id); +} + } // namespace full_restore
diff --git a/components/app_restore/full_restore_utils.h b/components/app_restore/full_restore_utils.h index 4b53591b..9ed3771 100644 --- a/components/app_restore/full_restore_utils.h +++ b/components/app_restore/full_restore_utils.h
@@ -66,6 +66,18 @@ COMPONENT_EXPORT(APP_RESTORE) std::string GetAppId(aura::Window* window); +// Invoked when an Chrome app Lacros window is created. `app_id` is the +// AppService id, and `window_id` is the wayland app_id property for the window. +COMPONENT_EXPORT(APP_RESTORE) +void OnLacrosChromeAppWindowAdded(const std::string& app_id, + const std::string& window_id); + +// Invoked when an Chrome app Lacros window is removed. `app_id` is the +// AppService id, and `window_id` is the wayland app_id property for the window. +COMPONENT_EXPORT(APP_RESTORE) +void OnLacrosChromeAppWindowRemoved(const std::string& app_id, + const std::string& window_id); + } // namespace full_restore #endif // COMPONENTS_APP_RESTORE_FULL_RESTORE_UTILS_H_
diff --git a/components/app_restore/lacros_save_handler.cc b/components/app_restore/lacros_save_handler.cc index 876ec8e..73c58b20 100644 --- a/components/app_restore/lacros_save_handler.cc +++ b/components/app_restore/lacros_save_handler.cc
@@ -6,6 +6,7 @@ #include "components/app_restore/app_launch_info.h" #include "components/app_restore/full_restore_save_handler.h" +#include "components/app_restore/window_info.h" #include "components/app_restore/window_properties.h" #include "extensions/common/constants.h" #include "ui/aura/window.h" @@ -21,11 +22,28 @@ const std::string* lacros_window_id = window->GetProperty(app_restore::kLacrosWindowId); DCHECK(lacros_window_id); - window_candidates_[*lacros_window_id].app_id = extension_misc::kLacrosAppId; - window_candidates_[*lacros_window_id].window_id = ++window_id_; - auto app_launch_info = std::make_unique<app_restore::AppLaunchInfo>( - extension_misc::kLacrosAppId, window_id_); + std::string app_id; + int32_t window_id = ++window_id_; + std::unique_ptr<app_restore::AppLaunchInfo> app_launch_info; + + auto it = lacros_window_id_to_app_id_.find(*lacros_window_id); + if (it != lacros_window_id_to_app_id_.end()) { + // For Chrome app windows, get the app launch info and set the Chrome app + // id. + app_id = it->second; + app_launch_info = FullRestoreSaveHandler::GetInstance()->FetchAppLaunchInfo( + profile_path_, app_id); + app_launch_info->window_id = window_id; + } else { + app_id = extension_misc::kLacrosAppId; + app_launch_info = + std::make_unique<app_restore::AppLaunchInfo>(app_id, window_id); + } + + window_candidates_[*lacros_window_id].app_id = app_id; + window_candidates_[*lacros_window_id].window_id = window_id; + FullRestoreSaveHandler::GetInstance()->AddAppLaunchInfo( profile_path_, std::move(app_launch_info)); } @@ -34,6 +52,8 @@ const std::string* lacros_window_id = window->GetProperty(app_restore::kLacrosWindowId); DCHECK(lacros_window_id); + lacros_window_id_to_app_id_.erase(*lacros_window_id); + auto it = window_candidates_.find(*lacros_window_id); if (it == window_candidates_.end()) return; @@ -44,4 +64,41 @@ window_candidates_.erase(it); } +void LacrosSaveHandler::OnAppWindowAdded(const std::string& app_id, + const std::string& lacros_window_id) { + auto it = window_candidates_.find(lacros_window_id); + if (it == window_candidates_.end()) { + // If the window is not created yet, save the app id to + // `lacros_window_id_to_app_id_` to wait for the window. + lacros_window_id_to_app_id_[lacros_window_id] = app_id; + return; + } + + // If the window has been created, get the app launch info and the current + // window info, then remove the restore data for lacros browser app id, and + // re-save the restore data for the Chrome app id. + + auto* save_handler = FullRestoreSaveHandler::GetInstance(); + DCHECK(save_handler); + auto window_info = save_handler->GetWindowInfo( + profile_path_, it->second.app_id, it->second.window_id); + + save_handler->RemoveAppRestoreData(profile_path_, it->second.app_id, + it->second.window_id); + + it->second.app_id = app_id; + auto app_launch_info = + save_handler->FetchAppLaunchInfo(profile_path_, app_id); + app_launch_info->window_id = it->second.window_id; + + save_handler->AddAppLaunchInfo(profile_path_, std::move(app_launch_info)); + save_handler->SaveWindowInfo(*window_info); +} + +void LacrosSaveHandler::OnAppWindowRemoved( + const std::string& app_id, + const std::string& lacros_window_id) { + lacros_window_id_to_app_id_.erase(lacros_window_id); +} + } // namespace full_restore
diff --git a/components/app_restore/lacros_save_handler.h b/components/app_restore/lacros_save_handler.h index 192e78f..c52bb0e 100644 --- a/components/app_restore/lacros_save_handler.h +++ b/components/app_restore/lacros_save_handler.h
@@ -19,9 +19,7 @@ // LacrosSaveHandler is a helper class for FullRestoreSaveHandler to handle // Lacros windows special cases, e.g. Lacros window id, etc. // TODO(crbug.com/1239984): -// 1. Save app launch info for Chrome app windows opened with Lacros windows. -// 2. Save window info for Chrome app windows opened with Lacros windows. -// 3. Use the browser session id as the window id. +// 1. Use the browser session id as the window id. class COMPONENT_EXPORT(APP_RESTORE) LacrosSaveHandler { public: explicit LacrosSaveHandler(const base::FilePath& profile_path); @@ -35,6 +33,18 @@ // Invoked when `window` is destroyed. void OnWindowDestroyed(aura::Window* window); + // Invoked when an Chrome app Lacros window is created. `app_id` is the + // AppService id, and `window_id` is the wayland app_id property for the + // window. + void OnAppWindowAdded(const std::string& app_id, + const std::string& lacros_window_id); + + // Invoked when an Chrome app Lacros window is removed. `app_id` is the + // AppService id, and `window_id` is the wayland app_id property for the + // window. + void OnAppWindowRemoved(const std::string& app_id, + const std::string& lacros_window_id); + private: struct WindowData { std::string app_id; @@ -54,6 +64,9 @@ // OnAppWindowAdded is called, `app_id` is modified to the Chrome app id. The // record is removed when the window is destroyed. std::map<std::string, WindowData> window_candidates_; + + // The map from the lacros window id to the app id for Chrome app windows. + std::map<std::string, std::string> lacros_window_id_to_app_id_; }; } // namespace full_restore
diff --git a/components/assist_ranker/ranker_model_loader_impl.cc b/components/assist_ranker/ranker_model_loader_impl.cc index 6a97371..65199d9c 100644 --- a/components/assist_ranker/ranker_model_loader_impl.cc +++ b/components/assist_ranker/ranker_model_loader_impl.cc
@@ -121,7 +121,7 @@ // There was no configured model path. Switch the state to IDLE and // fall through to consider the URL. state_ = LoaderState::IDLE; - FALLTHROUGH; + [[fallthrough]]; case LoaderState::IDLE: if (model_url_.is_valid()) { StartLoadFromURL(); @@ -130,7 +130,7 @@ // There was no configured model URL. Switch the state to FINISHED and // fall through. state_ = LoaderState::FINISHED; - FALLTHROUGH; + [[fallthrough]]; case LoaderState::FINISHED: case LoaderState::LOADING_FROM_FILE: case LoaderState::LOADING_FROM_URL:
diff --git a/components/autofill/content/renderer/page_passwords_analyser.cc b/components/autofill/content/renderer/page_passwords_analyser.cc index 436e3ac..f5a22fad 100644 --- a/components/autofill/content/renderer/page_passwords_analyser.cc +++ b/components/autofill/content/renderer/page_passwords_analyser.cc
@@ -331,7 +331,7 @@ switch (password_count) { case 3: (*autocomplete_suggestions)[password_inputs[0]] = "current-password"; - FALLTHROUGH; // To match the last two password fields. + [[fallthrough]]; // To match the last two password fields. case 2: (*autocomplete_suggestions)[password_inputs[password_count - 2]] = "new-password";
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc index 14b4bec..ee86766 100644 --- a/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -1409,7 +1409,7 @@ case COMMAND_LINE_URL: scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( switches::kAutofillServerURL, autofill_server_url.spec()); - FALLTHROUGH; + [[fallthrough]]; case DEFAULT_URL: scoped_feature_list_2_.InitAndEnableFeature( features::kAutofillServerCommunication);
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.cc b/components/autofill/core/browser/metrics/autofill_metrics.cc index ba2c58ed..a5e60fc6 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics.cc
@@ -523,7 +523,7 @@ switch (metric_type) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case AutofillMetrics::TYPE_SUBMISSION: return ""; case AutofillMetrics::TYPE_NO_SUBMISSION:
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc index 8898ed4..e3f788b 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -308,7 +308,8 @@ void CreditCardSaveManager::OnDidUploadCard( AutofillClient::PaymentsRpcResult result, - const std::string& server_id) { + const payments::PaymentsClient::UploadCardResponseDetails& + upload_card_response_details) { if (observer_for_testing_) observer_for_testing_->OnReceivedUploadCardResponse();
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.h b/components/autofill/core/browser/payments/credit_card_save_manager.h index 43c4370..c505c75 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.h +++ b/components/autofill/core/browser/payments/credit_card_save_manager.h
@@ -152,8 +152,10 @@ // |AutofillClient::PaymentsRpcResult::kSuccess|, clears strikes for the saved // card. Additionally, |server_id| may, optionally, contain the opaque // identifier for the card on the server. Exposed for testing. - virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id); + virtual void OnDidUploadCard( + AutofillClient::PaymentsRpcResult result, + const payments::PaymentsClient::UploadCardResponseDetails& + upload_card_response_details); private: friend class CreditCardSaveManagerTest;
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc index 7a62f27..b540239 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -1234,8 +1234,11 @@ credit_card_save_manager_->SetCreditCardUploadEnabled(true); - const char* const server_id = "InstrumentData:1234"; - payments_client_->SetServerIdForCardUpload(server_id); + payments::PaymentsClient::UploadCardResponseDetails + upload_card_response_details; + upload_card_response_details.server_id = "InstrumentData:1234"; + payments_client_->SetUploadCardResponseDetailsForUploadCard( + upload_card_response_details); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. @@ -5035,8 +5038,11 @@ // bubble is shown. TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NumStrikesLoggedOnUploadNotSuccess) { - const char* const server_id = "InstrumentData:1234"; - payments_client_->SetServerIdForCardUpload(server_id); + payments::PaymentsClient::UploadCardResponseDetails + upload_card_response_details; + upload_card_response_details.server_id = "InstrumentData:1234"; + payments_client_->SetUploadCardResponseDetailsForUploadCard( + upload_card_response_details); TestCreditCardSaveStrikeDatabase credit_card_save_strike_database = TestCreditCardSaveStrikeDatabase(strike_database_); EXPECT_EQ(0, credit_card_save_strike_database.GetStrikes("1111")); @@ -5047,7 +5053,8 @@ credit_card_save_manager_->set_upload_request_card_number( u"4111111111111111"); credit_card_save_manager_->OnDidUploadCard( - AutofillClient::PaymentsRpcResult::kTryAgainFailure, server_id); + AutofillClient::PaymentsRpcResult::kTryAgainFailure, + upload_card_response_details); EXPECT_EQ(1, credit_card_save_strike_database.GetStrikes("1111")); }
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index e196dcd..d3258e9 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -593,10 +593,12 @@ class UploadCardRequest : public PaymentsRequest { public: - UploadCardRequest(const PaymentsClient::UploadRequestDetails& request_details, - const bool full_sync_enabled, - base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> callback) + UploadCardRequest( + const PaymentsClient::UploadRequestDetails& request_details, + const bool full_sync_enabled, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const PaymentsClient::UploadCardResponseDetails&)> + callback) : request_details_(request_details), full_sync_enabled_(full_sync_enabled), callback_(std::move(callback)) {} @@ -692,22 +694,23 @@ void ParseResponse(const base::Value& response) override { const std::string* credit_card_id = response.FindStringKey("credit_card_id"); - server_id_ = credit_card_id ? *credit_card_id : std::string(); + upload_card_response_details_.server_id = + credit_card_id ? *credit_card_id : std::string(); } bool IsResponseComplete() override { return true; } void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - std::move(callback_).Run(result, server_id_); + std::move(callback_).Run(result, upload_card_response_details_); } private: const PaymentsClient::UploadRequestDetails request_details_; const bool full_sync_enabled_; base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> + const PaymentsClient::UploadCardResponseDetails&)> callback_; - std::string server_id_; + PaymentsClient::UploadCardResponseDetails upload_card_response_details_; }; class MigrateCardsRequest : public PaymentsRequest { @@ -1037,7 +1040,7 @@ void PaymentsClient::UploadCard( const PaymentsClient::UploadRequestDetails& request_details, base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> callback) { + const UploadCardResponseDetails&)> callback) { IssueRequest( std::make_unique<UploadCardRequest>( request_details, account_info_getter_->IsSyncFeatureEnabled(),
diff --git a/components/autofill/core/browser/payments/payments_client.h b/components/autofill/core/browser/payments/payments_client.h index 2202ea7..a7252e5 100644 --- a/components/autofill/core/browser/payments/payments_client.h +++ b/components/autofill/core/browser/payments/payments_client.h
@@ -277,6 +277,17 @@ LOCAL_CARD_MIGRATION_SETTINGS_PAGE, }; + // TODO(crbug.com/1285086): Remove the |server_id| field from + // UploadCardResponseDetails since it is never used. + // A collection of information received in the response for an + // UploadCardRequest. + struct UploadCardResponseDetails { + std::string server_id; + // TODO(crbug.com/1281695): Add |virtual_card_enrollment_state| and + // |card_art_url| data members when integrating all of the logic for the + // virtual card enrollment flow. + }; + // TODO(crbug.com/1281695): Add GetDetailsForEnrollRequest. // A collection of information received in the response for a // GetDetailsForEnrollRequest. @@ -373,7 +384,8 @@ virtual void UploadCard( const UploadRequestDetails& details, base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> callback); + const PaymentsClient::UploadCardResponseDetails&)> + callback); // The user has indicated that they would like to migrate their local credit // cards. This request will fail server-side if a successful call to
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc index e42e5b242..6f71767 100644 --- a/components/autofill/core/browser/payments/payments_client_unittest.cc +++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -128,7 +128,7 @@ switches::kWalletServiceUseSandbox, "0"); result_ = AutofillClient::PaymentsRpcResult::kNone; - server_id_.clear(); + upload_card_response_details_.server_id.clear(); unmask_response_details_ = nullptr; legal_message_.reset(); has_variations_header_ = false; @@ -200,9 +200,10 @@ } void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) { + const PaymentsClient::UploadCardResponseDetails& + upload_card_respone_details) { result_ = result; - server_id_ = server_id; + upload_card_response_details_ = upload_card_respone_details; } #if !defined(OS_ANDROID) && !defined(OS_IOS) @@ -434,7 +435,7 @@ raw_ptr<payments::PaymentsClient::UnmaskDetails> unmask_details_; // Server ID of a saved card via credit card upload save. - std::string server_id_; + PaymentsClient::UploadCardResponseDetails upload_card_response_details_; // The OptChangeResponseDetails retrieved from an OptChangeRequest. PaymentsClient::OptChangeResponseDetails opt_change_response_; // The UnmaskResponseDetails retrieved from an UnmaskRequest. Includes PAN. @@ -1140,7 +1141,7 @@ IssueOAuthToken(); ReturnResponse(net::HTTP_OK, "{}"); EXPECT_EQ(AutofillClient::PaymentsRpcResult::kSuccess, result_); - EXPECT_TRUE(server_id_.empty()); + EXPECT_TRUE(upload_card_response_details_.server_id.empty()); } TEST_F(PaymentsClientTest, UploadSuccessWithServerId) { @@ -1148,7 +1149,7 @@ IssueOAuthToken(); ReturnResponse(net::HTTP_OK, "{ \"credit_card_id\": \"InstrumentData:1\" }"); EXPECT_EQ(AutofillClient::PaymentsRpcResult::kSuccess, result_); - EXPECT_EQ("InstrumentData:1", server_id_); + EXPECT_EQ("InstrumentData:1", upload_card_response_details_.server_id); } TEST_F(PaymentsClientTest, UploadIncludesNonLocationData) {
diff --git a/components/autofill/core/browser/payments/test_credit_card_save_manager.cc b/components/autofill/core/browser/payments/test_credit_card_save_manager.cc index 6fa87d0..703cc37 100644 --- a/components/autofill/core/browser/payments/test_credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/test_credit_card_save_manager.cc
@@ -44,9 +44,10 @@ void TestCreditCardSaveManager::OnDidUploadCard( AutofillClient::PaymentsRpcResult result, - const std::string& server_id) { + const payments::PaymentsClient::UploadCardResponseDetails& + upload_card_response_details) { credit_card_was_uploaded_ = true; - CreditCardSaveManager::OnDidUploadCard(result, server_id); + CreditCardSaveManager::OnDidUploadCard(result, upload_card_response_details); } } // namespace autofill
diff --git a/components/autofill/core/browser/payments/test_credit_card_save_manager.h b/components/autofill/core/browser/payments/test_credit_card_save_manager.h index 0a90fdef..ef4b361 100644 --- a/components/autofill/core/browser/payments/test_credit_card_save_manager.h +++ b/components/autofill/core/browser/payments/test_credit_card_save_manager.h
@@ -45,8 +45,10 @@ void set_upload_request_card_number(const std::u16string& credit_card_number); private: - void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) override; + void OnDidUploadCard( + AutofillClient::PaymentsRpcResult result, + const payments::PaymentsClient::UploadCardResponseDetails& + upload_card_response_details) override; bool credit_card_upload_enabled_ = false; bool credit_card_was_uploaded_ = false;
diff --git a/components/autofill/core/browser/payments/test_payments_client.cc b/components/autofill/core/browser/payments/test_payments_client.cc index 4381fbe..3a9e78c 100644 --- a/components/autofill/core/browser/payments/test_payments_client.cc +++ b/components/autofill/core/browser/payments/test_payments_client.cc
@@ -79,11 +79,12 @@ void TestPaymentsClient::UploadCard( const payments::PaymentsClient::UploadRequestDetails& request_details, base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> callback) { + const PaymentsClient::UploadCardResponseDetails&)> + callback) { upload_card_addresses_ = request_details.profiles; active_experiments_ = request_details.active_experiments; std::move(callback).Run(AutofillClient::PaymentsRpcResult::kSuccess, - server_id_); + upload_card_response_details_); } void TestPaymentsClient::MigrateCards( @@ -161,8 +162,10 @@ ->Append(std::move(key_info)); } -void TestPaymentsClient::SetServerIdForCardUpload(std::string server_id) { - server_id_ = server_id; +void TestPaymentsClient::SetUploadCardResponseDetailsForUploadCard( + const PaymentsClient::UploadCardResponseDetails& + upload_card_response_details) { + upload_card_response_details_ = upload_card_response_details; } void TestPaymentsClient::SetSaveResultForCardsMigration(
diff --git a/components/autofill/core/browser/payments/test_payments_client.h b/components/autofill/core/browser/payments/test_payments_client.h index b4e79532..50ab316 100644 --- a/components/autofill/core/browser/payments/test_payments_client.h +++ b/components/autofill/core/browser/payments/test_payments_client.h
@@ -60,7 +60,8 @@ void UploadCard( const payments::PaymentsClient::UploadRequestDetails& request_details, base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::string&)> callback) override; + const PaymentsClient::UploadCardResponseDetails&)> + callback) override; void MigrateCards( const MigrationRequestDetails& details, @@ -82,7 +83,9 @@ std::string credential_id, std::string relying_party_id); - void SetServerIdForCardUpload(std::string); + void SetUploadCardResponseDetailsForUploadCard( + const PaymentsClient::UploadCardResponseDetails& + upload_card_response_details); void SetSaveResultForCardsMigration( std::unique_ptr<std::unordered_map<std::string, std::string>> @@ -126,7 +129,7 @@ } private: - std::string server_id_; + PaymentsClient::UploadCardResponseDetails upload_card_response_details_; // Some metrics are affected by the latency of GetUnmaskDetails, so it is // useful to control whether or not GetUnmaskDetails() is responded to. bool should_return_unmask_details_ = true;
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 593d56c..aacb9bc6 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -98,6 +98,14 @@ const base::Feature kAutofillEnableToolbarStatusChip{ "AutofillEnableToolbarStatusChip", base::FEATURE_DISABLED_BY_DEFAULT}; +// When enabled, the user will have the ability to update the virtual card +// enrollment of a credit card through their chrome browser after certain +// autofill flows (for example, downstream and upstream), and from the settings +// page. +const base::Feature kAutofillEnableUpdateVirtualCardEnrollment{ + "AutofillEnableUpdateVirtualCardEnrollment", + base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, the option of using cloud token virtual card will be offered // when all requirements are met. const base::Feature kAutofillEnableVirtualCard{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 4f46970..1cbdaa5 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -28,6 +28,7 @@ extern const base::Feature kAutofillEnableOffersInDownstream; extern const base::Feature kAutofillEnableStickyManualFallbackForCards; extern const base::Feature kAutofillEnableToolbarStatusChip; +extern const base::Feature kAutofillEnableUpdateVirtualCardEnrollment; extern const base::Feature kAutofillEnableVirtualCard; extern const base::Feature kAutofillEnableVirtualCardsRiskBasedAuthentication; extern const base::Feature kAutofillFillMerchantPromoCodeFields;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index f631115..289256c 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -168,8 +168,9 @@ "info_box.h", "intent_strings.cc", "intent_strings.h", - "js_flow_executor.cc", "js_flow_executor.h", + "js_flow_executor_impl.cc", + "js_flow_executor_impl.h", "metrics.cc", "metrics.h", "onboarding_result.h",
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 3f85bdc..2acba43 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -879,6 +879,9 @@ // point and therefore the reason we pass here in the argument should be // ignored. client_->Shutdown(Metrics::DropOutReason::UI_CLOSED_UNEXPECTEDLY); + } else if (needs_ui_) { + needs_ui_ = false; + client_->DestroyUI(); } } @@ -891,7 +894,11 @@ void Controller::EnterStoppedState(bool show_feedback_chip) { if (script_tracker_) script_tracker_->StopScript(); + SetStoppedUI(show_feedback_chip); + EnterState(AutofillAssistantState::STOPPED); +} +void Controller::SetStoppedUI(bool show_feedback_chip) { std::unique_ptr<std::vector<UserAction>> final_actions; if (base::FeatureList::IsEnabled(features::kAutofillAssistantFeedbackChip) && show_feedback_chip) { @@ -912,7 +919,6 @@ SetUserActions(std::move(final_actions)); SetCollectUserDataOptions(nullptr); SetForm(nullptr, base::DoNothing(), base::DoNothing()); - EnterState(AutofillAssistantState::STOPPED); } bool Controller::EnterState(AutofillAssistantState state) { @@ -941,8 +947,6 @@ if (!ui_shown_ && StateNeedsUI(state)) { RequireUI(); - } else if (needs_ui_ && state == AutofillAssistantState::TRACKING) { - needs_ui_ = false; } else if (browse_mode_invisible_ && ui_shown_ && state == AutofillAssistantState::BROWSE) { needs_ui_ = false; @@ -1176,9 +1180,13 @@ if (!start_message.empty()) SetStatusMessage(start_message); - EnterState(AutofillAssistantState::RUNNING); - if (needs_ui) + if (needs_ui) { RequireUI(); + } else if (needs_ui_ && state_ == AutofillAssistantState::TRACKING) { + needs_ui_ = false; + client_->DestroyUI(); + } + EnterState(AutofillAssistantState::RUNNING); touchable_element_area()->Clear(); @@ -1221,6 +1229,7 @@ client_->Shutdown(Metrics::DropOutReason::SCRIPT_SHUTDOWN); return; } + needs_ui_ = false; end_state = AutofillAssistantState::TRACKING; break; @@ -1231,6 +1240,8 @@ RecordDropOutOrShutdown(Metrics::DropOutReason::SCRIPT_SHUTDOWN); return; } + needs_ui_ = true; + SetStoppedUI(show_feedback_chip_on_graceful_shutdown_); end_state = AutofillAssistantState::TRACKING; break; @@ -1242,10 +1253,14 @@ client_->Shutdown(Metrics::DropOutReason::CUSTOM_TAB_CLOSED); return; } + needs_ui_ = false; end_state = AutofillAssistantState::TRACKING; return; case ScriptExecutor::CONTINUE: + if (end_state == AutofillAssistantState::TRACKING) { + needs_ui_ = false; + } break; default: @@ -1405,6 +1420,10 @@ return true; } +bool Controller::NeedsUI() const { + return needs_ui_; +} + void Controller::ShowFirstMessageAndStart() { // |status_message_| may be non-empty due to a trigger script that was run. SetStatusMessage( @@ -2111,6 +2130,15 @@ return; } + // When in TRACKING state all navigation is allowed, but user-initiated + // navigation will close the UI if any. + if (state_ == AutofillAssistantState::TRACKING && + is_user_initiated_or_back_forward && + !navigation_handle->WasServerRedirect()) { + ShutdownIfNecessary(); + return; + } + // Note that BROWSE state end conditions are in DidFinishNavigation, in order // to be able to properly evaluate the committed url. }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 15d40ef3..6ed39af1 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -107,7 +107,7 @@ std::unique_ptr<TriggerContext> trigger_context); // Returns true if the controller is in a state where UI is necessary. - bool NeedsUI() const { return needs_ui_; } + bool NeedsUI() const override; // Called when an accessibility service with "FEEDBACK_SPOKEN" feedback type // is enabled or disabled. @@ -418,9 +418,13 @@ void ShowFirstMessageAndStart(); // Clear out visible state and enter the stopped state. + void EnterStoppedState(bool show_feedback_chip); + + // Configure the UI for the stopped state, clearing out visible state except + // for the message and possibly the "Send feedback" chip. // If |show_feedback_chip| is true, a "Send feedback" chip will be added to // the bottom sheet. - void EnterStoppedState(bool show_feedback_chip); + void SetStoppedUI(bool show_feedback_chip); void OnFeedbackChipClicked();
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 40a891a3..16278ab7 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -1326,11 +1326,12 @@ TEST_F(ControllerTest, TrackScriptShowUIOnTell) { SupportsScriptResponseProto script_response; auto* script = AddRunnableScript(&script_response, "runnable"); - script->mutable_presentation()->set_needs_ui(false); + script->mutable_presentation()->set_needs_ui(true); SetupScripts(script_response); ActionsResponseProto runnable_script; runnable_script.add_actions()->mutable_tell()->set_message("error"); + runnable_script.add_actions()->mutable_stop(); SetupActionsForScript("runnable", runnable_script); // Start tracking at example.com, with one script matching @@ -1345,7 +1346,93 @@ controller_->PerformDirectAction(0, std::make_unique<TriggerContext>())); EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); - // As the controller is back in tracking mode; A UI is not needed anymore. + // The last tell message should still be shown to the user. + EXPECT_TRUE(controller_->NeedsUI()); + + // Check the full history of state transitions. + EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::TRACKING, + AutofillAssistantState::RUNNING, + AutofillAssistantState::TRACKING)); +} + +TEST_F(ControllerTest, RunDirectActionWhileTrackingWithUi) { + SupportsScriptResponseProto script_response; + auto* script_needs_ui = AddRunnableScript(&script_response, "needs_ui"); + script_needs_ui->mutable_presentation()->set_needs_ui(true); + + auto* script_no_ui = AddRunnableScript(&script_response, "no_ui"); + script_no_ui->mutable_presentation()->set_needs_ui(false); + SetupScripts(script_response); + + ActionsResponseProto needs_ui_script; + needs_ui_script.add_actions()->mutable_tell()->set_message("error"); + needs_ui_script.add_actions()->mutable_stop(); + SetupActionsForScript("needs_ui", needs_ui_script); + + ActionsResponseProto no_ui_script; + no_ui_script.add_actions()->mutable_stop(); + SetupActionsForScript("no_ui", no_ui_script); + + // Start tracking at example.com, with one script matching + SetLastCommittedUrl(GURL("http://example.com/")); + + controller_->Track(std::make_unique<TriggerContext>(), base::DoNothing()); + ASSERT_THAT(controller_->GetDirectActionScripts(), SizeIs(2)); + EXPECT_EQ(controller_->GetDirectActionScripts()[0].path, "needs_ui"); + + EXPECT_FALSE(controller_->NeedsUI()); + EXPECT_CALL(mock_client_, AttachUI()); + EXPECT_TRUE( + controller_->PerformDirectAction(0, std::make_unique<TriggerContext>())); + EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); + + // The last tell message should still be shown to the user. + EXPECT_TRUE(controller_->NeedsUI()); + + EXPECT_CALL(mock_client_, DestroyUI()); + EXPECT_TRUE( + controller_->PerformDirectAction(1, std::make_unique<TriggerContext>())); + + // UI should have been cleared + EXPECT_FALSE(controller_->NeedsUI()); + + // Check the full history of state transitions. + EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::TRACKING, + AutofillAssistantState::RUNNING, + AutofillAssistantState::TRACKING, + AutofillAssistantState::RUNNING, + AutofillAssistantState::TRACKING)); +} + +TEST_F(ControllerTest, TrackScriptClosesUI) { + SupportsScriptResponseProto script_response; + auto* script = AddRunnableScript(&script_response, "runnable"); + script->mutable_presentation()->set_needs_ui(false); + SetupScripts(script_response); + + ActionsResponseProto runnable_script; + runnable_script.add_actions()->mutable_tell()->set_message("hi"); + runnable_script.add_actions() + ->mutable_wait_for_dom() + ->mutable_wait_condition(); + runnable_script.add_actions()->mutable_stop(); + + SetupActionsForScript("runnable", runnable_script); + + // Start tracking at example.com, with one script matching + SetLastCommittedUrl(GURL("http://example.com/")); + + controller_->Track(std::make_unique<TriggerContext>(), base::DoNothing()); + ASSERT_THAT(controller_->GetDirectActionScripts(), SizeIs(1)); + + EXPECT_FALSE(controller_->NeedsUI()); + EXPECT_CALL(mock_client_, AttachUI()); + EXPECT_TRUE( + controller_->PerformDirectAction(0, std::make_unique<TriggerContext>())); + EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); + + // The tell action wasn't the last one before close, so UI should close when + // the script is finished. EXPECT_FALSE(controller_->NeedsUI()); // Check the full history of state transitions. @@ -1377,8 +1464,8 @@ controller_->PerformDirectAction(0, std::make_unique<TriggerContext>())); EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); - // As the controller is back in tracking mode; A UI is not needed anymore. - EXPECT_FALSE(controller_->NeedsUI()); + // UI must remain visible for the user to see the error message. + EXPECT_TRUE(controller_->NeedsUI()); // Check the full history of state transitions. EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::TRACKING, @@ -1959,6 +2046,41 @@ AutofillAssistantState::STOPPED)); } +TEST_F(ControllerTest, NavigationWhileTrackingWithUi) { + SupportsScriptResponseProto script_response; + auto* script = AddRunnableScript(&script_response, "runnable"); + script->mutable_presentation()->set_needs_ui(true); + SetupScripts(script_response); + + ActionsResponseProto runnable_script; + runnable_script.add_actions()->mutable_tell()->set_message("error"); + runnable_script.add_actions()->mutable_stop(); + SetupActionsForScript("runnable", runnable_script); + + // Start tracking at example.com, with one script matching + SetLastCommittedUrl(GURL("http://example.com/")); + + controller_->Track(std::make_unique<TriggerContext>(), base::DoNothing()); + ASSERT_THAT(controller_->GetDirectActionScripts(), SizeIs(1)); + + EXPECT_TRUE( + controller_->PerformDirectAction(0, std::make_unique<TriggerContext>())); + EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); + EXPECT_TRUE(controller_->NeedsUI()); + + // Browser navigation will destroy the UI. + EXPECT_CALL(mock_client_, DestroyUI()); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL("http://a.example.com/page")); + EXPECT_EQ(AutofillAssistantState::TRACKING, controller_->GetState()); + EXPECT_FALSE(controller_->NeedsUI()); + + // Full history of state transitions. + EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::TRACKING, + AutofillAssistantState::RUNNING, + AutofillAssistantState::TRACKING)); +} + TEST_F(ControllerTest, NavigationToGooglePropertyShutsDownDestroyingUI) { SupportsScriptResponseProto script_response; AddRunnableScript(&script_response, "autostart")
diff --git a/components/autofill_assistant/browser/js_flow_executor.h b/components/autofill_assistant/browser/js_flow_executor.h index 0cef5be..aa73717 100644 --- a/components/autofill_assistant/browser/js_flow_executor.h +++ b/components/autofill_assistant/browser/js_flow_executor.h
@@ -8,15 +8,13 @@ #include <memory> #include <string> #include "base/callback_forward.h" -#include "base/memory/weak_ptr.h" #include "base/values.h" #include "components/autofill_assistant/browser/client_status.h" -#include "components/autofill_assistant/browser/devtools/devtools_client.h" namespace autofill_assistant { -// Executes a JS flow in a sandbox JS context. The flow may request additional -// native actions to be performed by its delegate. +// Executes a JS flow. The flow may request additional native actions to be +// performed by its delegate. class JsFlowExecutor { public: class Delegate { @@ -33,142 +31,14 @@ finished_callback) = 0; }; - // |delegate| must outlive the JsFlowExecutor. - JsFlowExecutor(content::WebContents* web_contents, Delegate* delegate); - ~JsFlowExecutor(); - JsFlowExecutor(const JsFlowExecutor&) = delete; - JsFlowExecutor& operator=(const JsFlowExecutor&) = delete; + virtual ~JsFlowExecutor() = default; - // Starts executing |js_flow| in an isolated JS context. Once finished (or on - // error), |result_callback| is invoked with the final result. In the case of - // an uncaught exception during flow execution, the returned status may - // contain a stack trace and additional information (limited to the sandbox). - // Only one flow may run at a time. - // - // Flows may request additional native actions from the delegate, using the - // following syntax: - // - // let [status, result] = await runNativeAction('request') - // - // - |status| is an int corresponding to a ProcessedActionStatusProto. - // - [result] is a struct containing the result value, or an empty struct if - // no result was returned. The specific contents depend on the - // native action. - // - |runNativeAction| is provided automatically and takes a single argument. - // The type of the argument will depend on what the native - // delegate expects, but will typically be a serialized - // protobuffer. - // - // The flow result is one of the following, depending on the |js_flow|: - // (1) ACTION_APPLIED and a base::Value dictionary containing the 'result' key - // and value, as returned by the JS flow. Example for a one-liner js flow - // 'return 12345': - // { - // "result": { - // "description": "12345", - // "type": "number", - // "value": 12345 - // } - // } - // See the unit tests for further examples. Note: field names are - // auto-generated by base::Value serializers. - // - // (2) UNEXPECTED_JS_ERROR in case of an execution error, along with a - // base::Value dictionary containing the 'exceptionDetails' key and exception, - // if available. Note that this exception originates from the sandbox JS - // context. Example: - // JS flow: - // function doSomething(x) { - // console.log('foobar says: ' + x); - // throw new Error('Hello world!'); - // } - // function entrypoint() { - // doSomething('bla'); - // } - // entrypoint(); - // - // Returned exception details: - // "exceptionDetails": { - // "columnNumber": 0, - // "exception": { - // "className": "Error", - // "description": "Error: Hello world! - // at doSomething (<anonymous>:16:33) - // at entrypoint (<anonymous>:19:27) - // at <anonymous>:21:25 - // at <anonymous>:22:28", - // "objectId": "-3968045700143737919.4.2", - // "subtype": "error", - // "type": "object" - // }, - // "exceptionId": 2, - // "lineNumber": 0, - // "text": "Uncaught (in promise) Error: Hello world!" - // } - // - // (3) UNEXPECTED_JS_ERROR and null in case of internal errors during script - // execution (i.e., unrecoverable devtools errors). The status details may - // contain additional information. - void Start( - const std::string& js_flow, - base::OnceCallback<void(const ClientStatus&, - std::unique_ptr<base::Value>)> result_callback); - - private: - void InternalStart(); - void OnGetFrameTree(const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<page::GetFrameTreeResult> result); - void IsolatedWorldCreated( - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<page::CreateIsolatedWorldResult> result); - void RefreshNativeActionPromise(); - void OnNativeActionRequested(const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::EvaluateResult> result); - void OnNativeActionRequestActionRetrieved( - const std::string& js_array_object_id, - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result); - void OnNativeActionRequestFulfillPromiseRetrieved( - std::unique_ptr<base::Value> action_request, - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result); - void OnNativeActionFinished(const std::string& fulfill_promise_object_id, - const ClientStatus& status, - std::unique_ptr<base::Value> result); - void OnFlowResumed(const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result); - void OnFlowFinished(const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::EvaluateResult> result); - void RunCallback(const ClientStatus& status, - std::unique_ptr<base::Value> result_value); - - // Returns true if |reply_status| and |result| are ok. Else, stops the flow - // and returns false. - template <typename T> - bool CheckResultAndStopOnError( - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<T>& result, - const char* file, - int line) { - ClientStatus status = - CheckJavaScriptResult(reply_status, result.get(), file, line); - if (!status.ok()) { - RunCallback(status, (result != nullptr ? result->Serialize() : nullptr)); - return false; - } - return true; - } - - Delegate* const delegate_; - std::unique_ptr<DevtoolsClient> devtools_client_; - int isolated_world_context_id_ = -1; - - // Only set during a flow. - std::unique_ptr<std::string> js_flow_; - base::OnceCallback<void(const ClientStatus&, std::unique_ptr<base::Value>)> - callback_; - - base::WeakPtrFactory<JsFlowExecutor> weak_ptr_factory_{this}; + // Runs the specified JS flow. Refer to the specific implementation for more + // details. + virtual void Start(const std::string& js_flow, + base::OnceCallback<void(const ClientStatus&, + std::unique_ptr<base::Value>)> + result_callback) = 0; }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/js_flow_executor.cc b/components/autofill_assistant/browser/js_flow_executor_impl.cc similarity index 87% rename from components/autofill_assistant/browser/js_flow_executor.cc rename to components/autofill_assistant/browser/js_flow_executor_impl.cc index 6f9252c..87a56ff 100644 --- a/components/autofill_assistant/browser/js_flow_executor.cc +++ b/components/autofill_assistant/browser/js_flow_executor_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/autofill_assistant/browser/js_flow_executor.h" +#include "components/autofill_assistant/browser/js_flow_executor_impl.h" #include "base/json/json_writer.h" #include "base/logging.h" #include "base/strings/strcat.h" @@ -35,15 +35,15 @@ namespace autofill_assistant { -JsFlowExecutor::JsFlowExecutor(content::WebContents* web_contents, - Delegate* delegate) +JsFlowExecutorImpl::JsFlowExecutorImpl(content::WebContents* web_contents, + Delegate* delegate) : delegate_(delegate), devtools_client_(std::make_unique<DevtoolsClient>( content::DevToolsAgentHost::GetOrCreateFor(web_contents))) {} -JsFlowExecutor::~JsFlowExecutor() = default; +JsFlowExecutorImpl::~JsFlowExecutorImpl() = default; -void JsFlowExecutor::Start( +void JsFlowExecutorImpl::Start( const std::string& js_flow, base::OnceCallback<void(const ClientStatus&, std::unique_ptr<base::Value>)> callback) { @@ -57,14 +57,14 @@ callback_ = std::move(callback); if (isolated_world_context_id_ == -1) { devtools_client_->GetPage()->GetFrameTree( - kMainFrame, base::BindOnce(&JsFlowExecutor::OnGetFrameTree, + kMainFrame, base::BindOnce(&JsFlowExecutorImpl::OnGetFrameTree, weak_ptr_factory_.GetWeakPtr())); } else { InternalStart(); } } -void JsFlowExecutor::OnGetFrameTree( +void JsFlowExecutorImpl::OnGetFrameTree( const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<page::GetFrameTreeResult> result) { if (!result) { @@ -80,11 +80,11 @@ .SetFrameId(result->GetFrameTree()->GetFrame()->GetId()) .Build(), kMainFrame, - base::BindOnce(&JsFlowExecutor::IsolatedWorldCreated, + base::BindOnce(&JsFlowExecutorImpl::IsolatedWorldCreated, weak_ptr_factory_.GetWeakPtr())); } -void JsFlowExecutor::IsolatedWorldCreated( +void JsFlowExecutorImpl::IsolatedWorldCreated( const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<page::CreateIsolatedWorldResult> result) { if (!result) { @@ -99,7 +99,7 @@ InternalStart(); } -void JsFlowExecutor::InternalStart() { +void JsFlowExecutorImpl::InternalStart() { DCHECK(isolated_world_context_id_ != -1); DCHECK(callback_); @@ -135,11 +135,11 @@ .SetContextId(isolated_world_context_id_) .Build(), kMainFrame, - base::BindOnce(&JsFlowExecutor::OnFlowFinished, + base::BindOnce(&JsFlowExecutorImpl::OnFlowFinished, weak_ptr_factory_.GetWeakPtr())); } -void JsFlowExecutor::RefreshNativeActionPromise() { +void JsFlowExecutorImpl::RefreshNativeActionPromise() { devtools_client_->GetRuntime()->Evaluate( runtime::EvaluateParams::Builder() .SetExpression(kRunNativeAction) @@ -147,11 +147,11 @@ .SetContextId(isolated_world_context_id_) .Build(), kMainFrame, - base::BindOnce(&JsFlowExecutor::OnNativeActionRequested, + base::BindOnce(&JsFlowExecutorImpl::OnNativeActionRequested, weak_ptr_factory_.GetWeakPtr())); } -void JsFlowExecutor::OnNativeActionRequested( +void JsFlowExecutorImpl::OnNativeActionRequested( const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::EvaluateResult> result) { if (!CheckResultAndStopOnError(reply_status, result, __FILE__, __LINE__)) { @@ -170,11 +170,11 @@ .SetFunctionDeclaration(std::string(kArrayGetNthElement)) .Build(), kMainFrame, - base::BindOnce(&JsFlowExecutor::OnNativeActionRequestActionRetrieved, + base::BindOnce(&JsFlowExecutorImpl::OnNativeActionRequestActionRetrieved, weak_ptr_factory_.GetWeakPtr(), js_array_object_id)); } -void JsFlowExecutor::OnNativeActionRequestActionRetrieved( +void JsFlowExecutorImpl::OnNativeActionRequestActionRetrieved( const std::string& js_array_object_id, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::CallFunctionOnResult> result) { @@ -209,11 +209,11 @@ .Build(), kMainFrame, base::BindOnce( - &JsFlowExecutor::OnNativeActionRequestFulfillPromiseRetrieved, + &JsFlowExecutorImpl::OnNativeActionRequestFulfillPromiseRetrieved, weak_ptr_factory_.GetWeakPtr(), remote_object->Serialize())); } -void JsFlowExecutor::OnNativeActionRequestFulfillPromiseRetrieved( +void JsFlowExecutorImpl::OnNativeActionRequestFulfillPromiseRetrieved( std::unique_ptr<base::Value> action_request, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::CallFunctionOnResult> result) { @@ -238,12 +238,12 @@ delegate_->RunNativeAction( std::move(action_request), - base::BindOnce(&JsFlowExecutor::OnNativeActionFinished, + base::BindOnce(&JsFlowExecutorImpl::OnNativeActionFinished, weak_ptr_factory_.GetWeakPtr(), fulfill_promise_object->GetObjectId())); } -void JsFlowExecutor::OnNativeActionFinished( +void JsFlowExecutorImpl::OnNativeActionFinished( const std::string& fulfill_promise_object_id, const ClientStatus& result_status, std::unique_ptr<base::Value> result_value) { @@ -272,11 +272,11 @@ .SetFunctionDeclaration(std::string(kFulfillActionPromise)) .Build(), kMainFrame, - base::BindOnce(&JsFlowExecutor::OnFlowResumed, + base::BindOnce(&JsFlowExecutorImpl::OnFlowResumed, weak_ptr_factory_.GetWeakPtr())); } -void JsFlowExecutor::OnFlowResumed( +void JsFlowExecutorImpl::OnFlowResumed( const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::CallFunctionOnResult> result) { // This should never fail, but if it does, we need to catch it here to prevent @@ -286,7 +286,7 @@ } } -void JsFlowExecutor::OnFlowFinished( +void JsFlowExecutorImpl::OnFlowFinished( const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::EvaluateResult> result) { // Note that the result is always serialized if available, not just if the @@ -296,8 +296,9 @@ (result != nullptr ? result->Serialize() : nullptr)); } -void JsFlowExecutor::RunCallback(const ClientStatus& status, - std::unique_ptr<base::Value> result_value) { +void JsFlowExecutorImpl::RunCallback( + const ClientStatus& status, + std::unique_ptr<base::Value> result_value) { if (!status.ok() && result_value) { DVLOG(1) << "Flow failed with " << status << " and result: " << *result_value;
diff --git a/components/autofill_assistant/browser/js_flow_executor_impl.h b/components/autofill_assistant/browser/js_flow_executor_impl.h new file mode 100644 index 0000000..19f3837 --- /dev/null +++ b/components/autofill_assistant/browser/js_flow_executor_impl.h
@@ -0,0 +1,163 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_JS_FLOW_EXECUTOR_IMPL_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_JS_FLOW_EXECUTOR_IMPL_H_ + +#include <memory> +#include <string> +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "components/autofill_assistant/browser/client_status.h" +#include "components/autofill_assistant/browser/devtools/devtools_client.h" +#include "components/autofill_assistant/browser/js_flow_executor.h" + +namespace autofill_assistant { + +// Executes a JS flow in a sandbox JS context. The flow may request additional +// native actions to be performed by its delegate. +class JsFlowExecutorImpl : public JsFlowExecutor { + public: + // |delegate| must outlive the JsFlowExecutorImpl. + JsFlowExecutorImpl(content::WebContents* web_contents, Delegate* delegate); + ~JsFlowExecutorImpl() override; + JsFlowExecutorImpl(const JsFlowExecutorImpl&) = delete; + JsFlowExecutorImpl& operator=(const JsFlowExecutorImpl&) = delete; + + // Starts executing |js_flow| in an isolated JS context. Once finished (or on + // error), |result_callback| is invoked with the final result. In the case of + // an uncaught exception during flow execution, the returned status may + // contain a stack trace and additional information (limited to the sandbox). + // Only one flow may run at a time. + // + // Flows may request additional native actions from the delegate, using the + // following syntax: + // + // let [status, result] = await runNativeAction('request') + // + // - |status| is an int corresponding to a ProcessedActionStatusProto. + // - [result] is a struct containing the result value, or an empty struct if + // no result was returned. The specific contents depend on the + // native action. + // - |runNativeAction| is provided automatically and takes a single argument. + // The type of the argument will depend on what the native + // delegate expects, but will typically be a serialized + // protobuffer. + // + // The flow result is one of the following, depending on the |js_flow|: + // (1) ACTION_APPLIED and a base::Value dictionary containing the 'result' key + // and value, as returned by the JS flow. Example for a one-liner js flow + // 'return 12345': + // { + // "result": { + // "description": "12345", + // "type": "number", + // "value": 12345 + // } + // } + // See the unit tests for further examples. Note: field names are + // auto-generated by base::Value serializers. + // + // (2) UNEXPECTED_JS_ERROR in case of an execution error, along with a + // base::Value dictionary containing the 'exceptionDetails' key and exception, + // if available. Note that this exception originates from the sandbox JS + // context. Example: + // JS flow: + // function doSomething(x) { + // console.log('foobar says: ' + x); + // throw new Error('Hello world!'); + // } + // function entrypoint() { + // doSomething('bla'); + // } + // entrypoint(); + // + // Returned exception details: + // "exceptionDetails": { + // "columnNumber": 0, + // "exception": { + // "className": "Error", + // "description": "Error: Hello world! + // at doSomething (<anonymous>:16:33) + // at entrypoint (<anonymous>:19:27) + // at <anonymous>:21:25 + // at <anonymous>:22:28", + // "objectId": "-3968045700143737919.4.2", + // "subtype": "error", + // "type": "object" + // }, + // "exceptionId": 2, + // "lineNumber": 0, + // "text": "Uncaught (in promise) Error: Hello world!" + // } + // + // (3) UNEXPECTED_JS_ERROR and null in case of internal errors during script + // execution (i.e., unrecoverable devtools errors). The status details may + // contain additional information. + void Start(const std::string& js_flow, + base::OnceCallback<void(const ClientStatus&, + std::unique_ptr<base::Value>)> + result_callback) override; + + private: + void InternalStart(); + void OnGetFrameTree(const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<page::GetFrameTreeResult> result); + void IsolatedWorldCreated( + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<page::CreateIsolatedWorldResult> result); + void RefreshNativeActionPromise(); + void OnNativeActionRequested(const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::EvaluateResult> result); + void OnNativeActionRequestActionRetrieved( + const std::string& js_array_object_id, + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnNativeActionRequestFulfillPromiseRetrieved( + std::unique_ptr<base::Value> action_request, + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnNativeActionFinished(const std::string& fulfill_promise_object_id, + const ClientStatus& status, + std::unique_ptr<base::Value> result); + void OnFlowResumed(const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnFlowFinished(const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::EvaluateResult> result); + void RunCallback(const ClientStatus& status, + std::unique_ptr<base::Value> result_value); + + // Returns true if |reply_status| and |result| are ok. Else, stops the flow + // and returns false. + template <typename T> + bool CheckResultAndStopOnError( + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<T>& result, + const char* file, + int line) { + ClientStatus status = + CheckJavaScriptResult(reply_status, result.get(), file, line); + if (!status.ok()) { + RunCallback(status, (result != nullptr ? result->Serialize() : nullptr)); + return false; + } + return true; + } + + Delegate* const delegate_; + std::unique_ptr<DevtoolsClient> devtools_client_; + int isolated_world_context_id_ = -1; + + // Only set during a flow. + std::unique_ptr<std::string> js_flow_; + base::OnceCallback<void(const ClientStatus&, std::unique_ptr<base::Value>)> + callback_; + + base::WeakPtrFactory<JsFlowExecutorImpl> weak_ptr_factory_{this}; +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_JS_FLOW_EXECUTOR_IMPL_H_
diff --git a/components/autofill_assistant/browser/js_flow_executor_unittest.cc b/components/autofill_assistant/browser/js_flow_executor_impl_unittest.cc similarity index 89% rename from components/autofill_assistant/browser/js_flow_executor_unittest.cc rename to components/autofill_assistant/browser/js_flow_executor_impl_unittest.cc index 6760df259..74c4a53 100644 --- a/components/autofill_assistant/browser/js_flow_executor_unittest.cc +++ b/components/autofill_assistant/browser/js_flow_executor_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/autofill_assistant/browser/js_flow_executor.h" +#include "components/autofill_assistant/browser/js_flow_executor_impl.h" #include "base/callback.h" #include "base/json/json_reader.h" #include "base/strings/strcat.h" @@ -46,10 +46,10 @@ std::move(*base::JSONReader::Read(json))); } -class MockJsFlowExecutorDelegate : public JsFlowExecutor::Delegate { +class MockJsFlowExecutorImplDelegate : public JsFlowExecutorImpl::Delegate { public: - MockJsFlowExecutorDelegate() = default; - ~MockJsFlowExecutorDelegate() override = default; + MockJsFlowExecutorImplDelegate() = default; + ~MockJsFlowExecutorImplDelegate() override = default; MOCK_METHOD( void, @@ -61,9 +61,9 @@ (override)); }; -class JsFlowExecutorTest : public content::ContentBrowserTest { +class JsFlowExecutorImplTest : public content::ContentBrowserTest { public: - JsFlowExecutorTest() {} + JsFlowExecutorImplTest() {} void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch("site-per-process"); @@ -92,8 +92,8 @@ shell(), http_server_->GetURL("/autofill_assistant_target_website.html"))); - flow_executor_ = std::make_unique<JsFlowExecutor>(shell()->web_contents(), - &mock_delegate_); + flow_executor_ = std::make_unique<JsFlowExecutorImpl>( + shell()->web_contents(), &mock_delegate_); } // Overload, ignore result value, just return the client status. @@ -107,7 +107,7 @@ ClientStatus status; base::RunLoop run_loop; flow_executor_->Start( - js_flow, base::BindOnce(&JsFlowExecutorTest::OnFlowFinished, + js_flow, base::BindOnce(&JsFlowExecutorImplTest::OnFlowFinished, base::Unretained(this), run_loop.QuitClosure(), &status, std::ref(result_value))); run_loop.Run(); @@ -125,23 +125,23 @@ } protected: - NiceMock<MockJsFlowExecutorDelegate> mock_delegate_; - std::unique_ptr<JsFlowExecutor> flow_executor_; + NiceMock<MockJsFlowExecutorImplDelegate> mock_delegate_; + std::unique_ptr<JsFlowExecutorImpl> flow_executor_; std::unique_ptr<net::EmbeddedTestServer> http_server_; std::unique_ptr<net::EmbeddedTestServer> http_server_iframe_; }; -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, SmokeTest) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, SmokeTest) { EXPECT_THAT(RunTest(std::string()), Property(&ClientStatus::proto_status, ACTION_APPLIED)); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, InvalidJs) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, InvalidJs) { EXPECT_THAT(RunTest("Not valid Javascript"), Property(&ClientStatus::proto_status, UNEXPECTED_JS_ERROR)); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, RunNativeActionWithReturnValue) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, RunNativeActionWithReturnValue) { std::unique_ptr<base::Value> native_return_value = std::make_unique<base::Value>(std::move(*base::JSONReader::Read( R"( @@ -200,7 +200,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, RunMultipleNativeActions) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, RunMultipleNativeActions) { EXPECT_CALL(mock_delegate_, RunNativeAction) .WillOnce([&](auto value, auto callback) { EXPECT_EQ(*value, *UniqueValueFromJson(R"( @@ -239,7 +239,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ReturnInteger) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ReturnInteger) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest("return 12345;", result); EXPECT_EQ(status.proto_status(), ACTION_APPLIED); @@ -254,7 +254,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ReturnString) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ReturnString) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest("return 'Hello world!';", result); EXPECT_EQ(status.proto_status(), ACTION_APPLIED); @@ -268,7 +268,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ReturnDictionary) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ReturnDictionary) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest( R"( @@ -306,7 +306,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ReturnNothing) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ReturnNothing) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest("", result); EXPECT_EQ(status.proto_status(), ACTION_APPLIED); @@ -319,7 +319,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ReturnNull) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ReturnNull) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest("return null;", result); EXPECT_EQ(status.proto_status(), ACTION_APPLIED); @@ -334,7 +334,7 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, ExceptionReporting) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, ExceptionReporting) { std::unique_ptr<base::Value> result; ClientStatus status = RunTest("throw new Error('Hello world!');", result); EXPECT_EQ(status.proto_status(), UNEXPECTED_JS_ERROR); @@ -368,7 +368,7 @@ EXPECT_THAT(exceptionDetails->ExtractKey("exception"), Ne(absl::nullopt)); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, RunMultipleConsecutiveFlows) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, RunMultipleConsecutiveFlows) { for (int i = 0; i < 10; ++i) { std::unique_ptr<base::Value> result; ClientStatus status = @@ -378,7 +378,7 @@ } } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, UnserializableRunNativeActionArgument) { std::unique_ptr<base::Value> result; EXPECT_CALL(mock_delegate_, RunNativeAction).Times(0); @@ -395,7 +395,7 @@ EXPECT_TRUE(status.details().has_unexpected_error_info()); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, StartWhileAlreadyRunningFails) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, StartWhileAlreadyRunningFails) { EXPECT_CALL(mock_delegate_, RunNativeAction) .WillOnce(WithArg<1>([&](auto callback) { // Starting a second flow while the first one is running should fail. @@ -424,7 +424,8 @@ )")); } -IN_PROC_BROWSER_TEST_F(JsFlowExecutorTest, EnvironmentIsPreservedBetweenRuns) { +IN_PROC_BROWSER_TEST_F(JsFlowExecutorImplTest, + EnvironmentIsPreservedBetweenRuns) { EXPECT_EQ(RunTest("globalFlowState.i = 5;").proto_status(), ACTION_APPLIED); std::unique_ptr<base::Value> result;
diff --git a/components/autofill_assistant/browser/state.h b/components/autofill_assistant/browser/state.h index eaff567..d02b5ae3 100644 --- a/components/autofill_assistant/browser/state.h +++ b/components/autofill_assistant/browser/state.h
@@ -32,8 +32,10 @@ // Autofill assistant is keeping track of script availability. // - // In this mode, no UI is shown and scripts are not autostarted. User - // actions might be available. + // UI will only be shown if the previous state was RUNNING and if the script + // finished with tell + stop. + // + // In this mode, scripts are not autostarted. User actions might be available. // // Note that it is possible to go from TRACKING to STARTING to trigger // whatever autostartable scripts is defined for a page.
diff --git a/components/autofill_assistant/browser/ui_delegate.h b/components/autofill_assistant/browser/ui_delegate.h index cba3896c..d8c28e1 100644 --- a/components/autofill_assistant/browser/ui_delegate.h +++ b/components/autofill_assistant/browser/ui_delegate.h
@@ -276,6 +276,9 @@ // bottom sheet. virtual void OnInputTextFocusChanged(bool is_text_focused) = 0; + // Returns true if the controller is in a state where UI is necessary. + virtual bool NeedsUI() const = 0; + protected: UiDelegate() = default; };
diff --git a/components/browser_ui/modaldialog/android/java/res/layout/modal_dialog_title.xml b/components/browser_ui/modaldialog/android/java/res/layout/modal_dialog_title.xml index 5d22b53..1e56df4c 100644 --- a/components/browser_ui/modaldialog/android/java/res/layout/modal_dialog_title.xml +++ b/components/browser_ui/modaldialog/android/java/res/layout/modal_dialog_title.xml
@@ -20,5 +20,6 @@ android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="match_parent" + android:ellipsize="end" android:textAppearance="@style/TextAppearance.AlertDialogTitleStyle" /> -</LinearLayout> \ No newline at end of file +</LinearLayout>
diff --git a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java index a4fa245..8a7ba262 100644 --- a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java +++ b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java
@@ -146,6 +146,11 @@ updateContentVisibility(); } + /** @param maxLines The maximum number of title lines. */ + public void setTitleMaxLines(int maxLines) { + mTitleView.setMaxLines(maxLines); + } + /** * @param drawable The icon drawable on the title. */
diff --git a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewBinder.java b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewBinder.java index 7e8acf2..902dd3f5 100644 --- a/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewBinder.java +++ b/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewBinder.java
@@ -22,6 +22,8 @@ public void bind(PropertyModel model, ModalDialogView view, PropertyKey propertyKey) { if (ModalDialogProperties.TITLE == propertyKey) { view.setTitle(model.get(ModalDialogProperties.TITLE)); + } else if (ModalDialogProperties.TITLE_MAX_LINES == propertyKey) { + view.setTitleMaxLines(model.get(ModalDialogProperties.TITLE_MAX_LINES)); } else if (ModalDialogProperties.TITLE_ICON == propertyKey) { view.setTitleIcon(model.get(ModalDialogProperties.TITLE_ICON)); } else if (ModalDialogProperties.MESSAGE == propertyKey) {
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index a8dcf9e..9d34b879 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -24,10 +24,12 @@ android_resources("java_resources") { sources = [ "java/res/color/default_icon_color_accent1_tint_list.xml", + "java/res/color/default_icon_color_dark_tint_list.xml", "java/res/color/default_icon_color_light_tint_list.xml", "java/res/color/default_icon_color_secondary_light_tint_list.xml", "java/res/color/default_icon_color_secondary_tint_list.xml", "java/res/color/default_icon_color_tint_list.xml", + "java/res/color/default_icon_color_white_tint_list.xml", "java/res/color/default_text_color_accent1_tint_list.xml", "java/res/color/default_text_color_disabled_list.xml", "java/res/color/default_text_color_hint_list.xml",
diff --git a/chrome/browser/ui/android/theme/java/res/color/toolbar_icon_tint_dark.xml b/components/browser_ui/styles/android/java/res/color/default_icon_color_dark_tint_list.xml similarity index 100% rename from chrome/browser/ui/android/theme/java/res/color/toolbar_icon_tint_dark.xml rename to components/browser_ui/styles/android/java/res/color/default_icon_color_dark_tint_list.xml
diff --git a/components/browser_ui/styles/android/java/res/color/default_icon_color_white_tint_list.xml b/components/browser_ui/styles/android/java/res/color/default_icon_color_white_tint_list.xml new file mode 100644 index 0000000..bcb69a2 --- /dev/null +++ b/components/browser_ui/styles/android/java/res/color/default_icon_color_white_tint_list.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:alpha="@dimen/default_disabled_alpha" + android:state_enabled="false" android:color="@android:color/white" /> + <item android:color="@android:color/white"/> +</selector>
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/OWNERS b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/OWNERS new file mode 100644 index 0000000..bfe9f588 --- /dev/null +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/OWNERS
@@ -0,0 +1 @@ +per-file ContextMenu*=file://chrome/android/java/src/org/chromium/chrome/browser/contextmenu/OWNERS
diff --git a/components/browser_watcher/activity_report_extractor_unittest.cc b/components/browser_watcher/activity_report_extractor_unittest.cc index b7998f62..f37365652 100644 --- a/components/browser_watcher/activity_report_extractor_unittest.cc +++ b/components/browser_watcher/activity_report_extractor_unittest.cc
@@ -15,6 +15,7 @@ #include "base/files/memory_mapped_file.h" #include "base/files/scoped_temp_dir.h" #include "base/metrics/persistent_memory_allocator.h" +#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/cast_streaming/browser/BUILD.gn b/components/cast_streaming/browser/BUILD.gn index 27f18a2..f8512cdb 100644 --- a/components/cast_streaming/browser/BUILD.gn +++ b/components/cast_streaming/browser/BUILD.gn
@@ -11,9 +11,7 @@ source_set("core") { deps = [ "//base", - "//chromecast/bindings/shared:proto_serializer", "//media", - "//third_party/cast_core/public/src/proto/bindings:cast_channel_proto", ] public_deps = [ "//components/cast/message_port",
diff --git a/components/cast_streaming/browser/DEPS b/components/cast_streaming/browser/DEPS index 3ea1f73..0376433a 100644 --- a/components/cast_streaming/browser/DEPS +++ b/components/cast_streaming/browser/DEPS
@@ -1,5 +1,4 @@ include_rules = [ - "+chromecast/bindings/shared", "+components/cast/message_port", "+components/openscreen_platform", "+media/base", @@ -8,5 +7,4 @@ "+mojo/public", "+net/base", "+third_party/openscreen/src", - "+third_party/cast_core/public/src", ]
diff --git a/components/cast_streaming/browser/message_serialization.cc b/components/cast_streaming/browser/message_serialization.cc index aa7e5669..10a7095 100644 --- a/components/cast_streaming/browser/message_serialization.cc +++ b/components/cast_streaming/browser/message_serialization.cc
@@ -4,12 +4,10 @@ #include "components/cast_streaming/browser/message_serialization.h" -#include "base/base64.h" -#include "chromecast/bindings/shared/proto_serializer.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/values.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/cast_core/public/src/proto/bindings/cast_channel.pb.h" - -using CastChannelMessage = cast::bindings::CastChannelMessage; namespace cast_streaming { @@ -19,6 +17,8 @@ const char kInjectNamespace[] = "urn:x-cast:com.google.cast.inject"; const char kMediaNamespace[] = "urn:x-cast:com.google.cast.media"; +const char kKeySenderId[] = "senderId"; +const char kKeyNamespace[] = "namespace"; const char kKeyData[] = "data"; const char kKeyType[] = "type"; const char kKeyRequestId[] = "requestId"; @@ -55,20 +55,29 @@ std::string* sender_id, std::string* message_namespace, std::string* message) { - absl::optional<CastChannelMessage> proto = - chromecast::bindings::ProtoSerializer<CastChannelMessage>::Deserialize( - buffer); - if (!proto) { + absl::optional<base::Value> converted_value = base::JSONReader::Read(buffer); + if (!converted_value) return false; - } - if (proto->payload_case() != CastChannelMessage::PayloadCase::kPayloadUtf8) { + if (!converted_value->is_dict()) return false; - } - *sender_id = proto->sender_id(); - *message_namespace = proto->ns(); - *message = proto->payload_utf8(); + const std::string* sender_id_value = + converted_value->FindStringPath(kKeySenderId); + if (!sender_id_value) + return false; + *sender_id = *sender_id_value; + + const std::string* message_namespace_value = + converted_value->FindStringPath(kKeyNamespace); + if (!message_namespace_value) + return false; + *message_namespace = *message_namespace_value; + + const std::string* message_value = converted_value->FindStringPath(kKeyData); + if (!message_value) + return false; + *message = *message_value; return true; } @@ -76,13 +85,14 @@ std::string SerializeCastMessage(const std::string& sender_id, const std::string& message_namespace, const std::string& message) { - CastChannelMessage proto; - proto.set_sender_id(sender_id); - proto.set_ns(message_namespace); - proto.set_payload_utf8(message); + base::Value value(base::Value::Type::DICTIONARY); + value.SetStringKey(kKeyNamespace, message_namespace); + value.SetStringKey(kKeySenderId, sender_id); + value.SetStringKey(kKeyData, message); - return chromecast::bindings::ProtoSerializer<CastChannelMessage>::Serialize( - proto); + std::string json_message; + CHECK(base::JSONWriter::Write(value, &json_message)); + return json_message; } } // namespace cast_streaming
diff --git a/components/cast_streaming/browser/message_serialization.h b/components/cast_streaming/browser/message_serialization.h index 2217787c..1f2673c 100644 --- a/components/cast_streaming/browser/message_serialization.h +++ b/components/cast_streaming/browser/message_serialization.h
@@ -19,6 +19,8 @@ extern const char kInjectNamespace[]; extern const char kMediaNamespace[]; +extern const char kKeySenderId[]; +extern const char kKeyNamespace[]; extern const char kKeyData[]; extern const char kKeyType[]; extern const char kKeyRequestId[];
diff --git a/components/cast_streaming/public/BUILD.gn b/components/cast_streaming/public/BUILD.gn index 5affc2d..95602d8c 100644 --- a/components/cast_streaming/public/BUILD.gn +++ b/components/cast_streaming/public/BUILD.gn
@@ -10,8 +10,6 @@ sources = [ "cast_streaming_url.cc", "cast_streaming_url.h", - "constants.cc", - "constants.h", ] }
diff --git a/components/cast_streaming/public/constants.cc b/components/cast_streaming/public/constants.cc deleted file mode 100644 index b96ba0c..0000000 --- a/components/cast_streaming/public/constants.cc +++ /dev/null
@@ -1,12 +0,0 @@ -// 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/cast_streaming/public/constants.h" - -namespace cast_streaming { - -const char kCastTransportBindingName[] = - "cast.__platform__.proto_cast_transport"; - -} // namespace cast_streaming
diff --git a/components/cast_streaming/public/constants.h b/components/cast_streaming/public/constants.h deleted file mode 100644 index 29e4661d..0000000 --- a/components/cast_streaming/public/constants.h +++ /dev/null
@@ -1,16 +0,0 @@ -// 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_CAST_STREAMING_PUBLIC_CONSTANTS_H_ -#define COMPONENTS_CAST_STREAMING_PUBLIC_CONSTANTS_H_ - -namespace cast_streaming { - -// Name of the binding with which |ReceiverSession| communicates. Used for -// setting up the MessagePort. -extern const char kCastTransportBindingName[]; - -} // namespace cast_streaming - -#endif // COMPONENTS_CAST_STREAMING_PUBLIC_CONSTANTS_H_
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 54f867e..8b87a8a 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "4.78", - "log_list_timestamp": "2022-01-03T01:34:43Z", + "version": "4.81", + "log_list_timestamp": "2022-01-06T01:34:23Z", "operators": [ { "name": "Google",
diff --git a/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.cc b/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.cc index 17ebcd2..6556544 100644 --- a/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.cc +++ b/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.cc
@@ -18,12 +18,10 @@ #include "components/component_updater/component_installer.h" namespace component_updater { -const base::FilePath::CharType kClientModelBinaryPbFileName[] = - FILE_PATH_LITERAL("client_model.pb"); -const base::FilePath::CharType kVisualTfLiteModelFileName[] = - FILE_PATH_LITERAL("visual_model.tflite"); namespace { +const char kClientSidePhishingManifestName[] = "Client Side Phishing Detection"; + // The SHA256 of the SubjectPublicKeyInfo used to sign the extension. // The extension id is: imefjhfbkmcmebodilednhmaccmincoa const uint8_t kClientSidePhishingPublicKeySHA256[32] = { @@ -31,10 +29,13 @@ 0xc0, 0x22, 0xc8, 0xd2, 0xe0, 0xe3, 0xe2, 0x33, 0x88, 0x1f, 0x09, 0x6d, 0xde, 0x65, 0x6a, 0x83, 0x32, 0x71, 0x52, 0x6e, 0x77}; -const char kClientSidePhishingManifestName[] = "Client Side Phishing Detection"; - } // namespace +const base::FilePath::CharType kClientModelBinaryPbFileName[] = + FILE_PATH_LITERAL("client_model.pb"); +const base::FilePath::CharType kVisualTfLiteModelFileName[] = + FILE_PATH_LITERAL("visual_model.tflite"); + ClientSidePhishingComponentInstallerPolicy:: ClientSidePhishingComponentInstallerPolicy( const ReadFilesCallback& read_files_callback, @@ -46,6 +47,14 @@ ClientSidePhishingComponentInstallerPolicy:: ~ClientSidePhishingComponentInstallerPolicy() = default; +// static +void ClientSidePhishingComponentInstallerPolicy::GetPublicHash( + std::vector<uint8_t>* hash) { + hash->assign(kClientSidePhishingPublicKeySHA256, + kClientSidePhishingPublicKeySHA256 + + base::size(kClientSidePhishingPublicKeySHA256)); +} + bool ClientSidePhishingComponentInstallerPolicy:: SupportsGroupPolicyEnabledComponentUpdates() const { return true; @@ -89,9 +98,7 @@ void ClientSidePhishingComponentInstallerPolicy::GetHash( std::vector<uint8_t>* hash) const { - hash->assign(kClientSidePhishingPublicKeySHA256, - kClientSidePhishingPublicKeySHA256 + - base::size(kClientSidePhishingPublicKeySHA256)); + GetPublicHash(hash); } std::string ClientSidePhishingComponentInstallerPolicy::GetName() const {
diff --git a/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h b/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h index bf95047a..825c8ea1 100644 --- a/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h +++ b/components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h
@@ -45,6 +45,8 @@ const ClientSidePhishingComponentInstallerPolicy&) = delete; ~ClientSidePhishingComponentInstallerPolicy() override; + static void GetPublicHash(std::vector<uint8_t>* hash); + private: // The following methods override ComponentInstallerPolicy. bool SupportsGroupPolicyEnabledComponentUpdates() const override;
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn index 3485b9f..a7d77bd 100644 --- a/components/crash/android/BUILD.gn +++ b/components/crash/android/BUILD.gn
@@ -6,6 +6,7 @@ _jni_sources = [ "java/src/org/chromium/components/crash/CrashKeys.java", + "java/src/org/chromium/components/crash/PureJavaExceptionHandler.java", "java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java", "java/src/org/chromium/components/crash/browser/PackagePaths.java", "java/src/org/chromium/components/crash/browser/ProcessExitReasonFromSystem.java", @@ -53,6 +54,8 @@ sources = [ "crash_keys_android.cc", "crash_keys_android.h", + "pure_java_exception_handler.cc", + "pure_java_exception_handler.h", ] deps = [ ":jni_headers",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java similarity index 69% rename from chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java rename to components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java index 882f584..2aa7eb98 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java +++ b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java
@@ -2,13 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.crash; +package org.chromium.components.crash; -import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.MainDex; -import org.chromium.chrome.browser.base.SplitCompatUtils; -import org.chromium.components.crash.CrashKeys; /** * This UncaughtExceptionHandler will upload the stacktrace when there is an uncaught exception. @@ -21,14 +18,22 @@ private final Thread.UncaughtExceptionHandler mParent; private boolean mHandlingException; private static boolean sIsDisabled; + private JavaExceptionReporterFactory mReporterFactory; /** Interface to allow uploading reports. */ public interface JavaExceptionReporter { void createAndUploadReport(Throwable e); } - private PureJavaExceptionHandler(Thread.UncaughtExceptionHandler parent) { + /** A factory interface to allow creating custom reporters. */ + public interface JavaExceptionReporterFactory { + JavaExceptionReporter createJavaExceptionReporter(); + } + + private PureJavaExceptionHandler( + Thread.UncaughtExceptionHandler parent, JavaExceptionReporterFactory reporterFactory) { mParent = parent; + mReporterFactory = reporterFactory; } @Override @@ -42,10 +47,10 @@ } } - public static void installHandler() { + public static void installHandler(JavaExceptionReporterFactory reporterFactory) { if (!sIsDisabled) { - Thread.setDefaultUncaughtExceptionHandler( - new PureJavaExceptionHandler(Thread.getDefaultUncaughtExceptionHandler())); + Thread.setDefaultUncaughtExceptionHandler(new PureJavaExceptionHandler( + Thread.getDefaultUncaughtExceptionHandler(), reporterFactory)); } } @@ -60,10 +65,7 @@ } private void reportJavaException(Throwable e) { - // PureJavaExceptionReporter may be in the chrome module, so load by reflection from there. - JavaExceptionReporter reporter = (JavaExceptionReporter) SplitCompatUtils.newInstance( - SplitCompatUtils.createChromeContext(ContextUtils.getApplicationContext()), - "org.chromium.chrome.browser.crash.PureJavaExceptionReporter"); + JavaExceptionReporter reporter = mReporterFactory.createJavaExceptionReporter(); reporter.createAndUploadReport(e); } }
diff --git a/chrome/browser/android/crash/pure_java_exception_handler.cc b/components/crash/android/pure_java_exception_handler.cc similarity index 67% rename from chrome/browser/android/crash/pure_java_exception_handler.cc rename to components/crash/android/pure_java_exception_handler.cc index f75c048e..9a5005bae 100644 --- a/chrome/browser/android/crash/pure_java_exception_handler.cc +++ b/components/crash/android/pure_java_exception_handler.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/crash/pure_java_exception_handler.h" +#include "components/crash/android/pure_java_exception_handler.h" -#include "chrome/android/chrome_jni_headers/PureJavaExceptionHandler_jni.h" +#include "components/crash/android/jni_headers/PureJavaExceptionHandler_jni.h" void UninstallPureJavaExceptionHandler() { Java_PureJavaExceptionHandler_uninstallHandler(
diff --git a/components/crash/android/pure_java_exception_handler.h b/components/crash/android/pure_java_exception_handler.h new file mode 100644 index 0000000..c66fa7d --- /dev/null +++ b/components/crash/android/pure_java_exception_handler.h
@@ -0,0 +1,10 @@ +// Copyright 2017 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_CRASH_ANDROID_PURE_JAVA_EXCEPTION_HANDLER_H_ +#define COMPONENTS_CRASH_ANDROID_PURE_JAVA_EXCEPTION_HANDLER_H_ + +void UninstallPureJavaExceptionHandler(); + +#endif // COMPONENTS_CRASH_ANDROID_PURE_JAVA_EXCEPTION_HANDLER_H_
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index fdf4470..a60928d5 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -1027,8 +1027,8 @@ lint_suppressions_file = "lint-suppressions.xml" lint_baseline_file = "lint-baseline.xml" - # Still needs to support Jelly Bean. See crbug.com/922656. - lint_min_sdk_version = 16 + # Still needs to support KitKat. See crbug.com/1042122. + lint_min_sdk_version = 19 apk_name = "CronetTestInstrumentation" android_manifest = "test/javatests/AndroidManifest.xml"
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java index 2d38e082..e1c2fefb 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java
@@ -351,15 +351,9 @@ @Override protected void initializeStart(long totalBytes) { - if (totalBytes > 0 && totalBytes <= Integer.MAX_VALUE) { - mUrlConnection.setFixedLengthStreamingMode((int) totalBytes); - } else if (totalBytes > Integer.MAX_VALUE - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if (totalBytes > 0) { mUrlConnection.setFixedLengthStreamingMode(totalBytes); } else { - // Even if we know the length, but we're running pre-kitkat and it's larger - // than an int can hold, we have to use chunked - otherwise we'll end up - // buffering the whole response in memory. mUrlConnection.setChunkedStreamingMode(DEFAULT_CHUNK_LENGTH); } }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java index 8251bcf43..3ecf65c5 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -2462,8 +2462,7 @@ */ public void testManyRequests() throws Exception { String url = NativeTestServer.getMultiRedirectURL(); - // Jelly Bean has a 2000 limit on global references, crbug.com/922656. - final int numRequests = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? 2000 : 1500; + final int numRequests = 2000; TestUrlRequestCallback callbacks[] = new TestUrlRequestCallback[numRequests]; UrlRequest requests[] = new UrlRequest[numRequests]; for (int i = 0; i < numRequests; i++) {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLConnectionTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLConnectionTest.java index 24db14d..5580f3c5 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLConnectionTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLConnectionTest.java
@@ -242,20 +242,17 @@ (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - String dataString = "some very important data"; - byte[] data = dataString.getBytes(); - Class<?> c = connection.getClass(); - Method method = c.getMethod("setFixedLengthStreamingMode", - new Class[] {long.class}); - method.invoke(connection, (long) data.length); - OutputStream out = connection.getOutputStream(); - out.write(data); - assertEquals(200, connection.getResponseCode()); - assertEquals("OK", connection.getResponseMessage()); - assertEquals(dataString, TestUtil.getResponseAsString(connection)); - connection.disconnect(); - } + String dataString = "some very important data"; + byte[] data = dataString.getBytes(); + Class<?> c = connection.getClass(); + Method method = c.getMethod("setFixedLengthStreamingMode", new Class[] {long.class}); + method.invoke(connection, (long) data.length); + OutputStream out = connection.getOutputStream(); + out.write(data); + assertEquals(200, connection.getResponseCode()); + assertEquals("OK", connection.getResponseMessage()); + assertEquals(dataString, TestUtil.getResponseAsString(connection)); + connection.disconnect(); } @Test
diff --git a/components/cronet/tools/cr_cronet.py b/components/cronet/tools/cr_cronet.py index 99485859..d90c8fa 100755 --- a/components/cronet/tools/cr_cronet.py +++ b/components/cronet/tools/cr_cronet.py
@@ -135,7 +135,7 @@ def get_android_gn_args(is_release): return (get_mobile_gn_args('android', is_release) + # Keep in sync with //tools/mb/mb_config.pyl cronet_android config. - 'default_min_sdk_version = 16 ' + + 'default_min_sdk_version = 19 ' + 'use_errorprone_java_compiler=true ' + 'enable_reporting=true ' + 'use_hashed_jni_names=true ')
diff --git a/components/desks_storage/core/desk_model.h b/components/desks_storage/core/desk_model.h index 2fdef80..30880fa 100644 --- a/components/desks_storage/core/desk_model.h +++ b/components/desks_storage/core/desk_model.h
@@ -49,11 +49,15 @@ }; // Status codes for adding or updating a desk template. + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. enum class AddOrUpdateEntryStatus { - kOk, - kFailure, - kInvalidArgument, - kHitMaximumLimit, + kOk = 0, + kFailure = 1, + kInvalidArgument = 2, + kHitMaximumLimit = 3, + kEntryTooLarge = 4, + kMaxValue = kEntryTooLarge, }; // Status codes for deleting desk templates.
diff --git a/components/desks_storage/core/desk_sync_bridge.cc b/components/desks_storage/core/desk_sync_bridge.cc index a1794fd..9dc2894 100644 --- a/components/desks_storage/core/desk_sync_bridge.cc +++ b/components/desks_storage/core/desk_sync_bridge.cc
@@ -56,6 +56,13 @@ // The maximum number of templates the local storage can hold. constexpr std::size_t kMaxTemplateCount = 6u; +// The maximum number of bytes a template can be. +// Sync server silently ignores large items. The client-side +// needs to check item size to avoid sending large items. +// This limit follows precedent set by the chrome extension API: +// chrome.storage.sync.QUOTA_BYTES_PER_ITEM. +constexpr std::size_t kMaxTemplateSize = 8192u; + // Allocate a EntityData and copies |specifics| into it. std::unique_ptr<syncer::EntityData> CopyToEntityData( const sync_pb::WorkspaceDeskSpecifics& specifics) { @@ -702,9 +709,16 @@ std::unique_ptr<ModelTypeStore::WriteBatch> batch = store_->CreateWriteBatch(); - // Add/update this entry to the store and model. - auto entity_data = CopyToEntityData(ToSyncProto(entry.get())); + // Check the new entry size and ensure it is below the size limit. + auto sync_proto = ToSyncProto(entry.get()); + if (sync_proto.ByteSizeLong() > kMaxTemplateSize) { + std::move(callback).Run(AddOrUpdateEntryStatus::kEntryTooLarge); + return; + } + + // Add/update this entry to the store and model. + auto entity_data = CopyToEntityData(sync_proto); change_processor()->Put(uuid.AsLowercaseString(), std::move(entity_data), batch->GetMetadataChangeList());
diff --git a/components/desks_storage/core/desk_sync_bridge_unittest.cc b/components/desks_storage/core/desk_sync_bridge_unittest.cc index 838e825..cc2eaf1 100644 --- a/components/desks_storage/core/desk_sync_bridge_unittest.cc +++ b/components/desks_storage/core/desk_sync_bridge_unittest.cc
@@ -109,16 +109,17 @@ "2\",\"title\":\"Example2\"}],\"active_tab_index\":1,\"window_id\":0," "\"display_id\":\"100\",\"pre_minimized_window_state\":\"NORMAL\"}]}}]"; -void FillExampleBrowserAppWindow(WorkspaceDeskSpecifics_App* app) { +void FillExampleBrowserAppWindow(WorkspaceDeskSpecifics_App* app, + int number_of_tabs = 2) { BrowserAppWindow* app_window = app->mutable_app()->mutable_browser_app_window(); - BrowserAppTab* tab1 = app_window->add_tabs(); - tab1->set_url(base::StringPrintf(kTestUrlFormat, 1)); - BrowserAppTab* tab2 = app_window->add_tabs(); - tab2->set_url(base::StringPrintf(kTestUrlFormat, 2)); + for (int i = 0; i < number_of_tabs; ++i) { + BrowserAppTab* tab = app_window->add_tabs(); + tab->set_url(base::StringPrintf(kTestUrlFormat, i)); + } - app_window->set_active_tab_index(1); + app_window->set_active_tab_index(number_of_tabs - 1); WindowBound* window_bound = app->mutable_window_bound(); window_bound->set_left(110); @@ -169,7 +170,8 @@ WorkspaceDeskSpecifics ExampleWorkspaceDeskSpecifics( const std::string uuid, const std::string template_name, - base::Time created_time = base::Time::Now()) { + base::Time created_time = base::Time::Now(), + int number_of_tabs = 2) { WorkspaceDeskSpecifics specifics; specifics.set_uuid(uuid); specifics.set_name(template_name); @@ -180,7 +182,7 @@ .ToDeltaSinceWindowsEpoch() .InMicroseconds()); Desk* desk = specifics.mutable_desk(); - FillExampleBrowserAppWindow(desk->add_apps()); + FillExampleBrowserAppWindow(desk->add_apps(), number_of_tabs); FillExampleChromeAppWindow(desk->add_apps()); FillExampleProgressiveWebAppWindow(desk->add_apps()); return specifics; @@ -619,6 +621,31 @@ specifics2.SerializeAsString()); } +TEST_F(DeskSyncBridgeTest, AddEntryShouldFailWhenEntryIsTooLarge) { + InitializeBridge(); + + EXPECT_CALL(*mock_observer(), EntriesAddedOrUpdatedRemotely(_)).Times(0); + EXPECT_CALL(*mock_observer(), EntriesRemovedRemotely(_)).Times(0); + + EXPECT_EQ(0ul, bridge()->GetAllEntryUuids().size()); + + // Create a large entry with 500 tabs. This entry should be too large for + // Sync. + constexpr int number_of_tabs = 500; + auto specifics = ExampleWorkspaceDeskSpecifics( + kTestUuid1.AsLowercaseString(), "template 1", AdvanceAndGetTime(), + number_of_tabs); + + base::RunLoop loop; + bridge()->AddOrUpdateEntry( + DeskSyncBridge::FromSyncProto(specifics), + base::BindLambdaForTesting([&](DeskModel::AddOrUpdateEntryStatus status) { + EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kEntryTooLarge); + loop.Quit(); + })); + loop.Run(); +} + TEST_F(DeskSyncBridgeTest, AddEntryShouldSucceedWheSyncIsDisabled) { InitializeBridge(); DisableBridgeSync();
diff --git a/components/embedder_support/android/metrics/memory_metrics_logger.cc b/components/embedder_support/android/metrics/memory_metrics_logger.cc index e5bd196d..a131d813 100644 --- a/components/embedder_support/android/metrics/memory_metrics_logger.cc +++ b/components/embedder_support/android/metrics/memory_metrics_logger.cc
@@ -65,11 +65,11 @@ // renderer process, as it originated from WebView, where there are no // other processes. case memory_instrumentation::mojom::ProcessType::ARC: - FALLTHROUGH; + [[fallthrough]]; case memory_instrumentation::mojom::ProcessType::UTILITY: - FALLTHROUGH; + [[fallthrough]]; case memory_instrumentation::mojom::ProcessType::PLUGIN: - FALLTHROUGH; + [[fallthrough]]; case memory_instrumentation::mojom::ProcessType::OTHER: break; }
diff --git a/components/enterprise/browser/reporting/browser_report_generator.cc b/components/enterprise/browser/reporting/browser_report_generator.cc index 324eb326..6969ec3 100644 --- a/components/enterprise/browser/reporting/browser_report_generator.cc +++ b/components/enterprise/browser/reporting/browser_report_generator.cc
@@ -28,13 +28,16 @@ void BrowserReportGenerator::Generate(ReportType report_type, ReportCallback callback) { auto report = std::make_unique<em::BrowserReport>(); - if (report_type != ReportType::kProfileReport) - GenerateProfileInfo(report.get()); GenerateBasicInfo(report.get(), report_type); - // std::move is required here because the function completes the report - // asynchronously. - delegate_->GeneratePluginsIfNeeded(std::move(callback), std::move(report)); + if (report_type != ReportType::kProfileReport) { + GenerateProfileInfo(report.get()); + // std::move is required here because the function completes the report + // asynchronously. + delegate_->GeneratePluginsIfNeeded(std::move(callback), std::move(report)); + } else { + std::move(callback).Run(std::move(report)); + } } void BrowserReportGenerator::GenerateProfileInfo(em::BrowserReport* report) {
diff --git a/components/exo/drag_drop_operation.cc b/components/exo/drag_drop_operation.cc index 08f7958b..3be11c1 100644 --- a/components/exo/drag_drop_operation.cc +++ b/components/exo/drag_drop_operation.cc
@@ -49,7 +49,7 @@ for (const DndAction action : actions) { switch (action) { case DndAction::kNone: - FALLTHROUGH; + [[fallthrough]]; // We don't support the ask action case DndAction::kAsk: break;
diff --git a/components/exo/pointer.cc b/components/exo/pointer.cc index 47113d3..ef2c16f0 100644 --- a/components/exo/pointer.cc +++ b/components/exo/pointer.cc
@@ -451,7 +451,7 @@ switch (event->type()) { case ui::ET_MOUSE_RELEASED: seat_->AbortPendingDragOperation(); - FALLTHROUGH; + [[fallthrough]]; case ui::ET_MOUSE_PRESSED: { delegate_->OnPointerButton(event->time_stamp(), event->changed_button_flags(),
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index a02c7e1..aa9b336 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -1359,7 +1359,11 @@ gfx::RectF target_space_rect(quad_rect); quad_to_target_transform.TransformRect(&target_space_rect); CHECK(quad_to_target_transform.Preserves2dAxisAlignment()); - if (gfx::IsNearestRectWithinDistance(target_space_rect, 0.001f)) { + // This simple rect representation cannot mathematically express a rotation + // (and currently does not express flip/mirror) hence the + // 'IsPositiveScaleOrTranslation' check. + if (gfx::IsNearestRectWithinDistance(target_space_rect, 0.001f) && + quad_to_target_transform.IsPositiveScaleOrTranslation()) { quad_rect = gfx::ToNearestRect(target_space_rect); // Later in 'SurfaceAggregator' this transform will have 2d translation. quad_to_target_transform = gfx::Transform();
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index f924ed86..774a868 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -30,6 +30,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size_f.h" +#include "ui/gfx/geometry/test/geometry_util.h" #include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_fence_handle.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -858,38 +859,53 @@ false, false, false, false}; static_assert(base::size(kTestRects) == base::size(kExpectedAligned), "Number of elements in each list should be the identical."); + for (int j = 0; j < 2; j++) { + const bool kTestCaseRotation = (j == 1); + for (size_t i = 0; i < base::size(kTestRects); i++) { + auto rect_in_dip = kTestRects[i]; + device_scale_transform.TransformRect(&rect_in_dip); + sub_surface->SetPosition(rect_in_dip.origin()); + child_surface->SetViewport(rect_in_dip.size()); + const int kChildBufferScale = 2; + child_surface->SetBufferScale(kChildBufferScale); + if (kTestCaseRotation) { + child_surface->SetBufferTransform(Transform::ROTATE_90); + } + child_surface->Commit(); + surface->Commit(); + base::RunLoop().RunUntilIdle(); - for (size_t i = 0; i < base::size(kTestRects); i++) { - auto rect_in_dip = kTestRects[i]; - device_scale_transform.TransformRect(&rect_in_dip); - sub_surface->SetPosition(rect_in_dip.origin()); - child_surface->SetViewport(rect_in_dip.size()); - const int kChildBufferScale = 2; - child_surface->SetBufferScale(kChildBufferScale); - child_surface->Commit(); - surface->Commit(); - base::RunLoop().RunUntilIdle(); - - const viz::CompositorFrame& frame = - GetFrameFromSurface(shell_surface.get()); - ASSERT_EQ(1u, frame.render_pass_list.size()); - const auto& quad_list = frame.render_pass_list[0]->quad_list; - ASSERT_EQ(2u, quad_list.size()); - auto transform = - quad_list.front()->shared_quad_state->quad_to_target_transform; - auto rect = gfx::RectF(quad_list.front()->rect); - transform.TransformRect(&rect); - if (kExpectedAligned[i]) { - EXPECT_EQ(gfx::Transform(), transform); - EXPECT_EQ(kTestRects[i], rect); - } else { - EXPECT_EQ(gfx::Rect(1, 1), quad_list.front()->rect); - // Subpixel quads have non identity transforms and due to floating point - // math can only be approximately compared. - EXPECT_NEAR(kTestRects[i].x(), rect.x(), 0.001f); - EXPECT_NEAR(kTestRects[i].y(), rect.y(), 0.001f); - EXPECT_NEAR(kTestRects[i].width(), rect.width(), 0.001f); - EXPECT_NEAR(kTestRects[i].height(), rect.height(), 0.001f); + const viz::CompositorFrame& frame = + GetFrameFromSurface(shell_surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + const auto& quad_list = frame.render_pass_list[0]->quad_list; + ASSERT_EQ(2u, quad_list.size()); + auto transform = + quad_list.front()->shared_quad_state->quad_to_target_transform; + auto rect = gfx::RectF(quad_list.front()->rect); + transform.TransformRect(&rect); + if (kExpectedAligned[i] && !kTestCaseRotation) { + // A transformed rect cannot express a rotation. + // Manipulation of texture coordinates, in addition to a transformed + // rect, can represent flip/mirror but only as two uv points and not as + // a uv rect. + auto* tex_draw_quad = + viz::TextureDrawQuad::MaterialCast(quad_list.front()); + EXPECT_POINTF_NEAR(tex_draw_quad->uv_top_left, gfx::PointF(0, 0), + 0.001f); + EXPECT_POINTF_NEAR(tex_draw_quad->uv_bottom_right, gfx::PointF(1, 1), + 0.001f); + EXPECT_EQ(gfx::Transform(), transform); + EXPECT_EQ(kTestRects[i], rect); + } else { + EXPECT_EQ(gfx::Rect(1, 1), quad_list.front()->rect); + // Subpixel quads have non identity transforms and due to floating point + // math can only be approximately compared. + EXPECT_NEAR(kTestRects[i].x(), rect.x(), 0.001f); + EXPECT_NEAR(kTestRects[i].y(), rect.y(), 0.001f); + EXPECT_NEAR(kTestRects[i].width(), rect.width(), 0.001f); + EXPECT_NEAR(kTestRects[i].height(), rect.height(), 0.001f); + } } } }
diff --git a/components/exo/wayland/weston_test.cc b/components/exo/wayland/weston_test.cc index 3e6ed9f..6b575510 100644 --- a/components/exo/wayland/weston_test.cc +++ b/components/exo/wayland/weston_test.cc
@@ -75,7 +75,10 @@ ui_controls::SendMouseMoveNotifyWhenDone(point_in_root.x(), point_in_root.y(), run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_pointer_position(resource, x, y); + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) + weston_test_send_pointer_position(resource, x, y); } static void weston_test_send_button(struct wl_client* client, @@ -116,7 +119,11 @@ ui_controls::SendMouseEventsNotifyWhenDone(mouse_button, mouse_state, run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_pointer_button(resource, button, state); + + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) + weston_test_send_pointer_button(resource, button, state); } static void weston_test_reset_pointer(struct wl_client* client, @@ -128,8 +135,12 @@ ui_controls::SendMouseEventsNotifyWhenDone( ui_controls::LEFT, ui_controls::UP, run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_pointer_button(resource, BTN_LEFT, - WL_POINTER_BUTTON_STATE_RELEASED); + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) { + weston_test_send_pointer_button(resource, BTN_LEFT, + WL_POINTER_BUTTON_STATE_RELEASED); + } } if (weston_test->middle_button_pressed) { weston_test->middle_button_pressed = false; @@ -137,8 +148,12 @@ ui_controls::SendMouseEventsNotifyWhenDone( ui_controls::MIDDLE, ui_controls::UP, run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_pointer_button(resource, BTN_MIDDLE, - WL_POINTER_BUTTON_STATE_RELEASED); + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) { + weston_test_send_pointer_button(resource, BTN_MIDDLE, + WL_POINTER_BUTTON_STATE_RELEASED); + } } if (weston_test->right_button_pressed) { weston_test->right_button_pressed = false; @@ -146,8 +161,12 @@ ui_controls::SendMouseEventsNotifyWhenDone( ui_controls::RIGHT, ui_controls::UP, run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_pointer_button(resource, BTN_RIGHT, - WL_POINTER_BUTTON_STATE_RELEASED); + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) { + weston_test_send_pointer_button(resource, BTN_RIGHT, + WL_POINTER_BUTTON_STATE_RELEASED); + } } } @@ -221,7 +240,10 @@ weston_test->command_pressed, run_loop.QuitClosure()); run_loop.Run(); - weston_test_send_keyboard_key(resource, key, state); + // TODO(https://crbug.com/1284726): This should not be necessary. + // At this point the resource could have been destroyed. + if (GetUserDataAs<WestonTestState>(resource)) + weston_test_send_keyboard_key(resource, key, state); } static void weston_test_device_release(struct wl_client* client,
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java index 8644faa..babace2 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
@@ -1504,7 +1504,7 @@ * Sanitize intent to be passed to {@link queryIntentActivities()} * ensuring that web pages cannot bypass browser security. */ - private void sanitizeQueryIntentActivitiesIntent(Intent intent) { + public static void sanitizeQueryIntentActivitiesIntent(Intent intent) { intent.setFlags(intent.getFlags() & ALLOWED_INTENT_FLAGS); intent.addCategory(Intent.CATEGORY_BROWSABLE); intent.setComponent(null);
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/RedirectHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/RedirectHandler.java index d16d0f9..8e6f619 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/RedirectHandler.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/RedirectHandler.java
@@ -86,10 +86,9 @@ if (checkIsToChrome) mIsInitialIntentHeadingToChrome = isIntentToChrome(intent); - // A copy of the intent with component cleared to find resolvers. - mInitialIntent = new Intent(intent).setComponent(null); - Intent selector = mInitialIntent.getSelector(); - if (selector != null) selector.setComponent(null); + // A sanitized copy of the initial intent for detecting if resolvers have changed. + mInitialIntent = new Intent(intent); + ExternalNavigationHandler.sanitizeQueryIntentActivitiesIntent(mInitialIntent); } private static boolean isIntentToChrome(Intent intent) {
diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc index 13025e8..6ca56f5 100644 --- a/components/favicon/content/content_favicon_driver.cc +++ b/components/favicon/content/content_favicon_driver.cc
@@ -173,7 +173,7 @@ if (!entry) return; - if (!rfh->IsDocumentOnLoadCompletedInMainFrame()) + if (!rfh->IsDocumentOnLoadCompletedInPrimaryMainFrame()) return; OnUpdateCandidates(rfh->GetLastCommittedURL(), @@ -188,7 +188,7 @@ // occur when loading an initially blank page. content::NavigationEntry* entry = web_contents()->GetController().GetLastCommittedEntry(); - if (!entry || !rfh->IsDocumentOnLoadCompletedInMainFrame()) + if (!entry || !rfh->IsDocumentOnLoadCompletedInPrimaryMainFrame()) return; DocumentManifestData* document_data =
diff --git a/components/favicon/content/content_favicon_driver_unittest.cc b/components/favicon/content/content_favicon_driver_unittest.cc index c0ace2fd..4ea8e835af 100644 --- a/components/favicon/content/content_favicon_driver_unittest.cc +++ b/components/favicon/content/content_favicon_driver_unittest.cc
@@ -145,8 +145,9 @@ favicon_driver->GetManifestURL(web_contents()->GetMainFrame())); } -// Test that no download is initiated when DocumentOnLoadCompletedInMainFrame() -// is not triggered (e.g. user stopped an ongoing page load). +// Test that no download is initiated when +// DocumentOnLoadCompletedInPrimaryMainFrame() is not triggered (e.g. user +// stopped an ongoing page load). TEST_F(ContentFaviconDriverTest, ShouldNotCauseImageDownload) { ContentFaviconDriver* favicon_driver = ContentFaviconDriver::FromWebContents(web_contents());
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index 56cdee7..57f6bd7 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -417,7 +417,7 @@ base::Time(), kMaxCountForKeywordCacheBatch, base::BindOnce(&HistoryClustersService::PopulateClusterKeywordCache, weak_ptr_factory_.GetWeakPtr(), begin_time, - std::make_unique<std::set<std::u16string>>(), + std::make_unique<std::vector<std::u16string>>(), &all_keywords_cache_), &cache_query_task_tracker_); @@ -442,7 +442,7 @@ base::BindOnce(&HistoryClustersService::PopulateClusterKeywordCache, weak_ptr_factory_.GetWeakPtr(), all_keywords_cache_timestamp_, - std::make_unique<std::set<std::u16string>>(), + std::make_unique<std::vector<std::u16string>>(), &short_keyword_cache_), &cache_query_task_tracker_); } @@ -452,17 +452,10 @@ if (query.length() <= 1) return false; - query_parser::QueryNodeVector query_nodes; - query_parser::QueryParser::ParseQueryNodes( - base::UTF8ToUTF16(query), query_parser::MatchingAlgorithm::DEFAULT, - &query_nodes); + auto query_lower = base::i18n::ToLower(base::UTF8ToUTF16(query)); - return query_parser::QueryParser::DoesQueryMatch(all_keywords_cache_, - query_nodes, - /*exact=*/true) || - query_parser::QueryParser::DoesQueryMatch(short_keyword_cache_, - query_nodes, - /*exact=*/true); + return short_keyword_cache_.contains(query_lower) || + all_keywords_cache_.contains(query_lower); } // static @@ -521,8 +514,8 @@ void HistoryClustersService::PopulateClusterKeywordCache( base::Time begin_time, - std::unique_ptr<std::set<std::u16string>> keyword_accumulator, - query_parser::QueryWordVector* cache, + std::unique_ptr<std::vector<std::u16string>> keyword_accumulator, + KeywordSet* cache, QueryClustersResult result) { const size_t max_keyword_phrases = kMaxKeywordPhrases.Get(); @@ -533,8 +526,11 @@ // simple first-pass technique to avoid overtriggering the omnibox action. continue; } - keyword_accumulator->insert(cluster.keywords.begin(), - cluster.keywords.end()); + // Lowercase the keywords for case insensitive matching while adding to the + // accumulator. + for (auto& keyword : cluster.keywords) { + keyword_accumulator->push_back(base::i18n::ToLower(keyword)); + } // Limit the cache size. It's possible for the `cache.size()` to exceed // `max_keyword_phrases` since: @@ -566,19 +562,10 @@ return; } - // TODO(manukh) Even though `keyword_accumulator` is a `std::set`, we still - // often end up with duplicate keywords since different strings in the - // accumulator may contain the same words. We should add a metric to measure - // the keyword cache size and consider preventing duplicate keywords being - // inserted. - - // We've got all the keywords now, time to populate the cache. - cache->clear(); - for (auto& keyword : *keyword_accumulator) { - // Each `keyword` may itself have multiple terms that we need to extract. - query_parser::QueryParser::ExtractQueryWords(base::i18n::ToLower(keyword), - cache); - } + // We've got all the keywords now. Move them all into the flat_set at once + // via the constructor for efficiency (as recommended by the flat_set docs). + // De-duplication is handled by the flat_set itself. + *cache = KeywordSet(*keyword_accumulator); // Record keyword phrase & keyword counts for the appropriate cache. if (cache == &all_keywords_cache_) {
diff --git a/components/history_clusters/core/history_clusters_service.h b/components/history_clusters/core/history_clusters_service.h index 50cd1a29..29063953 100644 --- a/components/history_clusters/core/history_clusters_service.h +++ b/components/history_clusters/core/history_clusters_service.h
@@ -7,11 +7,11 @@ #include <map> #include <memory> -#include <set> #include <string> #include <vector> #include "base/callback.h" +#include "base/containers/flat_set.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -26,7 +26,6 @@ #include "components/history_clusters/core/clustering_backend.h" #include "components/history_clusters/core/history_clusters_types.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/query_parser/query_parser.h" #include "services/network/public/cpp/shared_url_loader_factory.h" class TemplateURLService; @@ -80,6 +79,8 @@ using IncompleteVisitMap = std::map<int64_t, IncompleteVisitContextAnnotations>; + using KeywordSet = base::flat_set<std::u16string>; + // `url_loader_factory` is allowed to be nullptr, like in unit tests. // In that case, HistoryClustersService will never instantiate a clustering // backend that requires it, such as the RemoteClusteringBackend. @@ -175,8 +176,8 @@ // another batch of clusters. Otherwise, will update the keyword cache. void PopulateClusterKeywordCache( base::Time begin_time, - std::unique_ptr<std::set<std::u16string>> keyword_accumulator, - query_parser::QueryWordVector* cache, + std::unique_ptr<std::vector<std::u16string>> keyword_accumulator, + KeywordSet* cache, QueryClustersResult result); // Internally used callback for `QueryClusters()`. @@ -222,7 +223,7 @@ // synchronously as the user types in the omnibox. Also save the timestamp // the cache was generated so we can periodically re-generate. // TODO(tommycli): Make a smarter mechanism for regenerating the cache. - query_parser::QueryWordVector all_keywords_cache_; + KeywordSet all_keywords_cache_; base::Time all_keywords_cache_timestamp_; // Like above, but will represent the clusters newer than @@ -235,7 +236,7 @@ // 2) Exclude keywords since keywords of size-1 clusters are not cached. // TODO(manukh) This is a "band aid" fix to missing keywords for recent // visits. - query_parser::QueryWordVector short_keyword_cache_; + KeywordSet short_keyword_cache_; base::Time short_keyword_cache_timestamp_; base::CancelableTaskTracker cache_query_task_tracker_;
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc index 403a9cc..863d965 100644 --- a/components/history_clusters/core/history_clusters_service_unittest.cc +++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -731,7 +731,7 @@ test_clustering_backend_->GetVisitById(1), test_clustering_backend_->GetVisitById(2), }, - {u"apples", u"oranges", u"z"}, + {u"apples", u"oranges", u"z", u"apples bananas"}, /*should_show_on_prominent_ui_surfaces=*/true)); clusters.push_back( history::Cluster(0, @@ -769,17 +769,23 @@ // Single character exact queries are also rejected. EXPECT_FALSE(history_clusters_service_->DoesQueryMatchAnyCluster("z")); - // Non-exact matches are rejected too. + // Non-exact (substring) matches are rejected too. EXPECT_FALSE(history_clusters_service_->DoesQueryMatchAnyCluster("appl")); // Adding a second non-exact query word also should make it no longer match. EXPECT_FALSE( history_clusters_service_->DoesQueryMatchAnyCluster("apples oran")); - // Multi-word queries with all exact matches should still work. - EXPECT_TRUE( + // A multi-word phrase shouldn't be considered a match against two separate + // keywords: "apples oranges" can't match keywords ["apples", "oranges"]. + EXPECT_FALSE( history_clusters_service_->DoesQueryMatchAnyCluster("apples oranges")); + // But a multi-word phrases can still match against a keyword with multiple + // words: "apples bananas" matches ["apples bananas"]. + EXPECT_TRUE( + history_clusters_service_->DoesQueryMatchAnyCluster("apples bananas")); + // Deleting a history entry should clear the keyword cache. history_service_->DeleteURLs({GURL{"https://google.com/"}}); history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); @@ -916,7 +922,8 @@ // The 1st cluster's phrases should always be cached. EXPECT_TRUE(history_clusters_service_->DoesQueryMatchAnyCluster("one")); - EXPECT_TRUE(history_clusters_service_->DoesQueryMatchAnyCluster("six")); + EXPECT_TRUE( + history_clusters_service_->DoesQueryMatchAnyCluster("four five six")); // Phrases should be cached if we haven't reached 5 phrases even if we've // reached 5 words. EXPECT_TRUE(history_clusters_service_->DoesQueryMatchAnyCluster("seven")); @@ -928,7 +935,7 @@ histogram_tester.ExpectUniqueSample( "History.Clusters.Backend.KeywordCache.AllKeywordPhraseCount", 5, 1); histogram_tester.ExpectUniqueSample( - "History.Clusters.Backend.KeywordCache.AllKeywordsCount", 7, 1); + "History.Clusters.Backend.KeywordCache.AllKeywordsCount", 5, 1); histogram_tester.ExpectTotalCount( "History.Clusters.Backend.KeywordCache.ShortKeywordPhraseCount", 0); histogram_tester.ExpectTotalCount(
diff --git a/components/language/core/common/language_experiments.cc b/components/language/core/common/language_experiments.cc index 42261a28..2da0269 100644 --- a/components/language/core/common/language_experiments.cc +++ b/components/language/core/common/language_experiments.cc
@@ -23,14 +23,8 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kForceAppLanguagePrompt{"ForceAppLanguagePrompt", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kUseFluentLanguageModel { - "UseFluentLanguageModel", -#if defined(OS_IOS) - base::FEATURE_DISABLED_BY_DEFAULT -#else - base::FEATURE_ENABLED_BY_DEFAULT -#endif -}; +const base::Feature kUseFluentLanguageModel{"UseFluentLanguageModel", + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kNotifySyncOnLanguageDetermined{ "NotifySyncOnLanguageDetermined", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDetailedLanguageSettings{
diff --git a/components/leveldb_proto/internal/proto_database_selector.cc b/components/leveldb_proto/internal/proto_database_selector.cc index 1c564b0..0e6f648 100644 --- a/components/leveldb_proto/internal/proto_database_selector.cc +++ b/components/leveldb_proto/internal/proto_database_selector.cc
@@ -473,7 +473,7 @@ break; case InitStatus::NOT_STARTED: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case InitStatus::DONE: std::move(task).Run(); break;
diff --git a/components/lookalikes/core/lookalike_url_util.cc b/components/lookalikes/core/lookalike_url_util.cc index 109a3603..ec5e091 100644 --- a/components/lookalikes/core/lookalike_url_util.cc +++ b/components/lookalikes/core/lookalike_url_util.cc
@@ -92,6 +92,11 @@ return ¶ms; } +// Minimum length of the eTLD+1 without registry needed to show the punycode +// interstitial. IDN whose eTLD+1 without registry is shorter than this are +// still displayed in punycode, but don't show an interstitial. +const size_t kMinimumE2LDLengthToShowPunycodeInterstitial = 2; + bool SkeletonsMatch(const url_formatter::Skeletons& skeletons1, const url_formatter::Skeletons& skeletons2) { DCHECK(!skeletons1.empty()); @@ -1020,6 +1025,16 @@ return true; } +// Returns true if the e2LD of domain is long enough to display a punycode +// interstitial. +bool IsPunycodeInterstitialCandidate(const DomainInfo& domain) { + const url_formatter::IDNConversionResult idn_result = + url_formatter::UnsafeIDNToUnicodeWithDetails( + domain.domain_without_registry); + return idn_result.result.size() >= + kMinimumE2LDLengthToShowPunycodeInterstitial; +} + bool ShouldBlockBySpoofCheckResult(const DomainInfo& navigated_domain) { // Here, only a subset of spoof checks that cause an IDN to fallback to // punycode are configured to show an interstitial. @@ -1030,7 +1045,8 @@ case url_formatter::IDNSpoofChecker::Result::kICUSpoofChecks: // If the eTLD+1 contains only a mix of ASCII + Emoji, allow. - return !IsASCIIAndEmojiOnly(navigated_domain.idn_result.result); + return !IsASCIIAndEmojiOnly(navigated_domain.idn_result.result) && + IsPunycodeInterstitialCandidate(navigated_domain); case url_formatter::IDNSpoofChecker::Result::kDeviationCharacters: // Failures because of deviation characters, especially ß, is common. @@ -1043,7 +1059,7 @@ case url_formatter::IDNSpoofChecker::Result:: kNonAsciiLatinCharMixedWithNonLatin: case url_formatter::IDNSpoofChecker::Result::kDangerousPattern: - return true; + return IsPunycodeInterstitialCandidate(navigated_domain); } }
diff --git a/components/lookalikes/core/lookalike_url_util.h b/components/lookalikes/core/lookalike_url_util.h index 98b71fe..8679a9ad 100644 --- a/components/lookalikes/core/lookalike_url_util.h +++ b/components/lookalikes/core/lookalike_url_util.h
@@ -171,7 +171,8 @@ // which doesn't have a notion of private registries. std::string GetETLDPlusOne(const std::string& hostname); -// Returns true if a lookalike interstitial should be shown. +// Returns true if a lookalike interstitial should be shown for the given +// match type. bool ShouldBlockLookalikeUrlNavigation(LookalikeUrlMatchType match_type); // Returns true if a domain is visually similar to the hostname of |url|. The
diff --git a/components/lookalikes/core/lookalike_url_util_unittest.cc b/components/lookalikes/core/lookalike_url_util_unittest.cc index ce47215a..bdd7ea8 100644 --- a/components/lookalikes/core/lookalike_url_util_unittest.cc +++ b/components/lookalikes/core/lookalike_url_util_unittest.cc
@@ -177,7 +177,39 @@ const TargetEmbeddingType expected_type; }; -TEST(LookalikeUrlUtilTest, TargetEmbedding) { +TEST(LookalikeUrlUtilTest, ShouldBlockBySpoofCheckResult) { + EXPECT_FALSE(ShouldBlockBySpoofCheckResult( + GetDomainInfo(GURL("https://example.com")))); + // ASCII short eTLD+1: + EXPECT_FALSE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://e.com")))); + EXPECT_FALSE(ShouldBlockBySpoofCheckResult( + GetDomainInfo(GURL("https://subdomain.e.com")))); + // Unicode single character e2LD: + EXPECT_FALSE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://τ.com")))); + EXPECT_FALSE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://test.τ.com")))); + // Unicode single character e2LD with a unicode registry. + EXPECT_FALSE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://τ.рф")))); + EXPECT_FALSE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://test.τ.рф")))); + // Non-unique hostname: + EXPECT_FALSE(ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://τ")))); + + // Multi character e2LD with disallowed characters: + EXPECT_TRUE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://ττ.com")))); + EXPECT_TRUE(ShouldBlockBySpoofCheckResult( + GetDomainInfo(GURL("https://test.ττ.com")))); + EXPECT_TRUE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://ττ.рф")))); + EXPECT_TRUE( + ShouldBlockBySpoofCheckResult(GetDomainInfo(GURL("https://test.ττ.рф")))); +} + +TEST(LookalikeUrlUtilTest, TargetEmbeddingTest) { const std::vector<DomainInfo> kEngagedSites = { GetDomainInfo(GURL("https://highengagement.com")), GetDomainInfo(GURL("https://highengagement.inthesubdomain.com")),
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc index b658066d..a153ba6 100644 --- a/components/metrics/file_metrics_provider.cc +++ b/components/metrics/file_metrics_provider.cc
@@ -125,7 +125,7 @@ switch (type) { case SOURCE_HISTOGRAMS_ACTIVE_FILE: DCHECK(prefs_key.empty()); - FALLTHROUGH; + [[fallthrough]]; case SOURCE_HISTOGRAMS_ATOMIC_FILE: path = params.path; break;
diff --git a/components/metrics/structured/histogram_util.cc b/components/metrics/structured/histogram_util.cc index 3b497bd..702abd8 100644 --- a/components/metrics/structured/histogram_util.cc +++ b/components/metrics/structured/histogram_util.cc
@@ -26,11 +26,6 @@ UMA_HISTOGRAM_ENUMERATION("UMA.StructuredMetrics.KeyValidationState", state); } -void LogClientInitializationSuccessful(bool success) { - UMA_HISTOGRAM_BOOLEAN("UMA.StructuredMetrics.ClientInitializationSuccessful", - success); -} - void LogIsEventRecordedUsingMojo(bool used_mojo_api) { UMA_HISTOGRAM_BOOLEAN("UMA.StructuredMetrics.EventsRecordedUsingMojo", used_mojo_api);
diff --git a/components/metrics/structured/histogram_util.h b/components/metrics/structured/histogram_util.h index e810723dd..c79ee550 100644 --- a/components/metrics/structured/histogram_util.h +++ b/components/metrics/structured/histogram_util.h
@@ -66,8 +66,6 @@ // ProvideCurrentSessionData. void LogNumEventsInUpload(int num_events); -void LogClientInitializationSuccessful(bool success); - // Logs that an event was recorded using the mojo API. void LogIsEventRecordedUsingMojo(bool used_mojo_api);
diff --git a/components/nacl/DEPS b/components/nacl/DEPS index b37894a2..17c2b5e 100644 --- a/components/nacl/DEPS +++ b/components/nacl/DEPS
@@ -3,4 +3,5 @@ "+ipc", "+mojo/public", "+services/service_manager", + "+third_party/cros_system_api/switches/chrome_switches.h", ]
diff --git a/components/nacl/common/nacl_cmd_line.cc b/components/nacl/common/nacl_cmd_line.cc index 09cad50..6424b7d5 100644 --- a/components/nacl/common/nacl_cmd_line.cc +++ b/components/nacl/common/nacl_cmd_line.cc
@@ -26,6 +26,7 @@ switches::kEnableLogging, switches::kDisableLogging, switches::kLoggingLevel, + switches::kVerboseLoggingInNacl, switches::kNoErrorDialogs, #if defined(OS_APPLE) sandbox::policy::switches::kEnableSandboxLogging,
diff --git a/components/nacl/common/nacl_switches.cc b/components/nacl/common/nacl_switches.cc index b9135b4..fd26b57 100644 --- a/components/nacl/common/nacl_switches.cc +++ b/components/nacl/common/nacl_switches.cc
@@ -39,4 +39,13 @@ // for SFI mode. const char kNaClLoaderProcess[] = "nacl-loader"; +// Sets NACLVERBOSITY to enable verbose logging. +// This should match the string used in chrome/browser/about_flags.cc +const char kVerboseLoggingInNacl[] = "verbose-logging-in-nacl"; + +const char kVerboseLoggingInNaclChoiceLow[] = "1"; +const char kVerboseLoggingInNaclChoiceMedium[] = "2"; +const char kVerboseLoggingInNaclChoiceHigh[] = "4"; +const char kVerboseLoggingInNaclChoiceHighest[] = "7"; +const char kVerboseLoggingInNaclChoiceDisabled[] = "0"; } // namespace switches
diff --git a/components/nacl/common/nacl_switches.h b/components/nacl/common/nacl_switches.h index e04606a..a682d9e 100644 --- a/components/nacl/common/nacl_switches.h +++ b/components/nacl/common/nacl_switches.h
@@ -20,6 +20,13 @@ extern const char kNaClGdb[]; extern const char kNaClLoaderProcess[]; +extern const char kVerboseLoggingInNacl[]; +extern const char kVerboseLoggingInNaclChoiceDisabled[]; +extern const char kVerboseLoggingInNaclChoiceLow[]; +extern const char kVerboseLoggingInNaclChoiceMedium[]; +extern const char kVerboseLoggingInNaclChoiceHigh[]; +extern const char kVerboseLoggingInNaclChoiceHighest[]; + } // namespace switches #endif // COMPONENTS_NACL_COMMON_NACL_SWITCHES_H_
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc index f9f69e71..179c95ff 100644 --- a/components/nacl/loader/nacl_helper_linux.cc +++ b/components/nacl/loader/nacl_helper_linux.cc
@@ -24,7 +24,9 @@ #include "base/at_exit.h" #include "base/command_line.h" +#include "base/environment.h" #include "base/files/scoped_file.h" +#include "base/json/json_reader.h" #include "base/logging.h" #include "base/message_loop/message_pump_type.h" #include "base/posix/eintr_wrapper.h" @@ -44,6 +46,7 @@ #include "mojo/core/embedder/embedder.h" #include "sandbox/linux/services/credentials.h" #include "sandbox/linux/services/namespace_sandbox.h" +#include "third_party/cros_system_api/switches/chrome_switches.h" namespace { @@ -52,6 +55,68 @@ long number_of_cores; }; +#if defined(OS_CHROMEOS) +std::string GetCommandLineFeatureFlagChoice( + const base::CommandLine* command_line, + std::string feature_flag) { + std::string encoded = + command_line->GetSwitchValueNative(chromeos::switches::kFeatureFlags); + if (encoded.empty()) { + return ""; + } + + auto flags_list = base::JSONReader::Read(encoded); + if (!flags_list) { + LOG(WARNING) << "Failed to parse feature flags configuration"; + return ""; + } + + for (const auto& flag : flags_list.value().GetList()) { + if (!flag.is_string()) + continue; + std::string flag_string = flag.GetString(); + if (flag_string.rfind(feature_flag) != std::string::npos) + // For option x, this has the form "feature-flag-name@x". Return "x". + return flag_string.substr(feature_flag.size() + 1); + } + return ""; +} + +void AddVerboseLoggingInNaclSwitch(base::CommandLine* command_line) { + if (command_line->HasSwitch(switches::kVerboseLoggingInNacl)) + // Flag is already present, nothing to do here. + return; + + std::string option = GetCommandLineFeatureFlagChoice( + command_line, switches::kVerboseLoggingInNacl); + + // This needs to be kept in sync with the order of choices for + // kVerboseLoggingInNacl in chrome/browser/about_flags.cc + if (option == "") + return; + if (option == "1") + return command_line->AppendSwitchASCII( + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceLow); + if (option == "2") + return command_line->AppendSwitchASCII( + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceMedium); + if (option == "3") + return command_line->AppendSwitchASCII( + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceHigh); + if (option == "4") + return command_line->AppendSwitchASCII( + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceHighest); + if (option == "5") + return command_line->AppendSwitchASCII( + switches::kVerboseLoggingInNacl, + switches::kVerboseLoggingInNaclChoiceDisabled); +} +#endif // defined(OS_CHROMEOS) + // The child must mimic the behavior of zygote_main_linux.cc on the child // side of the fork. See zygote_main_linux.cc:HandleForkRequest from // if (!child) { @@ -63,6 +128,16 @@ // Close or shutdown IPC channels that we don't need anymore. PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); +#if defined(OS_CHROMEOS) + AddVerboseLoggingInNaclSwitch(command_line); +#endif + if (command_line->HasSwitch(switches::kVerboseLoggingInNacl)) { + base::Environment::Create()->SetVar( + "NACLVERBOSITY", + command_line->GetSwitchValueASCII(switches::kVerboseLoggingInNacl)); + } + // Always ignore SIGPIPE, for consistency with other Chrome processes and // because some IPC code, such as sync_socket_posix.cc, requires this. // We do this before seccomp-bpf is initialized.
diff --git a/components/nacl/zygote/nacl_fork_delegate_linux.cc b/components/nacl/zygote/nacl_fork_delegate_linux.cc index 5a71fd90..29074ee 100644 --- a/components/nacl/zygote/nacl_fork_delegate_linux.cc +++ b/components/nacl/zygote/nacl_fork_delegate_linux.cc
@@ -38,6 +38,7 @@ #include "sandbox/linux/suid/client/setuid_sandbox_host.h" #include "sandbox/linux/suid/common/sandbox.h" #include "sandbox/policy/switches.h" +#include "third_party/cros_system_api/switches/chrome_switches.h" namespace { @@ -213,6 +214,8 @@ sandbox::policy::switches::kDisableSeccompFilterSandbox, sandbox::policy::switches::kNoSandbox, switches::kEnableNaClDebug, + switches::kVerboseLoggingInNacl, + chromeos::switches::kFeatureFlags, }; const base::CommandLine& current_cmd_line = *base::CommandLine::ForCurrentProcess();
diff --git a/components/ntp_tiles/popular_sites_impl.cc b/components/ntp_tiles/popular_sites_impl.cc index 746d1c7..4ce4d4f1 100644 --- a/components/ntp_tiles/popular_sites_impl.cc +++ b/components/ntp_tiles/popular_sites_impl.cc
@@ -115,9 +115,10 @@ "directory"); } -PopularSites::SitesVector ParseSiteList(const base::ListValue& list) { +PopularSites::SitesVector ParseSiteList( + const base::Value::ConstListView& list) { PopularSites::SitesVector sites; - for (const base::Value& item_value : list.GetList()) { + for (const base::Value& item_value : list) { if (!item_value.is_dict()) continue; const base::DictionaryValue& item = @@ -155,17 +156,17 @@ } std::map<SectionType, PopularSites::SitesVector> ParseVersion5( - const base::ListValue& list) { + const base::Value::ConstListView& list) { return {{SectionType::PERSONALIZED, ParseSiteList(list)}}; } std::map<SectionType, PopularSites::SitesVector> ParseVersion6OrAbove( - const base::ListValue& list) { + const base::Value::ConstListView& list) { // Valid lists would have contained at least the PERSONALIZED section. std::map<SectionType, PopularSites::SitesVector> sections = { std::make_pair(SectionType::PERSONALIZED, PopularSites::SitesVector{})}; - for (size_t i = 0; i < list.GetList().size(); i++) { - const base::Value& item_value = list.GetList()[i]; + for (size_t i = 0; i < list.size(); i++) { + const base::Value& item_value = list[i]; if (!item_value.is_dict()) { LOG(WARNING) << "Parsed SitesExploration list contained an invalid " << "section at position " << i << "."; @@ -182,18 +183,16 @@ SectionType section_type = static_cast<SectionType>(section); if (section_type != SectionType::PERSONALIZED) continue; - const base::DictionaryValue& item = - base::Value::AsDictionaryValue(item_value); - const base::ListValue* sites_list; - if (!item.GetList("sites", &sites_list)) + const base::Value* sites_list = item_value.FindListKey("sites"); + if (!sites_list) continue; - sections[section_type] = ParseSiteList(*sites_list); + sections[section_type] = ParseSiteList(sites_list->GetList()); } return sections; } std::map<SectionType, PopularSites::SitesVector> ParseSites( - const base::ListValue& list, + const base::Value::ConstListView& list, int version) { if (version >= kSitesExplorationStartVersion) return ParseVersion6OrAbove(list); @@ -271,8 +270,7 @@ url_loader_factory_(std::move(url_loader_factory)), is_fallback_(false), sections_( - ParseSites(base::Value::AsListValue( - *prefs->GetList(prefs::kPopularSitesJsonPref)), + ParseSites(prefs->GetList(prefs::kPopularSitesJsonPref)->GetList(), prefs_->GetInteger(prefs::kPopularSitesVersionPref))) {} PopularSitesImpl::~PopularSitesImpl() {} @@ -478,20 +476,19 @@ return; } - std::unique_ptr<base::ListValue> list = base::ListValue::From( - base::Value::ToUniquePtrValue(std::move(*result.value))); - if (!list) { + base::Value list = std::move(*result.value); + if (!list.is_list()) { DLOG(WARNING) << "JSON is not a list"; OnDownloadFailed(); return; } - prefs_->Set(prefs::kPopularSitesJsonPref, *list); + prefs_->Set(prefs::kPopularSitesJsonPref, list); prefs_->SetInt64(prefs::kPopularSitesLastDownloadPref, base::Time::Now().ToInternalValue()); prefs_->SetInteger(prefs::kPopularSitesVersionPref, version_in_pending_url_); prefs_->SetString(prefs::kPopularSitesURLPref, pending_url_.spec()); - sections_ = ParseSites(*list, version_in_pending_url_); + sections_ = ParseSites(list.GetList(), version_in_pending_url_); std::move(callback_).Run(true); }
diff --git a/components/offline_pages/core/background_snapshot_controller.cc b/components/offline_pages/core/background_snapshot_controller.cc index a9965780..d01fa50 100644 --- a/components/offline_pages/core/background_snapshot_controller.cc +++ b/components/offline_pages/core/background_snapshot_controller.cc
@@ -58,14 +58,13 @@ void BackgroundSnapshotController::RenovationsCompleted() { } -void BackgroundSnapshotController::DocumentOnLoadCompletedInMainFrame() { - // Post a delayed task to snapshot and then stop this controller. - task_runner_->PostDelayedTask( - FROM_HERE, - base::BindOnce( - &BackgroundSnapshotController::MaybeStartSnapshotThenStop, - weak_ptr_factory_.GetWeakPtr()), - base::Milliseconds(delay_after_document_on_load_completed_ms_)); +void BackgroundSnapshotController::DocumentOnLoadCompletedInPrimaryMainFrame() { + // Post a delayed task to snapshot and then stop this controller. + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&BackgroundSnapshotController::MaybeStartSnapshotThenStop, + weak_ptr_factory_.GetWeakPtr()), + base::Milliseconds(delay_after_document_on_load_completed_ms_)); } void BackgroundSnapshotController::MaybeStartSnapshot() {
diff --git a/components/offline_pages/core/background_snapshot_controller.h b/components/offline_pages/core/background_snapshot_controller.h index ced24a4a..0581ce2 100644 --- a/components/offline_pages/core/background_snapshot_controller.h +++ b/components/offline_pages/core/background_snapshot_controller.h
@@ -75,8 +75,8 @@ // The Client calls this when renovations have completed. void RenovationsCompleted(); - // Invoked from WebContentObserver::DocumentOnLoadCompletedInMainFrame - void DocumentOnLoadCompletedInMainFrame(); + // Invoked from WebContentObserver::DocumentOnLoadCompletedInPrimaryMainFrame + void DocumentOnLoadCompletedInPrimaryMainFrame(); int64_t GetDelayAfterDocumentOnLoadCompletedForTest(); int64_t GetDelayAfterRenovationsCompletedForTest();
diff --git a/components/offline_pages/core/background_snapshot_controller_unittest.cc b/components/offline_pages/core/background_snapshot_controller_unittest.cc index e6fa55d4..e2d9233 100644 --- a/components/offline_pages/core/background_snapshot_controller_unittest.cc +++ b/components/offline_pages/core/background_snapshot_controller_unittest.cc
@@ -77,7 +77,7 @@ TEST_F(BackgroundSnapshotControllerTest, OnLoad) { // Onload should make snapshot after its delay. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); PumpLoop(); EXPECT_EQ(0, snapshot_count()); FastForwardBy(base::Milliseconds( @@ -87,7 +87,7 @@ TEST_F(BackgroundSnapshotControllerTest, Stop) { // OnDOM should make snapshot after a delay. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); PumpLoop(); EXPECT_EQ(0, snapshot_count()); controller()->Stop(); @@ -96,21 +96,21 @@ // Should not start snapshots EXPECT_EQ(0, snapshot_count()); // Also should not start snapshot. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); EXPECT_EQ(0, snapshot_count()); } // This simulated a Reset while there is ongoing snapshot, which is reported // as done later. That reporting should have no effect nor crash. TEST_F(BackgroundSnapshotControllerTest, ClientReset) { - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); EXPECT_EQ(1, snapshot_count()); // This normally happens when navigation starts. controller()->Reset(); // Next snapshot should be initiated when new document is loaded. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); // No snapshot since session was reset.
diff --git a/components/offline_pages/core/snapshot_controller.cc b/components/offline_pages/core/snapshot_controller.cc index 2807320b..a01cb80f 100644 --- a/components/offline_pages/core/snapshot_controller.cc +++ b/components/offline_pages/core/snapshot_controller.cc
@@ -74,7 +74,7 @@ base::Milliseconds(delay_after_document_available_ms_)); } -void SnapshotController::DocumentOnLoadCompletedInMainFrame() { +void SnapshotController::DocumentOnLoadCompletedInPrimaryMainFrame() { // Post a delayed task to snapshot and then stop this controller. task_runner_->PostDelayedTask( FROM_HERE,
diff --git a/components/offline_pages/core/snapshot_controller.h b/components/offline_pages/core/snapshot_controller.h index a17b9fb..d82a712d 100644 --- a/components/offline_pages/core/snapshot_controller.h +++ b/components/offline_pages/core/snapshot_controller.h
@@ -85,8 +85,8 @@ // Invoked from WebContentObserver::DocumentAvailableInMainFrame void DocumentAvailableInMainFrame(); - // Invoked from WebContentObserver::DocumentOnLoadCompletedInMainFrame - void DocumentOnLoadCompletedInMainFrame(); + // Invoked from WebContentObserver::DocumentOnLoadCompletedInPrimaryMainFrame + void DocumentOnLoadCompletedInPrimaryMainFrame(); int64_t GetDelayAfterDocumentAvailableForTest(); int64_t GetDelayAfterDocumentOnLoadCompletedForTest();
diff --git a/components/offline_pages/core/snapshot_controller_unittest.cc b/components/offline_pages/core/snapshot_controller_unittest.cc index 0d4bb43..60d9698 100644 --- a/components/offline_pages/core/snapshot_controller_unittest.cc +++ b/components/offline_pages/core/snapshot_controller_unittest.cc
@@ -76,7 +76,7 @@ TEST_F(SnapshotControllerTest, OnLoad) { // Onload should make snapshot after its delay. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); PumpLoop(); EXPECT_EQ(0, snapshot_count()); FastForwardBy(base::Milliseconds( @@ -103,7 +103,7 @@ controller()->DocumentAvailableInMainFrame(); PumpLoop(); EXPECT_EQ(0, snapshot_count()); - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); // Advance time to OnLoadCompleted delay to trigger snapshot. FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); @@ -128,7 +128,7 @@ // Report that snapshot is completed. controller()->PendingSnapshotCompleted(); // OnLoad should make 2nd snapshot after its delay. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); EXPECT_EQ(2, snapshot_count()); @@ -145,7 +145,7 @@ // Should not start snapshots EXPECT_EQ(0, snapshot_count()); // Also should not start snapshot. - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); EXPECT_EQ(0, snapshot_count()); } @@ -157,7 +157,7 @@ controller()->GetDelayAfterDocumentAvailableForTest())); // No snapshot since session was reset. EXPECT_EQ(0, snapshot_count()); - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); EXPECT_EQ(1, snapshot_count()); @@ -173,7 +173,7 @@ // This simulated a Reset while there is ongoing snapshot, which is reported // as done later. That reporting should have no effect nor crash. TEST_F(SnapshotControllerTest, ClientResetWhileSnapshotting) { - controller()->DocumentOnLoadCompletedInMainFrame(); + controller()->DocumentOnLoadCompletedInPrimaryMainFrame(); FastForwardBy(base::Milliseconds( controller()->GetDelayAfterDocumentOnLoadCompletedForTest())); EXPECT_EQ(1, snapshot_count());
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 552b67a..30f6080 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/ui.gni") import("//components/vector_icons/vector_icons.gni") import("//device/vr/buildflags/buildflags.gni") +import("//extensions/buildflags/buildflags.gni") import("//testing/libfuzzer/fuzzer_test.gni") import("//third_party/protobuf/proto_library.gni") @@ -183,8 +184,6 @@ "omnibox_triggered_feature_service.h", "omnibox_view.cc", "omnibox_view.h", - "omnibox_watcher.cc", - "omnibox_watcher.h", "on_device_head_model.cc", "on_device_head_model.h", "on_device_head_provider.cc", @@ -291,6 +290,15 @@ deps += [ "//components/keyed_service/content" ] } + if (enable_extensions) { + sources += [ + "omnibox_input_watcher.cc", + "omnibox_input_watcher.h", + "omnibox_suggestions_watcher.cc", + "omnibox_suggestions_watcher.h", + ] + } + if (is_android) { sources += [ "autocomplete_match_android.cc",
diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc index c26eb04..f640d2f 100644 --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc
@@ -184,7 +184,7 @@ &upgraded_url)) { DCHECK(upgraded_url.is_valid()); added_default_scheme_to_typed_url_ = true; - scheme_ = base::ASCIIToUTF16(url::kHttpsScheme); + scheme_ = std::u16string(url::kHttpsScheme16); canonicalized_url = upgraded_url; // We changed the scheme from http to https. Offset remaining components // by one. @@ -202,8 +202,7 @@ AutocompleteInput::AutocompleteInput(const AutocompleteInput& other) = default; -AutocompleteInput::~AutocompleteInput() { -} +AutocompleteInput::~AutocompleteInput() = default; // static std::string AutocompleteInput::TypeToString(metrics::OmniboxInputType type) {
diff --git a/components/omnibox/browser/builtin_provider.cc b/components/omnibox/browser/builtin_provider.cc index b631648..6c0f698 100644 --- a/components/omnibox/browser/builtin_provider.cc +++ b/components/omnibox/browser/builtin_provider.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <string> +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/omnibox/browser/autocomplete_input.h" @@ -18,6 +19,7 @@ #include "components/search_engines/omnibox_focus_type.h" #include "components/url_formatter/url_fixer.h" #include "third_party/metrics_proto/omnibox_input_type.pb.h" +#include "url/url_constants.h" const int BuiltinProvider::kRelevance = 860; @@ -37,11 +39,10 @@ const size_t kAboutSchemeLength = strlen(url::kAboutScheme); const std::u16string kAbout = - base::ASCIIToUTF16(url::kAboutScheme) + - base::ASCIIToUTF16(url::kStandardSchemeSeparator); - const std::u16string embedderAbout = - base::UTF8ToUTF16(client_->GetEmbedderRepresentationOfAboutScheme()) + - base::ASCIIToUTF16(url::kStandardSchemeSeparator); + base::StrCat({url::kAboutScheme16, url::kStandardSchemeSeparator16}); + const std::u16string embedderAbout = base::StrCat( + {base::UTF8ToUTF16(client_->GetEmbedderRepresentationOfAboutScheme()), + url::kStandardSchemeSeparator16}); const int kUrl = ACMatchClassification::URL; const int kMatch = kUrl | ACMatchClassification::MATCH; @@ -78,12 +79,12 @@ // Chrome does not support trailing slashes or paths for about:blank. const std::u16string blank_host = u"blank"; const std::u16string host = base::UTF8ToUTF16(url.host()); - if (base::StartsWith(text, base::ASCIIToUTF16(url::kAboutScheme), + if (base::StartsWith(text, url::kAboutScheme16, base::CompareCase::INSENSITIVE_ASCII) && base::StartsWith(blank_host, host, base::CompareCase::INSENSITIVE_ASCII) && (url.path().length() <= 1) && !text_ends_with_slash) { - std::u16string match = base::ASCIIToUTF16(url::kAboutBlankURL); + std::u16string match(url::kAboutBlankURL16); const size_t corrected_length = kAboutSchemeLength + 1 + host.length(); TermMatches style_matches = {{0, 0, corrected_length}}; ACMatchClassifications styles =
diff --git a/components/omnibox/browser/builtin_provider_unittest.cc b/components/omnibox/browser/builtin_provider_unittest.cc index 29bda8ff..fa6b4bc7 100644 --- a/components/omnibox/browser/builtin_provider_unittest.cc +++ b/components/omnibox/browser/builtin_provider_unittest.cc
@@ -27,8 +27,6 @@ #include "third_party/metrics_proto/omnibox_event.pb.h" #include "url/gurl.h" -using base::ASCIIToUTF16; - namespace { const char kEmbedderAboutScheme[] = "chrome"; @@ -132,12 +130,11 @@ }; TEST_F(BuiltinProviderTest, TypingScheme) { - const std::u16string kAbout = ASCIIToUTF16(url::kAboutScheme); + const std::u16string kAbout = url::kAboutScheme16; const std::u16string kEmbedder = kEmbedderAboutScheme16; const std::u16string kSeparator1 = u":"; const std::u16string kSeparator2 = u":/"; - const std::u16string kSeparator3 = - ASCIIToUTF16(url::kStandardSchemeSeparator); + const std::u16string kSeparator3 = url::kStandardSchemeSeparator16; // These default URLs should correspond with those in BuiltinProvider::Start. const GURL kURL1(kDefaultURL1); @@ -197,11 +194,11 @@ } TEST_F(BuiltinProviderTest, EmbedderProvidedURLs) { - const std::u16string kAbout = ASCIIToUTF16(url::kAboutScheme); + const std::u16string kAbout = url::kAboutScheme16; const std::u16string kEmbedder = kEmbedderAboutScheme16; const std::u16string kSep1 = u":"; const std::u16string kSep2 = u":/"; - const std::u16string kSep3 = ASCIIToUTF16(url::kStandardSchemeSeparator); + const std::u16string kSep3 = url::kStandardSchemeSeparator16; // The following hosts are arbitrary, chosen so that they all start with the // letters "me". @@ -246,12 +243,11 @@ } TEST_F(BuiltinProviderTest, AboutBlank) { - const std::u16string kAbout = ASCIIToUTF16(url::kAboutScheme); + const std::u16string kAbout = url::kAboutScheme16; const std::u16string kEmbedder = kEmbedderAboutScheme16; - const std::u16string kAboutBlank = ASCIIToUTF16(url::kAboutBlankURL); + const std::u16string kAboutBlank = url::kAboutBlankURL16; const std::u16string kBlank = u"blank"; - const std::u16string kSeparator1 = - ASCIIToUTF16(url::kStandardSchemeSeparator); + const std::u16string kSeparator1 = url::kStandardSchemeSeparator16; const std::u16string kSeparator2 = u":///"; const std::u16string kSeparator3 = u";///"; @@ -338,9 +334,9 @@ } TEST_F(BuiltinProviderTest, Inlining) { - const std::u16string kAbout = ASCIIToUTF16(url::kAboutScheme); + const std::u16string kAbout = url::kAboutScheme16; const std::u16string kEmbedder = kEmbedderAboutScheme16; - const std::u16string kSep = ASCIIToUTF16(url::kStandardSchemeSeparator); + const std::u16string kSep = url::kStandardSchemeSeparator16; const std::u16string kHostM = kHostMedia; const std::u16string kHostB = kHostBar; const std::u16string kHostMem = kHostMemory;
diff --git a/components/omnibox/browser/keyword_provider.cc b/components/omnibox/browser/keyword_provider.cc index f6c1b40..5ecc40a 100644 --- a/components/omnibox/browser/keyword_provider.cc +++ b/components/omnibox/browser/keyword_provider.cc
@@ -11,6 +11,7 @@ #include "base/containers/cxx20_erase.h" #include "base/i18n/case_conversion.h" #include "base/memory/raw_ptr.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" @@ -28,6 +29,7 @@ #include "net/base/escape.h" #include "third_party/metrics_proto/omnibox_input_type.pb.h" #include "ui/base/l10n/l10n_util.h" +#include "url/url_constants.h" namespace { @@ -573,33 +575,31 @@ // If keyword is not found, try removing a "http" or "https" scheme if any. url::Component scheme_component; - if (url::ExtractScheme(base::UTF16ToUTF8(result).c_str(), - static_cast<int>(result.length()), - &scheme_component) && - (!result.compare(0, scheme_component.end(), - base::ASCIIToUTF16(url::kHttpScheme)) || - !result.compare(0, scheme_component.end(), - base::ASCIIToUTF16(url::kHttpsScheme)))) { - // Remove the scheme and the trailing ':'. - result.erase(0, scheme_component.end() + 1); - if (template_url_service->GetTemplateURLForKeyword(result) != nullptr) - return result; - // Many schemes usually have "//" after them, so strip it too. - const std::u16string after_scheme(u"//"); - if (result.compare(0, after_scheme.length(), after_scheme) == 0) - result.erase(0, after_scheme.length()); - if (template_url_service->GetTemplateURLForKeyword(result) != nullptr) - return result; + if (url::ExtractScheme(result.c_str(), static_cast<int>(result.length()), + &scheme_component)) { + const base::StringPiece16 scheme = base::StringPiece16(result).substr( + scheme_component.begin, scheme_component.len); + if (scheme == url::kHttpScheme16 || scheme == url::kHttpsScheme16) { + // Remove the scheme and the trailing ':'. + result.erase(0, scheme_component.end() + 1); + if (template_url_service->GetTemplateURLForKeyword(result) != nullptr) + return result; + // Many schemes usually have "//" after them, so strip it too. + constexpr base::StringPiece16 kAfterScheme(u"//"); + if (base::StartsWith(result, kAfterScheme)) + result.erase(0, kAfterScheme.length()); + if (template_url_service->GetTemplateURLForKeyword(result) != nullptr) + return result; + } } // Remove leading "www.", if any, and again try to find a matching keyword. // The 'www.' stripping is done directly here instead of calling // url_formatter::StripWWW because we're not assuming that the keyword is a // hostname. - const std::u16string kWww(u"www."); - constexpr size_t kWwwLength = 4; + constexpr base::StringPiece16 kWww(u"www."); result = base::StartsWith(result, kWww, base::CompareCase::SENSITIVE) - ? result.substr(kWwwLength) + ? result.substr(kWww.length()) : result; if (template_url_service->GetTemplateURLForKeyword(result) != nullptr) return result;
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc index ab91f41..83ecadd 100644 --- a/components/omnibox/browser/omnibox_edit_model.cc +++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -16,6 +16,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -450,10 +451,11 @@ // Infer the correct scheme for the copied text, and prepend it if necessary. { - std::u16string http = base::ASCIIToUTF16(url::kHttpScheme) + - base::ASCIIToUTF16(url::kStandardSchemeSeparator); - std::u16string https = base::ASCIIToUTF16(url::kHttpsScheme) + - base::ASCIIToUTF16(url::kStandardSchemeSeparator); + const std::u16string http = + base::StrCat({url::kHttpScheme16, url::kStandardSchemeSeparator16}); + const std::u16string https = + base::StrCat({url::kHttpsScheme16, url::kStandardSchemeSeparator16}); + const std::u16string& current_page_url_prefix = current_page_url.SchemeIs(url::kHttpScheme) ? http : https;
diff --git a/components/omnibox/browser/omnibox_watcher.cc b/components/omnibox/browser/omnibox_input_watcher.cc similarity index 60% rename from components/omnibox/browser/omnibox_watcher.cc rename to components/omnibox/browser/omnibox_input_watcher.cc index 24deb39..badb0e4 100644 --- a/components/omnibox/browser/omnibox_watcher.cc +++ b/components/omnibox/browser/omnibox_input_watcher.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "omnibox_watcher.h" +#include "omnibox_input_watcher.h" #if !defined(OS_IOS) #include "base/memory/singleton.h" @@ -13,28 +13,28 @@ namespace { #if !defined(OS_IOS) -class OmniboxWatcherFactory : public BrowserContextKeyedServiceFactory { +class OmniboxInputWatcherFactory : public BrowserContextKeyedServiceFactory { public: - static OmniboxWatcher* GetForBrowserContext( + static OmniboxInputWatcher* GetForBrowserContext( content::BrowserContext* context) { - return static_cast<OmniboxWatcher*>( + return static_cast<OmniboxInputWatcher*>( GetInstance()->GetServiceForBrowserContext(context, true)); } - static OmniboxWatcherFactory* GetInstance() { - return base::Singleton<OmniboxWatcherFactory>::get(); + static OmniboxInputWatcherFactory* GetInstance() { + return base::Singleton<OmniboxInputWatcherFactory>::get(); } - OmniboxWatcherFactory() + OmniboxInputWatcherFactory() : BrowserContextKeyedServiceFactory( - "OmniboxWatcher", + "OmniboxInputWatcher", BrowserContextDependencyManager::GetInstance()) {} private: // BrowserContextKeyedServiceFactory overrides KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override { - return new OmniboxWatcher(); + return new OmniboxInputWatcher(); } content::BrowserContext* GetBrowserContextToUse( @@ -46,26 +46,26 @@ } // namespace -OmniboxWatcher::OmniboxWatcher() = default; -OmniboxWatcher::~OmniboxWatcher() = default; +OmniboxInputWatcher::OmniboxInputWatcher() = default; +OmniboxInputWatcher::~OmniboxInputWatcher() = default; #if !defined(OS_IOS) // static -OmniboxWatcher* OmniboxWatcher::GetForBrowserContext( +OmniboxInputWatcher* OmniboxInputWatcher::GetForBrowserContext( content::BrowserContext* browser_context) { - return OmniboxWatcherFactory::GetForBrowserContext(browser_context); + return OmniboxInputWatcherFactory::GetForBrowserContext(browser_context); } #endif // !defined(OS_IOS) -void OmniboxWatcher::AddObserver(Observer* observer) { +void OmniboxInputWatcher::AddObserver(Observer* observer) { observers_.AddObserver(observer); } -void OmniboxWatcher::RemoveObserver(Observer* observer) { +void OmniboxInputWatcher::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } -void OmniboxWatcher::NotifyInputEntered() { +void OmniboxInputWatcher::NotifyInputEntered() { for (auto& observer : observers_) observer.OnOmniboxInputEntered(); }
diff --git a/components/omnibox/browser/omnibox_watcher.h b/components/omnibox/browser/omnibox_input_watcher.h similarity index 62% rename from components/omnibox/browser/omnibox_watcher.h rename to components/omnibox/browser/omnibox_input_watcher.h index f9999d8..9cda9569 100644 --- a/components/omnibox/browser/omnibox_watcher.h +++ b/components/omnibox/browser/omnibox_input_watcher.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_WATCHER_H_ -#define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_WATCHER_H_ +#ifndef COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_INPUT_WATCHER_H_ +#define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_INPUT_WATCHER_H_ #include "base/observer_list.h" #include "base/observer_list_types.h" @@ -14,9 +14,8 @@ #include "content/public/browser/browser_context.h" #endif // !defined(OS_IOS) -// This KeyedService is meant to observe the omnibox and provide notifications -// to observers on suggestion changes and provided input. -class OmniboxWatcher : public KeyedService { +// This KeyedService is meant to observe omnibox input and provide notifications +class OmniboxInputWatcher : public KeyedService { public: class Observer : public base::CheckedObserver { public: @@ -25,14 +24,14 @@ }; #if !defined(OS_IOS) - static OmniboxWatcher* GetForBrowserContext( + static OmniboxInputWatcher* GetForBrowserContext( content::BrowserContext* browser_context); #endif // !defined(OS_IOS) - OmniboxWatcher(); - ~OmniboxWatcher() override; - OmniboxWatcher(const OmniboxWatcher&) = delete; - OmniboxWatcher& operator=(const OmniboxWatcher&) = delete; + OmniboxInputWatcher(); + ~OmniboxInputWatcher() override; + OmniboxInputWatcher(const OmniboxInputWatcher&) = delete; + OmniboxInputWatcher& operator=(const OmniboxInputWatcher&) = delete; void NotifyInputEntered(); @@ -44,4 +43,4 @@ base::ObserverList<Observer> observers_; }; -#endif // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_WATCHER_H_ +#endif // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_INPUT_WATCHER_H_
diff --git a/components/omnibox/browser/omnibox_suggestions_watcher.cc b/components/omnibox/browser/omnibox_suggestions_watcher.cc new file mode 100644 index 0000000..ed2ae7fc --- /dev/null +++ b/components/omnibox/browser/omnibox_suggestions_watcher.cc
@@ -0,0 +1,74 @@ +// 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 "omnibox_suggestions_watcher.h" + +#if !defined(OS_IOS) +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#endif // !defined(OS_IOS) + +namespace { + +#if !defined(OS_IOS) +class OmniboxSuggestionsWatcherFactory + : public BrowserContextKeyedServiceFactory { + public: + static OmniboxSuggestionsWatcher* GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<OmniboxSuggestionsWatcher*>( + GetInstance()->GetServiceForBrowserContext(context, true)); + } + + static OmniboxSuggestionsWatcherFactory* GetInstance() { + return base::Singleton<OmniboxSuggestionsWatcherFactory>::get(); + } + + OmniboxSuggestionsWatcherFactory() + : BrowserContextKeyedServiceFactory( + "OmniboxSuggestionsWatcher", + BrowserContextDependencyManager::GetInstance()) {} + + private: + // BrowserContextKeyedServiceFactory overrides + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override { + return new OmniboxSuggestionsWatcher(); + } + + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override { + return context; + } +}; +#endif // !defined(OS_IOS) + +} // namespace + +OmniboxSuggestionsWatcher::OmniboxSuggestionsWatcher() = default; +OmniboxSuggestionsWatcher::~OmniboxSuggestionsWatcher() = default; + +#if !defined(OS_IOS) +// static +OmniboxSuggestionsWatcher* OmniboxSuggestionsWatcher::GetForBrowserContext( + content::BrowserContext* browser_context) { + return OmniboxSuggestionsWatcherFactory::GetForBrowserContext( + browser_context); +} +#endif // !defined(OS_IOS) + +void OmniboxSuggestionsWatcher::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void OmniboxSuggestionsWatcher::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void OmniboxSuggestionsWatcher::NotifySuggestionsReady( + extensions::api::omnibox::SendSuggestions::Params* suggestions) { + for (auto& observer : observers_) + observer.OnOmniboxSuggestionsReady(suggestions); +}
diff --git a/components/omnibox/browser/omnibox_suggestions_watcher.h b/components/omnibox/browser/omnibox_suggestions_watcher.h new file mode 100644 index 0000000..f296d52 --- /dev/null +++ b/components/omnibox/browser/omnibox_suggestions_watcher.h
@@ -0,0 +1,59 @@ +// 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_OMNIBOX_BROWSER_OMNIBOX_SUGGESTIONS_WATCHER_H_ +#define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_SUGGESTIONS_WATCHER_H_ + +#include "base/observer_list.h" +#include "base/observer_list_types.h" +#include "build/build_config.h" +#include "components/keyed_service/core/keyed_service.h" + +#if !defined(OS_IOS) +#include "content/public/browser/browser_context.h" +#endif // !defined(OS_IOS) + +namespace extensions { +namespace api { +namespace omnibox { +namespace SendSuggestions { +struct Params; +} // namespace SendSuggestions +} // namespace omnibox +} // namespace api +} // namespace extensions + +// This KeyedService is meant to observe omnibox suggestions and provide +// notifications to observers on suggestion changes. +class OmniboxSuggestionsWatcher : public KeyedService { + public: + class Observer : public base::CheckedObserver { + public: + virtual void OnOmniboxSuggestionsReady( + extensions::api::omnibox::SendSuggestions::Params* suggestions) {} + }; + +#if !defined(OS_IOS) + static OmniboxSuggestionsWatcher* GetForBrowserContext( + content::BrowserContext* browser_context); +#endif // !defined(OS_IOS) + + OmniboxSuggestionsWatcher(); + ~OmniboxSuggestionsWatcher() override; + OmniboxSuggestionsWatcher(const OmniboxSuggestionsWatcher&) = delete; + OmniboxSuggestionsWatcher& operator=(const OmniboxSuggestionsWatcher&) = + delete; + + void NotifySuggestionsReady( + extensions::api::omnibox::SendSuggestions::Params* suggestions); + + // Add/remove observer. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + private: + base::ObserverList<Observer> observers_; +}; + +#endif // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_SUGGESTIONS_WATCHER_H_
diff --git a/components/omnibox/browser/omnibox_view.cc b/components/omnibox/browser/omnibox_view.cc index 66b82f30..7f2997ef 100644 --- a/components/omnibox/browser/omnibox_view.cc +++ b/components/omnibox/browser/omnibox_view.cc
@@ -12,6 +12,7 @@ #include <string> #include <utility> +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -26,6 +27,7 @@ #include "components/omnibox/common/omnibox_features.h" #include "extensions/common/constants.h" #include "ui/base/l10n/l10n_util.h" +#include "url/url_constants.h" #if !defined(OS_ANDROID) && !defined(OS_IOS) @@ -51,8 +53,8 @@ // static std::u16string OmniboxView::StripJavascriptSchemas(const std::u16string& text) { - const std::u16string kJsPrefix(base::ASCIIToUTF16(url::kJavaScriptScheme) + - u":"); + const std::u16string kJsPrefix( + base::StrCat({url::kJavaScriptScheme16, u":"})); bool found_JavaScript = false; size_t i = 0; @@ -372,7 +374,7 @@ // For normal URLs, the host is the best proxy for "identity". if (url_scheme == base::UTF8ToUTF16(extensions::kExtensionScheme)) deemphasize = EVERYTHING; - else if (url_scheme == base::UTF8ToUTF16(url::kDataScheme)) + else if (url_scheme == url::kDataScheme16) deemphasize = ALL_BUT_SCHEME; else if (host.is_nonempty()) deemphasize = ALL_BUT_HOST;
diff --git a/components/omnibox/browser/zero_suggest_verbatim_match_provider.cc b/components/omnibox/browser/zero_suggest_verbatim_match_provider.cc index e298d668..dc6f368 100644 --- a/components/omnibox/browser/zero_suggest_verbatim_match_provider.cc +++ b/components/omnibox/browser/zero_suggest_verbatim_match_provider.cc
@@ -5,6 +5,7 @@ #include "components/omnibox/browser/zero_suggest_verbatim_match_provider.h" #include "base/feature_list.h" +#include "components/omnibox/browser/autocomplete_match_classification.h" #include "components/omnibox/browser/autocomplete_provider_client.h" #include "components/omnibox/browser/autocomplete_provider_listener.h" #include "components/omnibox/browser/verbatim_match.h" @@ -76,6 +77,16 @@ net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); + TermMatches term_matches; + if (input.text().length() > 0) { + term_matches = {{0, 0, input.text().length()}}; + } + + match.contents_class = ClassifyTermMatches( + term_matches, match.contents.size(), + ACMatchClassification::MATCH | ACMatchClassification::URL, + ACMatchClassification::URL); + // In the case of native pages, the classifier may replace the URL with an // empty content, resulting with a verbatim match that does not point // anywhere.
diff --git a/components/optimization_guide/proto/models.proto b/components/optimization_guide/proto/models.proto index e36ff0c..43784f1f 100644 --- a/components/optimization_guide/proto/models.proto +++ b/components/optimization_guide/proto/models.proto
@@ -300,6 +300,8 @@ MODEL_ENGINE_VERSION_TFLITE_2_7 = 5; // A model using only operations that are supported by TensorflowLite 2.8.0. MODEL_ENGINE_VERSION_TFLITE_2_8 = 6; + // A model using only operations that are supported by TensorflowLite 2.9.0. + MODEL_ENGINE_VERSION_TFLITE_2_9 = 7; } // A set of model features and the host that it applies to.
diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc index 8bd17c50..b9a6f996 100644 --- a/components/page_info/page_info_ui.cc +++ b/components/page_info/page_info_ui.cc
@@ -493,7 +493,7 @@ // Internal pages on desktop have their own UI implementations which // should never call this function. NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case PageInfo::SITE_IDENTITY_STATUS_EV_CERT: case PageInfo::SITE_IDENTITY_STATUS_CERT: case PageInfo::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT: @@ -604,7 +604,7 @@ button_text_ids = kPermissionButtonTextIDDefaultSetting; break; } - FALLTHROUGH; + [[fallthrough]]; case content_settings::SETTING_SOURCE_POLICY: case content_settings::SETTING_SOURCE_EXTENSION: #if !defined(OS_ANDROID)
diff --git a/components/performance_manager/decorators/page_load_tracker_decorator.cc b/components/performance_manager/decorators/page_load_tracker_decorator.cc index c077b21a..1d297ce 100644 --- a/components/performance_manager/decorators/page_load_tracker_decorator.cc +++ b/components/performance_manager/decorators/page_load_tracker_decorator.cc
@@ -229,7 +229,7 @@ LoadIdleState::kWaitingForNavigationTimedOut); } - FALLTHROUGH; + [[fallthrough]]; } case LoadIdleState::kWaitingForNavigationTimedOut: { @@ -268,7 +268,7 @@ data->loading_stopped_ = now; // Let the kLoadedNotIdling state transition evaluate, allowing an // immediate transition to kLoadedAndIdling if the page is already idling. - FALLTHROUGH; + [[fallthrough]]; } case LoadIdleState::kLoadedNotIdling: { @@ -282,7 +282,7 @@ data->SetLoadIdleState(page_node, LoadIdleState::kLoadedAndIdling); data->idling_started_ = now; - FALLTHROUGH; + [[fallthrough]]; } case LoadIdleState::kLoadedAndIdling: {
diff --git a/components/permissions/contexts/geolocation_permission_context_unittest.cc b/components/permissions/contexts/geolocation_permission_context_unittest.cc index a96f3f9f..05e79a46 100644 --- a/components/permissions/contexts/geolocation_permission_context_unittest.cc +++ b/components/permissions/contexts/geolocation_permission_context_unittest.cc
@@ -402,7 +402,7 @@ void GeolocationPermissionContextTests::RequestManagerDocumentLoadCompleted( content::WebContents* web_contents) { PermissionRequestManager::FromWebContents(web_contents) - ->DocumentOnLoadCompletedInMainFrame(main_rfh()); + ->DocumentOnLoadCompletedInPrimaryMainFrame(); } ContentSetting GeolocationPermissionContextTests::GetGeolocationContentSetting(
diff --git a/components/permissions/contexts/nfc_permission_context_unittest.cc b/components/permissions/contexts/nfc_permission_context_unittest.cc index 03c50e5..558c290 100644 --- a/components/permissions/contexts/nfc_permission_context_unittest.cc +++ b/components/permissions/contexts/nfc_permission_context_unittest.cc
@@ -183,7 +183,7 @@ void NfcPermissionContextTests::RequestManagerDocumentLoadCompleted() { PermissionRequestManager::FromWebContents(web_contents()) - ->DocumentOnLoadCompletedInMainFrame(web_contents()->GetMainFrame()); + ->DocumentOnLoadCompletedInPrimaryMainFrame(); } ContentSetting NfcPermissionContextTests::GetNfcContentSetting(GURL frame_0,
diff --git a/components/permissions/permission_context_base_unittest.cc b/components/permissions/permission_context_base_unittest.cc index 2358bbe07..954e0c5 100644 --- a/components/permissions/permission_context_base_unittest.cc +++ b/components/permissions/permission_context_base_unittest.cc
@@ -721,7 +721,7 @@ void SetUpUrl(const GURL& url) { NavigateAndCommit(url); - prompt_factory_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + prompt_factory_->DocumentOnLoadCompletedInPrimaryMainFrame(); } private:
diff --git a/components/permissions/permission_manager_unittest.cc b/components/permissions/permission_manager_unittest.cc index 576bccd..788e84b1 100644 --- a/components/permissions/permission_manager_unittest.cc +++ b/components/permissions/permission_manager_unittest.cc
@@ -756,7 +756,7 @@ PermissionRequestManager::FromWebContents(web_contents()); auto prompt_factory = std::make_unique<MockPermissionPromptFactory>(manager); prompt_factory->set_response_type(PermissionRequestManager::ACCEPT_ALL); - prompt_factory->DocumentOnLoadCompletedInMainFrame(main_rfh()); + prompt_factory->DocumentOnLoadCompletedInPrimaryMainFrame(); RequestPermission(PermissionType::GEOLOCATION, child, GURL(kOrigin2));
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc index 7c2d6ad..63af2c42 100644 --- a/components/permissions/permission_request_manager.cc +++ b/components/permissions/permission_request_manager.cc
@@ -375,8 +375,7 @@ CleanUpRequests(); } -void PermissionRequestManager::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void PermissionRequestManager::DocumentOnLoadCompletedInPrimaryMainFrame() { // This is scheduled because while all calls to the browser have been // issued at DOMContentLoaded, they may be bouncing around in scheduled // callbacks finding the UI thread still. This makes sure we allow those @@ -428,7 +427,7 @@ return; } - if (!web_contents()->IsDocumentOnLoadCompletedInMainFrame()) + if (!web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame()) return; if (!IsRequestInProgress()) { @@ -584,7 +583,7 @@ // PermissionBubbleMediaAccessHandler and UserMediaClient. We probably don't // need two permission queues, so resolve the duplication. - if (!web_contents()->IsDocumentOnLoadCompletedInMainFrame() || view_ || + if (!web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame() || view_ || IsRequestInProgress()) { return; } @@ -665,7 +664,7 @@ if (!IsRequestInProgress() || view_) return; - DCHECK(web_contents()->IsDocumentOnLoadCompletedInMainFrame()); + DCHECK(web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame()); DCHECK(current_request_ui_to_use_); if (tab_is_hidden_)
diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h index 4ef2815..c594748 100644 --- a/components/permissions/permission_request_manager.h +++ b/components/permissions/permission_request_manager.h
@@ -126,8 +126,7 @@ content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; void WebContentsDestroyed() override; void OnVisibilityChanged(content::Visibility visibility) override;
diff --git a/components/permissions/permission_request_manager_unittest.cc b/components/permissions/permission_request_manager_unittest.cc index 79aa0f23..bc7ddfd 100644 --- a/components/permissions/permission_request_manager_unittest.cc +++ b/components/permissions/permission_request_manager_unittest.cc
@@ -99,7 +99,7 @@ } void WaitForBubbleToBeShown() { - manager_->DocumentOnLoadCompletedInMainFrame(main_rfh()); + manager_->DocumentOnLoadCompletedInPrimaryMainFrame(); base::RunLoop().RunUntilIdle(); }
diff --git a/components/permissions/test/mock_permission_prompt_factory.cc b/components/permissions/test/mock_permission_prompt_factory.cc index 3a860ed8..eb5a48c 100644 --- a/components/permissions/test/mock_permission_prompt_factory.cc +++ b/components/permissions/test/mock_permission_prompt_factory.cc
@@ -60,9 +60,8 @@ request_origins_seen_.clear(); } -void MockPermissionPromptFactory::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { - manager_->DocumentOnLoadCompletedInMainFrame(render_frame_host); +void MockPermissionPromptFactory::DocumentOnLoadCompletedInPrimaryMainFrame() { + manager_->DocumentOnLoadCompletedInPrimaryMainFrame(); } bool MockPermissionPromptFactory::is_visible() {
diff --git a/components/permissions/test/mock_permission_prompt_factory.h b/components/permissions/test/mock_permission_prompt_factory.h index 0041667..5f6ed7d4 100644 --- a/components/permissions/test/mock_permission_prompt_factory.h +++ b/components/permissions/test/mock_permission_prompt_factory.h
@@ -44,8 +44,7 @@ void ResetCounts(); - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host); + void DocumentOnLoadCompletedInPrimaryMainFrame(); void set_response_type(PermissionRequestManager::AutoResponseType type) { response_type_ = type;
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 4f55df3..857f3f9 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -173,6 +173,9 @@ // Audio telemetry policy optional int64 report_device_audio_status_checking_rate_ms = 35 [default = 600000]; + + // CRD Sessions reporting policy + optional bool report_crd_sessions = 36 [default = false]; } message EphemeralUsersEnabledProto {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index def17e2..32c3bde4 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -972,6 +972,7 @@ 'ReportDeviceSystemInfo', 'ReportDevicePrintJobs', 'ReportDeviceLoginLogout', + 'ReportCRDSessions', 'ReportUploadFrequency', 'ReportArcStatusEnabled', 'HeartbeatEnabled', @@ -11153,6 +11154,38 @@ 'arc_support': 'This policy has no effect on the logging done by Android.', }, { + 'name': 'ReportCRDSessions', + 'owners': ['lbaraz@google.com', 'cros-reporting-team@google.com'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:99-'], + 'supported_chrome_os_management': ['google_cloud'], + 'device_only': True, + 'features': { + 'dynamic_refresh': True, + }, + 'items': [ + { + 'value': True, + 'caption': 'Report <ph name="CHROME_REMOTE_DESKTOP_PRODUCT_NAME">Chrome Remote Desktop</ph> events', + }, + { + 'value': False, + 'caption': 'Do not report CRD sessions events', + }, + ], + 'example_value': False, + 'default': False, + 'id': 939, + 'caption': '''Report CRD sessions''', + 'tags': ['admin-sharing'], + 'desc': '''Report CRD sessions events on enrolled devices for affiliated users. + + If the policy is Disabled or left unset, the information will not be reported. + If Enabled, the CRD events will be reported, if the user is affiliated''', + 'arc_support': 'This policy has no effect on the logging done by Android.', + }, + { 'name': 'ReportUploadFrequency', 'owners': ['cros-reporting-team@google.com', 'lbaraz@chromium.org'], 'type': 'int', @@ -13023,8 +13056,8 @@ }, { 'id': 930, - 'name': 'FullscreenNotificationUrlExemptList', - 'caption': '''List of URLs which are exempt from the full screen notification''', + 'name': 'KeepFullscreenWithoutNotificationUrlAllowList', + 'caption': '''List of URLs which are allowed to remain in full screen mode without showing a notification''', 'owners': ['aninak@chromium.org', 'file://ash/session/OWNERS'], 'type': 'list', 'schema': { @@ -13042,11 +13075,11 @@ '*', ], 'tags': [], - 'desc': '''Configure a list of URLs that are exempt from the full screen notification. The notification is shown when the device returns from sleep, low brightness or the lock screen and has a window in full screen mode. This is to make users aware that they are in full screen mode, which reduces the risk of phishing attacks. + 'desc': '''Configure a list of URLs that are allowed to stay in full screen mode without showing a notification when the device returns from the lock screen. - This policy allows to disable the notification for specific URLs that will be considered trusted sources. It is set by specifying a list of URL patterns formatted according to this format ( https://www.chromium.org/administrators/url-blocklist-filter-format ). E.g., it is possible to disable the notifications altogether by specifying the wildcard character <ph name="WILDCARD_VALUE">*</ph> matching all URLs. + Normally, full screen mode is turned off when returning from the lock screen in order to reduce the risk of phishing attacks. This policy allows to specify URLs that will be considered trusted sources which are permitted to continue full screen mode on unlock. It is set by specifying a list of URL patterns formatted according to this format ( https://www.chromium.org/administrators/url-blocklist-filter-format ). E.g., it is possible to always keep full screen mode on unlock and disable the notifications altogether by specifying the wildcard character <ph name="WILDCARD_VALUE">*</ph> matching all URLs. - Setting this policy to an empty list or leaving it unset means no URLs are exempt from the full screen notification.''', + Setting this policy to an empty list or leaving it unset means no URLs are allowed to continue full screen mode without a notification.''', }, { 'name': 'ScreenDimDelayAC', @@ -29642,6 +29675,7 @@ 'ReportDeviceSystemInfo': 'device_reporting.report_system_info', 'ReportDevicePrintJobs': 'device_reporting.report_print_jobs', 'ReportDeviceLoginLogout': 'device_reporting.report_login_logout', + 'ReportCRDSessions': 'device_reporting.report_crd_sessions', 'ReportDeviceNetworkTelemetryCollectionRateMs': 'device_reporting.report_network_telemetry_collection_rate_ms', 'ReportDeviceNetworkTelemetryEventCheckingRateMs': 'device_reporting.report_network_telemetry_event_checking_rate_ms', 'ReportDeviceAudioStatusCheckingRateMs': 'device_reporting.report_device_audio_status_checking_rate_ms', @@ -30226,6 +30260,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 204, 205, 206, 341, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669, 872], 'deleted_atomic_policy_group_ids': [19], - 'highest_id_currently_used': 938, + 'highest_id_currently_used': 939, 'highest_atomic_group_id_currently_used': 41 }
diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb index 6ddd899..6568054 100644 --- a/components/policy/resources/policy_templates_fr.xtb +++ b/components/policy/resources/policy_templates_fr.xtb
@@ -2584,6 +2584,7 @@ <translation id="3964298692570794635">Autoriser le contenu non sécurisé sur ces sites</translation> <translation id="3965339130942650562">Délai avant exécution de la déconnexion de l'utilisateur en cas d'inactivité</translation> <translation id="396536755218079668">Utilisateurs supervisés</translation> +<translation id="3968218878014278212">Autoriser le lancement de l'application Eche.</translation> <translation id="3971673686578912106">Si cette règle est activée, <ph name="PLUGIN_VM_NAME" /> est activé pour l'appareil tant que d'autres paramètres le permettent également. Les règles "<ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" />" et "<ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" />" doivent être définies sur "True", et l'une des deux règles "<ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" />" et "<ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />" doit être configurée pour que <ph name="PLUGIN_VM_NAME" /> puisse être exécuté. Si cette règle est désactivée ou qu'elle n'est pas configurée, <ph name="PLUGIN_VM_NAME" /> n'est pas activé pour l'appareil.</translation> @@ -3417,6 +3418,7 @@ Si cette règle est définie sur "False" ou qu'elle n'est pas configurée, <ph name="PRODUCT_NAME" /> utilise les paramètres actuels de vérification en ligne de la révocation.</translation> <translation id="5078623750797048009">Activer les annotations des PDF</translation> <translation id="5081204761483900654">Sessions Invité gérées restreintes</translation> +<translation id="5082296146261894974">Permet aux utilisateurs de cliquer sur une notification Phone Hub pour lancer l'application Eche.</translation> <translation id="5082572440690475059">Autoriser l'accès en lecture via l'API File System pour ces sites</translation> <translation id="5085647276663819155">Désactiver l'aperçu avant impression</translation> <translation id="5090791951240382356">Autoriser la fusion de règles de dictionnaire qui proviennent de sources différentes</translation> @@ -4174,6 +4176,7 @@ Le champ <ph name="RUN_ON_OS_LOGIN_FIELD" /> indique si une application Web peut être exécutée pendant la connexion au système d'exploitation. Si ce champ est défini sur <ph name="BLOCKED" />, l'application Web ne s'exécutera pas pendant la connexion au système d'exploitation et l'utilisateur ne pourra pas activer ce champ plus tard. Si ce champ est défini sur <ph name="RUN_WINDOWED" />, l'application Web s'exécutera pendant la connexion au système d'exploitation et l'utilisateur ne pourra pas désactiver ce champ plus tard. Si ce champ est défini sur <ph name="ALLOWED" />, l'utilisateur pourra configurer l'application Web pour qu'elle s'exécute pendant la connexion au système d'exploitation. La configuration par défaut n'autorise que les valeurs <ph name="ALLOWED" /> et <ph name="BLOCKED" />. </translation> +<translation id="5945312246863177268">Empêche les utilisateurs de cliquer sur une notification Phone Hub pour lancer l'application Eche.</translation> <translation id="5946082169633555022">Version bêta</translation> <translation id="5946329690214660966">Planifier de manière personnalisée la recherche de mises à jour</translation> <translation id="5950069117106131681">Si vous activez cette règle, les en-têtes et les pieds de pages sont activés dans l'aperçu avant impression. Si vous la désactivez, ces éléments le sont également dans l'aperçu avant impression. @@ -4752,6 +4755,11 @@ <translation id="66265932317331474">Transmettre les informations concernant le ou les processeurs</translation> <translation id="6628120204569232711">Envoyer des rapports sur l'état du stockage</translation> <translation id="663685822663765995">Limiter l'impression en mode couleur</translation> +<translation id="6640355849038068978">Si ce paramètre est activé, les utilisateurs pourront lancer l'application Eche, par exemple en cliquant sur une notification Phone Hub. + + S'il est désactivé, ils ne pourront pas lancer cette application. + + Si cette règle n'est pas définie, le comportement par défaut sera autorisé pour les utilisateurs gérés par une entreprise et pour les utilisateurs non gérés.</translation> <translation id="6641981670621198190">Désactiver la prise en charge des API 3D graphics</translation> <translation id="6642682198621199507">Cette règle permet d'établir la liste des sites automatiquement autorisés à accéder à tous les ports série disponibles.
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb index bb76ee7..3fd616f 100644 --- a/components/policy/resources/policy_templates_id.xtb +++ b/components/policy/resources/policy_templates_id.xtb
@@ -2604,6 +2604,7 @@ <translation id="3964298692570794635">Izinkan konten tidak aman di situs ini</translation> <translation id="3965339130942650562">Waktu tunggu sampai proses keluar pengguna nganggur dieksekusi</translation> <translation id="396536755218079668">Pengguna yang dilindungi</translation> +<translation id="3968218878014278212">Mengizinkan Eche diaktifkan.</translation> <translation id="3971673686578912106">Jika kebijakan disetel ke Aktif, <ph name="PLUGIN_VM_NAME" /> akan diaktifkan untuk perangkat, selama setelan lainnya memungkinkan pengaktifan. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> dan <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" /> harus disetel ke Benar (True), dan <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> atau <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" /> harus disetel agar <ph name="PLUGIN_VM_NAME" /> dapat berjalan. Jika kebijakan disetel ke Nonaktif atau tidak disetel, <ph name="PLUGIN_VM_NAME" /> tidak akan diaktifkan untuk perangkat.</translation> @@ -3442,6 +3443,7 @@ Jika kebijakan ditetapkan ke Salah (False) atau tidak ditetapkan, <ph name="PRODUCT_NAME" /> akan menggunakan setelan pemeriksaan pencabutan online yang ada.</translation> <translation id="5078623750797048009">Mengaktifkan Anotasi PDF</translation> <translation id="5081204761483900654">Sesi tamu terkelola yang dibatasi</translation> +<translation id="5082296146261894974">Mengizinkan pengguna mengklik notifikasi Phone Hub untuk meluncurkan aplikasi Eche.</translation> <translation id="5082572440690475059">Izinkan akses baca melalui File System API di situs ini</translation> <translation id="5085647276663819155">Nonaktifkan Pratinjau Cetak</translation> <translation id="5090791951240382356">Mengizinkan penggabungan kebijakan kamus dari sumber berbeda</translation> @@ -4198,6 +4200,7 @@ Kolom <ph name="RUN_ON_OS_LOGIN_FIELD" /> menentukan apakah aplikasi web dapat dijalankan selama login OS. Jika kolom ini disetel ke <ph name="BLOCKED" />, aplikasi web tidak akan dijalankan selama login OS dan pengguna tidak akan dapat mengaktifkannya nanti. Jika kolom ini disetel ke <ph name="RUN_WINDOWED" />, aplikasi web akan dijalankan selama login OS dan pengguna tidak akan dapat menonaktifkannya nanti. Jika kolom ini disetel ke <ph name="ALLOWED" />, pengguna akan dapat mengonfigurasi aplikasi web untuk dijalankan saat login OS. Konfigurasi default hanya mengizinkan nilai <ph name="ALLOWED" /> dan <ph name="BLOCKED" />. </translation> +<translation id="5945312246863177268">Melarang pengguna mengklik notifikasi Phone Hub untuk meluncurkan aplikasi Eche.</translation> <translation id="5946082169633555022">Saluran beta</translation> <translation id="5946329690214660966">Menetapkan jadwal kustom untuk memeriksa update</translation> <translation id="5950069117106131681">Jika kebijakan disetel ke Aktif, header dan footer akan diaktifkan dalam pratinjau cetak. Jika kebijakan disetel ke Nonaktif, header dan footer akan dinonaktifkan dalam pratinjau cetak. @@ -4780,6 +4783,11 @@ <translation id="66265932317331474">Melaporkan info CPU</translation> <translation id="6628120204569232711">Laporkan status penyimpanan</translation> <translation id="663685822663765995">Batasi mode warna pencetakan</translation> +<translation id="6640355849038068978">Jika setelan ini diaktifkan, pengguna akan dapat meluncurkan aplikasi Eche, misalnya dengan mengklik notifikasi Phone Hub. + + Jika setelan ini dinonaktifkan, pengguna tidak akan dapat meluncurkan aplikasi Eche. + + Jika kebijakan ini tidak disetel, baik pengguna yang dikelola maupun tidak dikelola perusahaan akan diizinkan secara default.</translation> <translation id="6641981670621198190">Nonaktifkan dukungan untuk API grafis 3D</translation> <translation id="6642682198621199507">Menyetel kebijakan memungkinkan Anda menetapkan daftar situs yang otomatis diizinkan untuk mengakses semua port serial yang tersedia.
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb index 8792d0a..a30fdea 100644 --- a/components/policy/resources/policy_templates_ko.xtb +++ b/components/policy/resources/policy_templates_ko.xtb
@@ -2592,6 +2592,7 @@ <translation id="3964298692570794635">이 사이트에서 안전하지 않은 콘텐츠 허용</translation> <translation id="3965339130942650562">유휴 상태인 사용자의 로그아웃이 실행되기까지 시간 제한</translation> <translation id="396536755218079668">관리 대상 사용자</translation> +<translation id="3968218878014278212">Eche 사용을 허용합니다.</translation> <translation id="3971673686578912106">정책을 사용 설정하면 다른 설정에서도 허용하는 한 기기에서 <ph name="PLUGIN_VM_NAME" />이 사용 설정됩니다. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> 및 <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" />가 True로 설정되고 <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> 또는 <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />가 설정되어야 <ph name="PLUGIN_VM_NAME" />이 실행될 수 있습니다. 정책을 사용 중지하거나 설정하지 않으면 기기에서 <ph name="PLUGIN_VM_NAME" />이 사용 설정되지 않습니다.</translation> @@ -3428,6 +3429,7 @@ 정책을 False로 설정하거나 설정하지 않으면 <ph name="PRODUCT_NAME" />에서 기존 온라인 취소 확인 설정을 사용합니다.</translation> <translation id="5078623750797048009">PDF 주석 사용 설정</translation> <translation id="5081204761483900654">제한된 관리 게스트 세션</translation> +<translation id="5082296146261894974">사용자가 휴대전화 허브 알림을 클릭하여 Eche 애플리케이션을 실행하도록 허용합니다.</translation> <translation id="5082572440690475059">다음 사이트에서 File System API를 통한 읽기 액세스 허용</translation> <translation id="5085647276663819155">인쇄 미리보기 사용 안함</translation> <translation id="5090791951240382356">출처가 서로 다른 사전 정책의 병합 허용</translation> @@ -4184,6 +4186,7 @@ <ph name="RUN_ON_OS_LOGIN_FIELD" /> 필드는 OS 로그인 시 웹 앱의 실행 여부를 지정합니다. 필드가 <ph name="BLOCKED" />로 설정되면 OS 로그인 시 웹 앱이 실행되지 않으며 사용자가 나중에 run_on_os_login을 사용 설정할 수 없습니다. 필드가 <ph name="RUN_WINDOWED" />로 설정되면 OS 로그인 시 웹 앱이 실행되며 사용자가 나중에 run_on_os_login을 사용 중지할 수 없습니다. 필드가 <ph name="ALLOWED" />로 설정되면 사용자가 OS 로그인 시 웹 앱이 실행되도록 구성할 수 있습니다. 기본 구성에서는 <ph name="ALLOWED" /> 및 <ph name="BLOCKED" /> 값만 허용됩니다. </translation> +<translation id="5945312246863177268">사용자가 휴대전화 허브 알림을 클릭하여 Eche 애플리케이션을 실행하도록 허용하지 않습니다.</translation> <translation id="5946082169633555022">베타 채널</translation> <translation id="5946329690214660966">업데이트 확인을 위한 맞춤 일정 설정</translation> <translation id="5950069117106131681">정책을 사용 설정하면 인쇄 미리보기에서 머리글과 바닥글이 사용 설정됩니다. 정책을 사용 중지하면 인쇄 미리보기에서 머리글과 바닥글이 사용 중지됩니다. @@ -4766,6 +4769,11 @@ <translation id="66265932317331474">CPU 정보 보고</translation> <translation id="6628120204569232711">저장용량 상태 보고</translation> <translation id="663685822663765995">컬러 인쇄 모드 제한</translation> +<translation id="6640355849038068978">설정을 사용하면 사용자가 예를 들어 휴대전화 허브 알림을 클릭하여 Eche 애플리케이션을 실행할 수 있습니다. + + 설정을 사용 중지하면 사용자가 Eche 애플리케이션을 실행할 수 없습니다. + + 정책을 설정하지 않는 경우 기본값은 엔터프라이즈 관리 사용자 및 관리되지 않는 사용자 모두의 애플리케이션 실행을 허용하는 것입니다.</translation> <translation id="6641981670621198190">3D 그래픽 API 지원 사용 중지</translation> <translation id="6642682198621199507">정책을 설정하면 사용 가능한 모든 직렬 포트에 대한 액세스 권한을 자동으로 부여받는 사이트의 목록을 작성할 수 있습니다.
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb index a45fbdc..f9ba9876 100644 --- a/components/policy/resources/policy_templates_tr.xtb +++ b/components/policy/resources/policy_templates_tr.xtb
@@ -2588,6 +2588,7 @@ <translation id="3964298692570794635">Bu sitelerde güvenli olmayan içeriğe izin ver</translation> <translation id="3965339130942650562">Boştaki kullanıcının çıkış yapması için geçecek zaman aşımı süresi</translation> <translation id="396536755218079668">Denetlenen kullanıcılar</translation> +<translation id="3968218878014278212">Eche uygulamasının etkinleştirilmesine izin ver.</translation> <translation id="3971673686578912106">Politika, Etkin değerine ayarlanırsa diğer ayarlar izin verdiği sürece cihaz için <ph name="PLUGIN_VM_NAME" /> açılır. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> ile <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" /> Doğru değerine ayarlanmalı ve <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> veya <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />, <ph name="PLUGIN_VM_NAME" /> adlı sanal makinenin çalışması için ayarlanmalıdır. Politika, Devre Dışı değerine ayarlanır veya ayarlanmadan bırakılırsa <ph name="PLUGIN_VM_NAME" /> cihaz için açık değildir.</translation> @@ -3423,6 +3424,7 @@ Uygulamayı False (Yanlış) değerine ayarlamak veya ayarlamadan bırakmak, <ph name="PRODUCT_NAME" /> ürününün mevcut online iptal kontrolü ayarlarını kullanacağı anlamına gelir.</translation> <translation id="5078623750797048009">PDF Ek Açıklamalarını etkinleştir</translation> <translation id="5081204761483900654">Kısıtlanmış yönetilen misafir oturumları</translation> +<translation id="5082296146261894974">Kullanıcıların Eche uygulamasını başlatmak için Telefon Merkezi bildirimini tıklamasına izin verir.</translation> <translation id="5082572440690475059">Bu sitelerde File System API üzerinden okuma erişimine izin ver</translation> <translation id="5085647276663819155">Baskı Önizlemeyi Devre Dışı Bırak</translation> <translation id="5090791951240382356">Farklı kaynaklara ait sözlük politikalarını birleştirmeye izin ver</translation> @@ -4166,6 +4168,7 @@ <ph name="RUN_ON_OS_LOGIN_FIELD" /> alanı, OS girişi sırasında bir web uygulamasının çalıştırılıp çalıştırılamayacağını belirtir. Bu alan, <ph name="BLOCKED" /> değerine ayarlanırsa OS girişi sırasında web uygulaması çalıştırılmaz. Kullanıcı, bu ayarı daha sonra etkinleştiremez. Bu alan, <ph name="RUN_WINDOWED" /> değerine ayarlanırsa OS girişi sırasında web uygulaması çalıştırılır. Kullanıcı, bu ayarı daha sonra devre dışı bırakamaz. Bu alan, <ph name="ALLOWED" /> değerine ayarlanırsa kullanıcı, OS girişi sırasında web uygulamasını çalışacak şekilde yapılandırabilir. Varsayılan yapılandırma, yalnızca <ph name="ALLOWED" /> ve <ph name="BLOCKED" /> değerlerine izin verir. </translation> +<translation id="5945312246863177268">Kullanıcıların Eche uygulamasını başlatmak için Telefon Merkezi bildirimini tıklamasına izin vermez.</translation> <translation id="5946082169633555022">Beta kanalı</translation> <translation id="5946329690214660966">Güncellemeleri kontrol etmek için özel bir program belirle</translation> <translation id="5950069117106131681">Politika, Etkin değerine ayarlanırsa baskı önizlemede üst bilgiler ve alt bilgiler etkinleştirilir. Politika, Devre Dışı değerine ayarlanırsa bunlar baskı önizlemede devre dışı bırakılır. @@ -4731,6 +4734,11 @@ <translation id="66265932317331474">CPU bilgisi raporlama</translation> <translation id="6628120204569232711">Depolama durumunu bildir</translation> <translation id="663685822663765995">Renkli yazdırma modunu kısıtla</translation> +<translation id="6640355849038068978">Bu ayar etkinleştirilirse kullanıcılar örneğin bir Telefon Merkezi bildirimini tıklayarak Eche uygulamasını başlatabilir. + + Bu ayar devre dışı bırakılırsa kullanıcılar Eche uygulamasını başlatamaz. + + Bu politika ayarlanmadan bırakılırsa hem kurumsal olarak yönetilen kullanıcılar hem de yönetilmeyen kullanıcılar için varsayılana izin verilir.</translation> <translation id="6641981670621198190">3D grafik API'ları için desteği devre dışı bırak</translation> <translation id="6642682198621199507">Politikanın ayarlanması, kullanılabilen tüm seri bağlantı noktalarına erişmesine otomatik olarak izin verilen sitelerin listesini oluşturmanıza olanak tanır.
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb index d029f1cc..469f7fe 100644 --- a/components/policy/resources/policy_templates_vi.xtb +++ b/components/policy/resources/policy_templates_vi.xtb
@@ -2593,6 +2593,7 @@ <translation id="3964298692570794635">Cho phép nội dung không an toàn trên các trang web này</translation> <translation id="3965339130942650562">Thời gian chờ cho tới khi đăng xuất của người dùng không hoạt động được thực thi</translation> <translation id="396536755218079668">Người dùng được giám sát</translation> +<translation id="3968218878014278212">Cho phép bật Eche.</translation> <translation id="3971673686578912106">Khi bạn đặt chính sách này thành Bật, <ph name="PLUGIN_VM_NAME" /> sẽ bật cho thiết bị, với điều kiện là các tùy chọn cài đặt khác cũng cho phép chính sách này. Bạn phải đặt <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> và <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" /> thành Bật, đồng thời đặt <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> hoặc <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" /> để <ph name="PLUGIN_VM_NAME" /> có thể chạy. Nếu bạn đặt thành Tắt hoặc không đặt chính sách này, <ph name="PLUGIN_VM_NAME" /> sẽ không bật cho thiết bị.</translation> @@ -3431,6 +3432,7 @@ Nếu bạn đặt chính sách này thành False hoặc không đặt chính sách này, thì <ph name="PRODUCT_NAME" /> sẽ sử dụng tùy chọn kiểm tra trạng thái thu hồi trực tuyến hiện có.</translation> <translation id="5078623750797048009">Cho phép chú thích trong tệp PDF</translation> <translation id="5081204761483900654">Các phiên khách được quản lý và bị hạn chế</translation> +<translation id="5082296146261894974">Cho phép người dùng nhấp vào thông báo trong Trung tâm điều khiển điện thoại để chạy ứng dụng Eche.</translation> <translation id="5082572440690475059">Cho phép quyền đọc qua API Hệ thống tệp trên các trang web này</translation> <translation id="5085647276663819155">Vô hiệu hóa xem trước bản in</translation> <translation id="5090791951240382356">Cho phép hợp nhất các chính sách từ điển thuộc các nguồn khác nhau</translation> @@ -4188,6 +4190,7 @@ Trường <ph name="RUN_ON_OS_LOGIN_FIELD" /> sẽ chỉ định xem có thể chạy một ứng dụng web trong quá trình đăng nhập vào hệ điều hành hay không. Nếu bạn đặt trường này thành <ph name="BLOCKED" />, ứng dụng web sẽ không chạy trong quá trình đăng nhập vào hệ điều hành và sau này, người dùng sẽ không thể bật ứng dụng này. Nếu bạn đặt trường này thành <ph name="RUN_WINDOWED" />, ứng dụng web sẽ chạy trong quá trình đăng nhập vào hệ điều hành và sau này, người dùng sẽ không thể tắt ứng dụng này. Nếu bạn đặt trường này thành <ph name="ALLOWED" />, người dùng sẽ có thể định cấu hình chạy ứng dụng web khi đăng nhập vào hệ điều hành. Cấu hình mặc định chỉ cho phép các giá trị <ph name="ALLOWED" /> và <ph name="BLOCKED" />. </translation> +<translation id="5945312246863177268">Không cho phép người dùng nhấp vào thông báo trong Trung tâm điều khiển điện thoại để mở ứng dụng Eche.</translation> <translation id="5946082169633555022">Kênh beta</translation> <translation id="5946329690214660966">Đặt lịch biểu tùy chỉnh để kiểm tra bản cập nhật</translation> <translation id="5950069117106131681">Nếu bạn đặt chính sách này thành Bật, đầu trang và chân trang ở chế độ xem trước bản in sẽ được bật. Nếu bạn đặt chính sách này thành Tắt, đầu trang và chân trang ở chế độ xem trước bản in sẽ bị tắt. @@ -4769,6 +4772,11 @@ <translation id="66265932317331474">Báo cáo thông tin CPU</translation> <translation id="6628120204569232711">Báo cáo trạng thái bộ nhớ</translation> <translation id="663685822663765995">Hạn chế chế độ in màu</translation> +<translation id="6640355849038068978">Nếu chế độ cài đặt này đang bật, người dùng sẽ mở được ứng dụng Eche, chẳng hạn như bằng cách nhấp vào thông báo trong Trung tâm điều khiển điện thoại. + + Nếu chế độ cài đặt này đang tắt, người dùng sẽ không mở được ứng dụng Eche. + + Nếu bạn không thiết lập chính sách này, thì chế độ mặc định sẽ là cho phép cả người dùng do doanh nghiệp quản lý và người dùng không được quản lý.</translation> <translation id="6641981670621198190">Tắt hỗ trợ dành cho API đồ họa 3D</translation> <translation id="6642682198621199507">Nếu bạn đặt chính sách này, thì bạn có thể thiết lập danh sách các trang web được hệ thống tự động cấp quyền truy cập vào tất cả các cổng nối tiếp có sẵn.
diff --git a/components/prefs/pref_notifier_impl.cc b/components/prefs/pref_notifier_impl.cc index 1f012bc..a6001cacd 100644 --- a/components/prefs/pref_notifier_impl.cc +++ b/components/prefs/pref_notifier_impl.cc
@@ -48,9 +48,7 @@ // For DbusAppmenu, crbug.com/946668 pref_name == "bookmark_bar.show_on_all_tabs" || // For BrowserWindowPropertyManager, crbug.com/942491 - pref_name == "profile.icon_version" || - // For BrowserWindowDefaultTouchBar, crbug.com/945772 - pref_name == "default_search_provider_data.template_url_data") { + pref_name == "profile.icon_version") { base::debug::DumpWithoutCrashing(); } }
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h index 9023692..6726344 100644 --- a/components/printing/renderer/print_render_frame_helper.h +++ b/components/printing/renderer/print_render_frame_helper.h
@@ -36,12 +36,8 @@ // http://crbug.com/187500 #if defined(OS_ANDROID) #define MAYBE_PrintRenderFrameHelperTest DISABLED_PrintRenderFrameHelperTest -#define MAYBE_PrintRenderFrameHelperPreviewTest \ - DISABLED_PrintRenderFrameHelperPreviewTest #else #define MAYBE_PrintRenderFrameHelperTest PrintRenderFrameHelperTest -#define MAYBE_PrintRenderFrameHelperPreviewTest \ - PrintRenderFrameHelperPreviewTest #endif // defined(OS_ANDROID) namespace base { @@ -167,8 +163,9 @@ const mojo::AssociatedRemote<mojom::PrintManagerHost>& GetPrintManagerHost(); private: + friend class PrintRenderFrameHelperPreviewTest; friend class PrintRenderFrameHelperTestBase; - FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintRenderFrameHelperPreviewTest, + FRIEND_TEST_ALL_PREFIXES(PrintRenderFrameHelperPreviewTest, BlockScriptInitiatedPrinting); FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintRenderFrameHelperTest, PrintRequestedPages);
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc index 8ab0b644..cf44f23c 100644 --- a/components/printing/test/print_render_frame_helper_browsertest.cc +++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -118,28 +118,6 @@ // A web page to simulate the print preview page. const char kPrintPreviewHTML[] = "<body><p id=\"pdf-viewer\">Hello World!</p></body>"; - -void CreatePrintSettingsDictionary(base::DictionaryValue* dict) { - dict->SetBoolean(kSettingLandscape, false); - dict->SetBoolean(kSettingCollate, false); - dict->SetInteger(kSettingColor, static_cast<int>(mojom::ColorModel::kGray)); - dict->SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kPdf)); - dict->SetInteger(kSettingDuplexMode, - static_cast<int>(mojom::DuplexMode::kSimplex)); - dict->SetInteger(kSettingCopies, 1); - dict->SetString(kSettingDeviceName, "dummy"); - dict->SetInteger(kPreviewUIID, 4); - dict->SetInteger(kPreviewRequestID, 12345); - dict->SetBoolean(kIsFirstRequest, true); - dict->SetInteger(kSettingMarginsType, - static_cast<int>(mojom::MarginType::kDefaultMargins)); - dict->SetBoolean(kSettingPreviewModifiable, true); - dict->SetBoolean(kSettingPreviewIsFromArc, false); - dict->SetBoolean(kSettingHeaderFooterEnabled, false); - dict->SetBoolean(kSettingShouldPrintBackgrounds, false); - dict->SetBoolean(kSettingShouldPrintSelectionOnly, false); -} #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) #endif // !BUILDFLAG(IS_CHROMEOS_ASH) @@ -205,7 +183,7 @@ void DidPreviewPage(mojom::DidPreviewPageParamsPtr params, int32_t request_id) override { uint32_t page_number = params->page_number; - DCHECK_NE(page_number, printing::kInvalidPageIndex); + DCHECK_NE(page_number, kInvalidPageIndex); print_preview_pages_remaining_--; print_preview_pages_.emplace_back( params->page_number, params->content->metafile_data_region.GetSize()); @@ -268,7 +246,7 @@ bool has_custom_page_size_style_ = false; // Simulates cancelling print preview if |print_preview_pages_remaining_| // equals this. - uint32_t print_preview_cancel_page_number_ = printing::kInvalidPageIndex; + uint32_t print_preview_cancel_page_number_ = kInvalidPageIndex; mojom::PageSizeMarginsPtr page_layout_; mojom::DidPreviewDocumentParamsPtr did_preview_document_params_; // Number of pages to generate for print preview. @@ -333,41 +311,38 @@ // Check and make sure the required settings are all there. // We don't actually care about the values. absl::optional<int> margins_type = - job_settings.FindIntKey(printing::kSettingMarginsType); + job_settings.FindIntKey(kSettingMarginsType); if (!margins_type.has_value() || - !job_settings.FindBoolKey(printing::kSettingLandscape) || - !job_settings.FindBoolKey(printing::kSettingCollate) || - !job_settings.FindIntKey(printing::kSettingColor) || - !job_settings.FindIntKey(printing::kSettingPrinterType) || - !job_settings.FindBoolKey(printing::kIsFirstRequest) || - !job_settings.FindStringKey(printing::kSettingDeviceName) || - !job_settings.FindIntKey(printing::kSettingDuplexMode) || - !job_settings.FindIntKey(printing::kSettingCopies) || - !job_settings.FindIntKey(printing::kPreviewUIID) || - !job_settings.FindIntKey(printing::kPreviewRequestID)) { + !job_settings.FindBoolKey(kSettingLandscape) || + !job_settings.FindBoolKey(kSettingCollate) || + !job_settings.FindIntKey(kSettingColor) || + !job_settings.FindIntKey(kSettingPrinterType) || + !job_settings.FindBoolKey(kIsFirstRequest) || + !job_settings.FindStringKey(kSettingDeviceName) || + !job_settings.FindIntKey(kSettingDuplexMode) || + !job_settings.FindIntKey(kSettingCopies) || + !job_settings.FindIntKey(kPreviewUIID) || + !job_settings.FindIntKey(kPreviewRequestID)) { std::move(callback).Run(std::move(params), canceled); return; } // Just return the default settings. - const base::Value* page_range = - job_settings.FindListKey(printing::kSettingPageRange); - printing::PageRanges new_ranges; + const base::Value* page_range = job_settings.FindListKey(kSettingPageRange); + PageRanges new_ranges; if (page_range) { for (const base::Value& dict : page_range->GetList()) { if (!dict.is_dict()) continue; - absl::optional<int> range_from = - dict.FindIntKey(printing::kSettingPageRangeFrom); - absl::optional<int> range_to = - dict.FindIntKey(printing::kSettingPageRangeTo); + absl::optional<int> range_from = dict.FindIntKey(kSettingPageRangeFrom); + absl::optional<int> range_to = dict.FindIntKey(kSettingPageRangeTo); if (!range_from || !range_to) continue; // Page numbers are 1-based in the dictionary. // Page numbers are 0-based for the printing context. - printing::PageRange range; + PageRange range; range.from = range_from.value() - 1; range.to = range_to.value() - 1; new_ranges.push_back(range); @@ -376,18 +351,17 @@ // Get media size const base::Value* media_size_value = - job_settings.FindDictKey(printing::kSettingMediaSize); + job_settings.FindDictKey(kSettingMediaSize); gfx::Size page_size; if (media_size_value) { absl::optional<int> width_microns = - media_size_value->FindIntKey(printing::kSettingMediaSizeWidthMicrons); - absl::optional<int> height_microns = media_size_value->FindIntKey( - printing::kSettingMediaSizeHeightMicrons); + media_size_value->FindIntKey(kSettingMediaSizeWidthMicrons); + absl::optional<int> height_microns = + media_size_value->FindIntKey(kSettingMediaSizeHeightMicrons); if (width_microns && height_microns) { float device_microns_per_unit = - static_cast<float>(printing::kMicronsPerInch) / - printing::kDefaultPdfDpi; + static_cast<float>(kMicronsPerInch) / kDefaultPdfDpi; page_size = gfx::Size(width_microns.value() / device_microns_per_unit, height_microns.value() / device_microns_per_unit); } @@ -395,16 +369,16 @@ // Get scaling absl::optional<int> setting_scale_factor = - job_settings.FindIntKey(printing::kSettingScaleFactor); + job_settings.FindIntKey(kSettingScaleFactor); int scale_factor = setting_scale_factor.value_or(100); - std::vector<uint32_t> pages(printing::PageRange::GetPages(new_ranges)); + std::vector<uint32_t> pages(PageRange::GetPages(new_ranges)); printer_->UpdateSettings(cookie, params.get(), pages, margins_type.value(), page_size, scale_factor); absl::optional<bool> selection_only = - job_settings.FindBoolKey(printing::kSettingShouldPrintSelectionOnly); + job_settings.FindBoolKey(kSettingShouldPrintSelectionOnly); absl::optional<bool> should_print_backgrounds = - job_settings.FindBoolKey(printing::kSettingShouldPrintBackgrounds); + job_settings.FindBoolKey(kSettingShouldPrintBackgrounds); params->params->selection_only = selection_only.value(); params->params->should_print_backgrounds = should_print_backgrounds.value(); std::move(callback).Run(std::move(params), canceled); @@ -543,22 +517,6 @@ base::RunLoop().RunUntilIdle(); } -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void BindToFakePrintPreviewUI() { - PrintRenderFrameHelper* frame_helper = GetPrintRenderFrameHelper(); - frame_helper->SetPrintPreviewUI(preview_ui_->BindReceiver()); - } - - void WaitForPreviewMessages() { preview_ui()->WaitUntilPreviewUpdate(); } - - // The renderer should be done calculating the number of rendered pages - // according to the specified settings defined in the mock render thread. - // Verify the page count is correct. - void VerifyPreviewPageCount(uint32_t expected_count) { - EXPECT_EQ(expected_count, preview_ui()->page_count()); - } -#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Verifies whether the pages printed or not. void VerifyPagesPrinted(bool expect_printed, content::RenderFrame* render_frame = nullptr) { @@ -586,25 +544,6 @@ base::RunLoop().RunUntilIdle(); } -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void VerifyPreviewRequest(bool expect_request) { - EXPECT_EQ(expect_request, print_manager()->IsSetupScriptedPrintPreview()); - } - - void OnPrintPreview(const base::DictionaryValue& dict) { - PrintRenderFrameHelper* print_render_frame_helper = - GetPrintRenderFrameHelper(); - print_render_frame_helper->InitiatePrintPreview( - mojo::NullAssociatedRemote(), false); - print_render_frame_helper->PrintPreview(dict.Clone()); - WaitForPreviewMessages(); - } - - void OnClosePrintPreviewDialog() { - GetPrintRenderFrameHelper()->OnPrintPreviewDialogClosed(); - } -#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - PrintRenderFrameHelper* GetPrintRenderFrameHelper() { return PrintRenderFrameHelper::Get( content::RenderFrame::FromWebFrame(GetMainFrame())); @@ -974,33 +913,55 @@ // These print preview tests do not work on Chrome OS yet. #if !BUILDFLAG(IS_CHROMEOS_ASH) -// RenderViewTest-based tests crash on Android -// http://crbug.com/187500 -#if defined(OS_ANDROID) -#define MAYBE_PrintRenderFrameHelperPreviewTest \ - DISABLED_PrintRenderFrameHelperPreviewTest -#else -#define MAYBE_PrintRenderFrameHelperPreviewTest \ - PrintRenderFrameHelperPreviewTest -#endif // defined(OS_ANDROID) - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) -class MAYBE_PrintRenderFrameHelperPreviewTest +class PrintRenderFrameHelperPreviewTest : public PrintRenderFrameHelperTestBase { public: - MAYBE_PrintRenderFrameHelperPreviewTest() = default; - MAYBE_PrintRenderFrameHelperPreviewTest( - const MAYBE_PrintRenderFrameHelperPreviewTest&) = delete; - MAYBE_PrintRenderFrameHelperPreviewTest& operator=( - const MAYBE_PrintRenderFrameHelperPreviewTest&) = delete; - ~MAYBE_PrintRenderFrameHelperPreviewTest() override = default; + PrintRenderFrameHelperPreviewTest() = default; + PrintRenderFrameHelperPreviewTest(const PrintRenderFrameHelperPreviewTest&) = + delete; + PrintRenderFrameHelperPreviewTest& operator=( + const PrintRenderFrameHelperPreviewTest&) = delete; + ~PrintRenderFrameHelperPreviewTest() override = default; void SetUp() override { PrintRenderFrameHelperTestBase::SetUp(); BindToFakePrintPreviewUI(); + CreatePrintSettingsDictionary(); } protected: + void BindToFakePrintPreviewUI() { + PrintRenderFrameHelper* frame_helper = GetPrintRenderFrameHelper(); + frame_helper->SetPrintPreviewUI(preview_ui()->BindReceiver()); + } + + void OnPrintPreview() { + PrintRenderFrameHelper* print_render_frame_helper = + GetPrintRenderFrameHelper(); + print_render_frame_helper->InitiatePrintPreview( + mojo::NullAssociatedRemote(), false); + print_render_frame_helper->PrintPreview(print_settings_.Clone()); + WaitForPreviewMessages(); + } + + void OnClosePrintPreviewDialog() { + GetPrintRenderFrameHelper()->OnPrintPreviewDialogClosed(); + } + + void WaitForPreviewMessages() { preview_ui()->WaitUntilPreviewUpdate(); } + + void VerifyPreviewRequest(bool expect_request) { + EXPECT_EQ(expect_request, print_manager()->IsSetupScriptedPrintPreview()); + } + + // The renderer should be done calculating the number of rendered pages + // according to the specified settings defined in the mock render thread. + // Verify the page count is correct. + void VerifyPreviewPageCount(uint32_t expected_count) { + EXPECT_EQ(expected_count, preview_ui()->page_count()); + } + void VerifyPrintPreviewCancelled(bool expect_cancel) { EXPECT_EQ(expect_cancel, preview_ui()->PreviewCancelled()); } @@ -1060,9 +1021,39 @@ EXPECT_EQ(expected_page_has_print_css, preview_ui()->has_custom_page_size_style()); } + + base::Value& print_settings() { return print_settings_; } + + private: + void CreatePrintSettingsDictionary() { + print_settings_ = base::Value(base::Value::Type::DICTIONARY); + print_settings_.SetBoolKey(kSettingLandscape, false); + print_settings_.SetBoolKey(kSettingCollate, false); + print_settings_.SetIntKey(kSettingColor, + static_cast<int>(mojom::ColorModel::kGray)); + print_settings_.SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kPdf)); + print_settings_.SetIntKey(kSettingDuplexMode, + static_cast<int>(mojom::DuplexMode::kSimplex)); + print_settings_.SetIntKey(kSettingCopies, 1); + print_settings_.SetStringKey(kSettingDeviceName, "dummy"); + print_settings_.SetIntKey(kPreviewUIID, 4); + print_settings_.SetIntKey(kPreviewRequestID, 12345); + print_settings_.SetBoolKey(kIsFirstRequest, true); + print_settings_.SetIntKey( + kSettingMarginsType, + static_cast<int>(mojom::MarginType::kDefaultMargins)); + print_settings_.SetBoolKey(kSettingPreviewModifiable, true); + print_settings_.SetBoolKey(kSettingPreviewIsFromArc, false); + print_settings_.SetBoolKey(kSettingHeaderFooterEnabled, false); + print_settings_.SetBoolKey(kSettingShouldPrintBackgrounds, false); + print_settings_.SetBoolKey(kSettingShouldPrintSelectionOnly, false); + } + + base::Value print_settings_; }; -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, BlockScriptInitiatedPrinting) { +TEST_F(PrintRenderFrameHelperPreviewTest, BlockScriptInitiatedPrinting) { LoadHTML(kHelloWorldHTML); PrintRenderFrameHelper* print_render_frame_helper = GetPrintRenderFrameHelper(); @@ -1077,7 +1068,7 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintWithJavaScript) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintWithJavaScript) { LoadHTML(kPrintOnUserAction); gfx::Size new_size(200, 100); Resize(new_size, false); @@ -1092,13 +1083,10 @@ // Tests that print preview work and sending and receiving messages through // that channel all works. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, OnPrintPreview) { +TEST_F(PrintRenderFrameHelperPreviewTest, OnPrintPreview) { LoadHTML(kHelloWorldHTML); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1112,8 +1100,7 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - PrintPreviewHTMLWithPageMarginsCss) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewHTMLWithPageMarginsCss) { // A simple web page with print margins css. static const char kHTMLWithPageMarginsCss[] = "<html><head><style>" @@ -1127,12 +1114,9 @@ "</body></html>"; LoadHTML(kHTMLWithPageMarginsCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(519, 432, 216, 144, 21, 72, false); @@ -1148,18 +1132,15 @@ // Test to verify that print preview ignores print media css when non-default // margin is selected. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, +TEST_F(PrintRenderFrameHelperPreviewTest, NonDefaultMarginsSelectedIgnorePrintCss) { LoadHTML(kHTMLWithPageSizeCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - dict.SetInteger(kSettingMarginsType, - static_cast<int>(mojom::MarginType::kNoMargins)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + print_settings().SetIntKey(kSettingMarginsType, + static_cast<int>(mojom::MarginType::kNoMargins)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(612, 792, 0, 0, 0, 0, true); @@ -1175,16 +1156,13 @@ // Test to verify that print preview honor print media size css when // PRINT_TO_PDF is selected and doesn't fit to printer default paper size. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - PrintToPDFSelectedHonorPrintCss) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintToPDFSelectedHonorPrintCss) { LoadHTML(kHTMLWithPageSizeCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingMarginsType, - static_cast<int>(mojom::MarginType::kPrintableAreaMargins)); - OnPrintPreview(dict); + print_settings().SetIntKey( + kSettingMarginsType, + static_cast<int>(mojom::MarginType::kPrintableAreaMargins)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page @@ -1200,8 +1178,7 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - PreviewLayoutTriggeredByResize) { +TEST_F(PrintRenderFrameHelperPreviewTest, PreviewLayoutTriggeredByResize) { // A simple web page with print margins css. static const char kHTMLWithPageCss[] = "<!DOCTYPE html>" @@ -1306,12 +1283,9 @@ "</div>"; LoadHTML(kHTMLWithPageCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1327,7 +1301,7 @@ // Test to verify that print preview honor print margin css when PRINT_TO_PDF // is selected and doesn't fit to printer default paper size. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, +TEST_F(PrintRenderFrameHelperPreviewTest, PrintToPDFSelectedHonorPageMarginsCss) { // A simple web page with print margins css. static const char kHTMLWithPageCss[] = @@ -1343,10 +1317,7 @@ "</body></html>"; LoadHTML(kHTMLWithPageCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page @@ -1364,15 +1335,12 @@ // Test to verify that print preview workflow center the html page contents to // fit the page size. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewCenterToFitPage) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewCenterToFitPage) { LoadHTML(kHTMLWithPageSizeCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(216, 216, 288, 288, 198, 198, true); @@ -1388,7 +1356,7 @@ // Test to verify that print preview workflow scale the html page contents to // fit the page size. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewShrinkToFitPage) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewShrinkToFitPage) { // A simple web page with print margins css. static const char kHTMLWithPageCss[] = "<html><head><style>" @@ -1402,12 +1370,9 @@ "</body></html>"; LoadHTML(kHTMLWithPageCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(571, 652, 69, 71, 20, 21, true); @@ -1423,18 +1388,14 @@ // Test to verify that print preview workflow honor the orientation settings // specified in css. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - PrintPreviewHonorsOrientationCss) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewHonorsOrientationCss) { LoadHTML(kHTMLWithLandscapePageCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - dict.SetInteger(kSettingMarginsType, - static_cast<int>(mojom::MarginType::kNoMargins)); - OnPrintPreview(dict); + print_settings().SetIntKey(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); + print_settings().SetIntKey(kSettingMarginsType, + static_cast<int>(mojom::MarginType::kNoMargins)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(792, 612, 0, 0, 0, 0, true); @@ -1450,16 +1411,13 @@ // Test to verify that print preview workflow honors the orientation settings // specified in css when PRINT_TO_PDF is selected. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, +TEST_F(PrintRenderFrameHelperPreviewTest, PrintToPDFSelectedHonorOrientationCss) { LoadHTML(kHTMLWithLandscapePageCss); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetInteger(kSettingMarginsType, - static_cast<int>(mojom::MarginType::kCustomMargins)); - OnPrintPreview(dict); + print_settings().SetIntKey( + kSettingMarginsType, static_cast<int>(mojom::MarginType::kCustomMargins)); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDefaultPageLayout(748, 568, 21, 23, 21, 23, true); @@ -1473,14 +1431,10 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewForMultiplePages) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewForMultiplePages) { LoadHTML(kMultipageHTML); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1495,13 +1449,9 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedPages) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedPages) { LoadHTML(kMultipageHTML); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - // Set a page range and update the dictionary to generate only the complete // metafile with the selected pages. Page numbers used in the dictionary // are 1-based. @@ -1510,9 +1460,9 @@ page_range.SetKey(kSettingPageRangeTo, base::Value(3)); base::Value page_range_array(base::Value::Type::LIST); page_range_array.Append(std::move(page_range)); - dict.SetKey(kSettingPageRange, std::move(page_range_array)); + print_settings().SetKey(kSettingPageRange, std::move(page_range_array)); - OnPrintPreview(dict); + OnPrintPreview(); // The expected page count below is 3 because the total number of pages in the // document, without the page range, is 3. Since only 2 pages have been @@ -1533,18 +1483,15 @@ } // Test to verify that preview generated only for one page. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedText) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedText) { LoadHTML(kMultipageHTML); GetMainFrame()->SelectRange(blink::WebRange(1, 3), blink::WebLocalFrame::kHideSelectionHandle, blink::mojom::SelectionMenuBehavior::kHide); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetBoolean(kSettingShouldPrintSelectionOnly, true); + print_settings().SetBoolKey(kSettingShouldPrintSelectionOnly, true); - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1558,18 +1505,15 @@ } // Test to verify that preview generated only for two pages. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedText2) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedText2) { LoadHTML(kMultipageHTML); GetMainFrame()->SelectRange(blink::WebRange(1, 8), blink::WebLocalFrame::kHideSelectionHandle, blink::mojom::SelectionMenuBehavior::kHide); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - dict.SetBoolean(kSettingShouldPrintSelectionOnly, true); + print_settings().SetBoolKey(kSettingShouldPrintSelectionOnly, true); - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1583,15 +1527,13 @@ } // Tests that cancelling print preview works. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewCancel) { +TEST_F(PrintRenderFrameHelperPreviewTest, PrintPreviewCancel) { LoadHTML(kLongPageHTML); const uint32_t kCancelPage = 3; preview_ui()->set_print_preview_cancel_page_number(kCancelPage); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + + OnPrintPreview(); EXPECT_EQ(kCancelPage, preview_ui()->print_preview_pages_remaining()); VerifyPrintPreviewCancelled(true); @@ -1604,17 +1546,14 @@ // Tests that when default printer has invalid printer settings, print preview // receives error message. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, +TEST_F(PrintRenderFrameHelperPreviewTest, OnPrintPreviewUsingInvalidPrinterSettings) { LoadHTML(kPrintPreviewHTML); // Set mock printer to provide invalid settings. printer()->UseInvalidSettings(); - // Fill in some dummy values. - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); // We should have received invalid printer settings from |printer_|. VerifyPrintPreviewInvalidPrinterSettings(true); @@ -1629,15 +1568,12 @@ // Tests that when the selected printer has invalid page settings, print preview // receives error message. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - OnPrintPreviewUsingInvalidPageSize) { +TEST_F(PrintRenderFrameHelperPreviewTest, OnPrintPreviewUsingInvalidPageSize) { LoadHTML(kPrintPreviewHTML); printer()->UseInvalidPageSize(); - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); VerifyPrintPreviewInvalidPrinterSettings(true); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); @@ -1651,15 +1587,13 @@ // Tests that when the selected printer has invalid content settings, print // preview receives error message. -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, +TEST_F(PrintRenderFrameHelperPreviewTest, OnPrintPreviewUsingInvalidContentSize) { LoadHTML(kPrintPreviewHTML); printer()->UseInvalidContentSize(); - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); VerifyPrintPreviewInvalidPrinterSettings(true); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); @@ -1671,13 +1605,11 @@ OnClosePrintPreviewDialog(); } -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, BasicBeforePrintAfterPrint) { +TEST_F(PrintRenderFrameHelperPreviewTest, BasicBeforePrintAfterPrint) { LoadHTML(kBeforeAfterPrintHtml); ExpectNoBeforeNoAfterPrintEvent(); - base::DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - OnPrintPreview(dict); + OnPrintPreview(); EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); VerifyDidPreviewPage(true, 0); @@ -1694,8 +1626,7 @@ } // Regression test for https://crbug.com/912966 -TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, - WindowPrintBeforePrintAfterPrint) { +TEST_F(PrintRenderFrameHelperPreviewTest, WindowPrintBeforePrintAfterPrint) { LoadHTML(kBeforeAfterPrintHtml); gfx::Size new_size(200, 100); Resize(new_size, false);
diff --git a/components/reporting/proto/synced/metric_data.proto b/components/reporting/proto/synced/metric_data.proto index 17f0188..33dbe00 100644 --- a/components/reporting/proto/synced/metric_data.proto +++ b/components/reporting/proto/synced/metric_data.proto
@@ -277,6 +277,8 @@ optional NetworksTelemetry networks_telemetry = 1; // Audio telemetry data. optional AudioTelemetry audio_telemetry = 2; + // Usb telemetry data + optional UsbTelemetry usb_telemetry = 3; } enum MetricEventType { @@ -289,15 +291,15 @@ USB_REMOVED = 6; } -message UsbEventData { +message UsbTelemetry { // Vendor name optional string vendor = 1; // Device name, model name, or product name optional string name = 2; // Vendor ID - optional int64 vid = 3; + optional int32 vid = 3; // Product ID - optional int64 pid = 4; + optional int32 pid = 4; // List of names of USB categories the device falls under // https://www.usb.org/defined-class-codes repeated string categories = 5; @@ -307,7 +309,6 @@ // associated with the event will be reported as TelemetryData. message EventData { optional MetricEventType type = 1; - optional UsbEventData usb_event_data = 2; } // Main message to be reported, can contain `InfoData`, `TelemetryData`, or
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn index 9e7762f6..9f53dc8d 100644 --- a/components/safe_browsing/content/browser/BUILD.gn +++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -52,6 +52,7 @@ "//components/safe_browsing/core/browser:safe_browsing_metrics_collector", "//components/safe_browsing/core/common", "//components/safe_browsing/core/common:safe_browsing_prefs", + "//components/safe_browsing/core/common/proto:csd_proto", "//components/security_interstitials/content:security_interstitial_page", "//components/security_interstitials/core", "//components/security_interstitials/core:unsafe_resource",
diff --git a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc index 48b340fc..124f0e7 100644 --- a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc +++ b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc
@@ -76,6 +76,8 @@ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool should_trigger_reporting, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, SafeBrowsingNavigationObserverManager* navigation_observer_manager, SafeBrowsingMetricsCollector* metrics_collector, TriggerManager* trigger_manager, @@ -89,6 +91,7 @@ threat_details_in_progress_(false), threat_source_(unsafe_resources[0].threat_source), history_service_(history_service), + get_user_population_callback_(get_user_population_callback), navigation_observer_manager_(navigation_observer_manager), metrics_collector_(metrics_collector), trigger_manager_(trigger_manager) { @@ -123,7 +126,7 @@ trigger_manager_->StartCollectingThreatDetails( TriggerType::SECURITY_INTERSTITIAL, web_contents, unsafe_resources[0], url_loader_factory, history_service_, - navigation_observer_manager_, + get_user_population_callback_, navigation_observer_manager_, sb_error_ui()->get_error_display_options()); } }
diff --git a/components/safe_browsing/content/browser/safe_browsing_blocking_page.h b/components/safe_browsing/content/browser/safe_browsing_blocking_page.h index 644b7bb..e973230 100644 --- a/components/safe_browsing/content/browser/safe_browsing_blocking_page.h +++ b/components/safe_browsing/content/browser/safe_browsing_blocking_page.h
@@ -34,6 +34,7 @@ #include "base/memory/raw_ptr.h" #include "components/safe_browsing/content/browser/base_blocking_page.h" #include "components/safe_browsing/content/browser/base_ui_manager.h" +#include "components/safe_browsing/core/common/proto/csd.pb.h" namespace history { class HistoryService; @@ -111,6 +112,8 @@ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool should_trigger_reporting, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, SafeBrowsingNavigationObserverManager* navigation_observer_manager, SafeBrowsingMetricsCollector* metrics_collector, TriggerManager* trigger_manager, @@ -137,6 +140,7 @@ private: raw_ptr<history::HistoryService> history_service_ = nullptr; + base::RepeatingCallback<ChromeUserPopulation()> get_user_population_callback_; raw_ptr<SafeBrowsingNavigationObserverManager> navigation_observer_manager_ = nullptr; raw_ptr<SafeBrowsingMetricsCollector> metrics_collector_ = nullptr;
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc index 4f25e84..3444ebd2 100644 --- a/components/safe_browsing/content/browser/threat_details.cc +++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -330,6 +330,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) override { @@ -338,8 +340,8 @@ // used. auto threat_details = base::WrapUnique(new ThreatDetails( ui_manager, web_contents, unsafe_resource, url_loader_factory, - history_service, referrer_chain_provider, trim_to_ad_tags, - std::move(done_callback))); + history_service, get_user_population_callback, referrer_chain_provider, + trim_to_ad_tags, std::move(done_callback))); threat_details->StartCollection(); return threat_details; } @@ -361,6 +363,8 @@ const UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) { @@ -370,7 +374,8 @@ factory_ = g_threat_details_factory_impl.Pointer(); return factory_->CreateThreatDetails( ui_manager, web_contents, resource, url_loader_factory, history_service, - referrer_chain_provider, trim_to_ad_tags, std::move(done_callback)); + get_user_population_callback, referrer_chain_provider, trim_to_ad_tags, + std::move(done_callback)); } // Create a ThreatDetails for the given tab. Runs in the UI thread. @@ -380,6 +385,8 @@ const UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) @@ -388,6 +395,7 @@ ui_manager_(ui_manager), browser_context_(web_contents->GetBrowserContext()), resource_(resource), + get_user_population_callback_(get_user_population_callback), referrer_chain_provider_(referrer_chain_provider), cache_result_(false), did_proceed_(false), @@ -665,16 +673,20 @@ pending_render_frame_hosts_.push_back(frame); raw_threat_report->GetThreatDOMDetails( base::BindOnce(&ThreatDetails::OnReceivedThreatDOMDetails, GetWeakPtr(), - std::move(threat_reporter), frame)); + std::move(threat_reporter), frame->GetGlobalId())); } // When the renderer is done, this is called. void ThreatDetails::OnReceivedThreatDOMDetails( mojo::Remote<mojom::ThreatReporter> threat_reporter, - content::RenderFrameHost* sender, + content::GlobalRenderFrameHostId sender_id, std::vector<mojom::ThreatDOMDetailsNodePtr> params) { // If the RenderFrameHost was closed between sending the IPC and this callback // running, |sender| will be invalid. + auto* sender = content::RenderFrameHost::FromID(sender_id); + if (!sender) { + return; + } const auto sender_it = std::find(pending_render_frame_hosts_.begin(), pending_render_frame_hosts_.end(), sender); if (sender_it == pending_render_frame_hosts_.end()) { @@ -851,6 +863,10 @@ report_->mutable_client_properties()->set_url_api_type( GetUrlApiTypeForThreatSource(resource_.threat_source)); + if (!get_user_population_callback_.is_null()) { + *report_->mutable_population() = get_user_population_callback_.Run(); + } + // Fill the referrer chain if applicable. MaybeFillReferrerChain();
diff --git a/components/safe_browsing/content/browser/threat_details.h b/components/safe_browsing/content/browser/threat_details.h index a2700ddf8..f1f9b25 100644 --- a/components/safe_browsing/content/browser/threat_details.h +++ b/components/safe_browsing/content/browser/threat_details.h
@@ -24,6 +24,7 @@ #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" #include "mojo/public/cpp/bindings/remote.h" @@ -86,6 +87,8 @@ const UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback); @@ -126,6 +129,8 @@ const UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback); @@ -172,7 +177,7 @@ void OnReceivedThreatDOMDetails( mojo::Remote<mojom::ThreatReporter> threat_reporter, - content::RenderFrameHost* sender, + content::GlobalRenderFrameHostId sender_id, std::vector<mojom::ThreatDOMDetailsNodePtr> params); void AddRedirectUrlList(const std::vector<GURL>& urls); @@ -206,6 +211,8 @@ const UnsafeResource resource_; + base::RepeatingCallback<ChromeUserPopulation()> get_user_population_callback_; + raw_ptr<ReferrerChainProvider> referrer_chain_provider_; // For every Url we collect we create a Resource message. We keep @@ -300,6 +307,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) = 0;
diff --git a/components/safe_browsing/content/browser/triggers/BUILD.gn b/components/safe_browsing/content/browser/triggers/BUILD.gn index b7cef3ac..d1447798 100644 --- a/components/safe_browsing/content/browser/triggers/BUILD.gn +++ b/components/safe_browsing/content/browser/triggers/BUILD.gn
@@ -63,6 +63,7 @@ "//base:base", "//components/safe_browsing/core/browser:referrer_chain_provider", "//components/safe_browsing/core/common", + "//components/safe_browsing/core/common/proto:csd_proto", "//content/public/browser", ] } @@ -80,6 +81,7 @@ "//components/prefs:prefs", "//components/safe_browsing/core/browser:referrer_chain_provider", "//components/safe_browsing/core/common", + "//components/safe_browsing/core/common/proto:csd_proto", "//content/public/browser", "//net:net", ]
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc index e2df179b..e7b6d9b 100644 --- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
@@ -85,6 +85,8 @@ PrefService* prefs, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider) : content::WebContentsObserver(web_contents), content::WebContentsUserData<AdSamplerTrigger>(*web_contents), @@ -97,6 +99,7 @@ prefs_(prefs), url_loader_factory_(url_loader_factory), history_service_(history_service), + get_user_population_callback_(get_user_population_callback), referrer_chain_provider_(referrer_chain_provider), task_runner_(content::GetUIThreadTaskRunner({})) {} @@ -143,7 +146,8 @@ if (!trigger_manager_->StartCollectingThreatDetails( TriggerType::AD_SAMPLE, web_contents(), resource, url_loader_factory_, - history_service_, referrer_chain_provider_, error_options)) { + history_service_, get_user_population_callback_, + referrer_chain_provider_, error_options)) { UMA_HISTOGRAM_ENUMERATION(kAdSamplerTriggerActionMetricName, NO_SAMPLE_COULD_NOT_START_REPORT, MAX_ACTIONS); return;
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.h b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.h index b6336dab..59af2aad 100644 --- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.h +++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.h
@@ -8,6 +8,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "components/safe_browsing/core/common/proto/csd.pb.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -82,6 +83,8 @@ PrefService* prefs, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider); // Called to create an ad sample report. @@ -113,6 +116,7 @@ raw_ptr<PrefService> prefs_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; raw_ptr<history::HistoryService> history_service_; + base::RepeatingCallback<ChromeUserPopulation()> get_user_population_callback_; raw_ptr<ReferrerChainProvider> referrer_chain_provider_; // Task runner for posting delayed tasks. Normally set to the runner for the
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger_unittest.cc b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger_unittest.cc index 9204c559..85c8017 100644 --- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger_unittest.cc +++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger_unittest.cc
@@ -50,7 +50,8 @@ void CreateTriggerWithFrequency(const size_t denominator) { safe_browsing::AdSamplerTrigger::CreateForWebContents( - web_contents(), &trigger_manager_, &prefs_, nullptr, nullptr, nullptr); + web_contents(), &trigger_manager_, &prefs_, nullptr, nullptr, + base::NullCallback(), nullptr); safe_browsing::AdSamplerTrigger* ad_sampler = safe_browsing::AdSamplerTrigger::FromWebContents(web_contents()); @@ -100,7 +101,7 @@ // zero, which disables the trigger. CreateTriggerWithFrequency(kAdSamplerFrequencyDisabled); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetails(_, _, _, _, _, _, _)) + StartCollectingThreatDetails(_, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -127,7 +128,7 @@ CreateTriggerWithFrequency(/*denominator=*/1); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetails(_, _, _, _, _, _, _)) + StartCollectingThreatDetails(_, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -150,7 +151,7 @@ CreateTriggerWithFrequency(/*denominator=*/1); EXPECT_CALL(*get_trigger_manager(), StartCollectingThreatDetails(TriggerType::AD_SAMPLE, - web_contents(), _, _, _, _, _)) + web_contents(), _, _, _, _, _, _)) .Times(2) .WillRepeatedly(Return(true)); EXPECT_CALL(*get_trigger_manager(), @@ -183,7 +184,7 @@ CreateTriggerWithFrequency(/*denominator=*/1); EXPECT_CALL(*get_trigger_manager(), StartCollectingThreatDetails(TriggerType::AD_SAMPLE, - web_contents(), _, _, _, _, _)) + web_contents(), _, _, _, _, _, _)) .Times(1) .WillOnce(Return(false)); EXPECT_CALL(*get_trigger_manager(), @@ -215,7 +216,8 @@ // given. content::BrowserTaskEnvironment task_environment; AdSamplerTrigger trigger_default(nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr); + base::NullCallback(), nullptr); + EXPECT_EQ(kAdSamplerDefaultFrequency, trigger_default.sampler_frequency_denominator_); @@ -230,7 +232,7 @@ safe_browsing::kAdSamplerTriggerFeature, feature_params); AdSamplerTrigger trigger_finch(nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr); + base::NullCallback(), nullptr); EXPECT_EQ(kDenominatorInt, trigger_finch.sampler_frequency_denominator_); } } // namespace safe_browsing
diff --git a/components/safe_browsing/content/browser/triggers/mock_trigger_manager.h b/components/safe_browsing/content/browser/triggers/mock_trigger_manager.h index 46833c4..13a05caa 100644 --- a/components/safe_browsing/content/browser/triggers/mock_trigger_manager.h +++ b/components/safe_browsing/content/browser/triggers/mock_trigger_manager.h
@@ -21,22 +21,26 @@ ~MockTriggerManager() override; - MOCK_METHOD7( + MOCK_METHOD8( StartCollectingThreatDetails, bool(TriggerType trigger_type, content::WebContents* web_contents, const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options)); - MOCK_METHOD8( + MOCK_METHOD9( StartCollectingThreatDetailsWithReason, bool(TriggerType trigger_type, content::WebContents* web_contents, const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options, TriggerManagerReason* out_reason));
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc index eb0bc72..d4d092fa 100644 --- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
@@ -61,6 +61,8 @@ PrefService* prefs, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool monitor_mode) : content::WebContentsObserver(web_contents), @@ -72,6 +74,7 @@ prefs_(prefs), url_loader_factory_(url_loader_factory), history_service_(history_service), + get_user_population_callback_(get_user_population_callback), referrer_chain_provider_(referrer_chain_provider), task_runner_(content::GetUIThreadTaskRunner({})) {} @@ -99,8 +102,8 @@ TriggerManagerReason reason; if (!trigger_manager_->StartCollectingThreatDetailsWithReason( TriggerType::SUSPICIOUS_SITE, web_contents(), resource, - url_loader_factory_, history_service_, referrer_chain_provider_, - error_options, &reason)) { + url_loader_factory_, history_service_, get_user_population_callback_, + referrer_chain_provider_, error_options, &reason)) { UMA_HISTOGRAM_ENUMERATION(kSuspiciousSiteTriggerEventMetricName, SuspiciousSiteTriggerEvent::REPORT_START_FAILED); LOCAL_HISTOGRAM_ENUMERATION(
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h index 88c9f90..fc225e43 100644 --- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h +++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h
@@ -7,6 +7,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "components/safe_browsing/core/common/proto/csd.pb.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -131,6 +132,8 @@ PrefService* prefs, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool monitor_mode); @@ -171,6 +174,7 @@ raw_ptr<PrefService> prefs_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; raw_ptr<history::HistoryService> history_service_; + base::RepeatingCallback<ChromeUserPopulation()> get_user_population_callback_; raw_ptr<ReferrerChainProvider> referrer_chain_provider_; // Task runner for posting delayed tasks. Normally set to the runner for the
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger_unittest.cc b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger_unittest.cc index 01c04760..7e7dcba5 100644 --- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger_unittest.cc +++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger_unittest.cc
@@ -55,8 +55,8 @@ void CreateTrigger(bool monitor_mode) { safe_browsing::SuspiciousSiteTrigger::CreateForWebContents( - web_contents(), &trigger_manager_, &prefs_, nullptr, nullptr, nullptr, - monitor_mode); + web_contents(), &trigger_manager_, &prefs_, nullptr, nullptr, + base::NullCallback(), nullptr, monitor_mode); safe_browsing::SuspiciousSiteTrigger* trigger = safe_browsing::SuspiciousSiteTrigger::FromWebContents(web_contents()); // Give the trigger a test task runner that we can synchronize on. @@ -172,7 +172,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -204,7 +204,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(1) .WillOnce(Return(true)); EXPECT_CALL(*get_trigger_manager(), @@ -242,7 +242,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(1) .WillOnce(Return(true)); EXPECT_CALL(*get_trigger_manager(), @@ -279,10 +279,10 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(1) .WillOnce( - DoAll(SetArgPointee<7>(TriggerManagerReason::DAILY_QUOTA_EXCEEDED), + DoAll(SetArgPointee<8>(TriggerManagerReason::DAILY_QUOTA_EXCEEDED), Return(false))); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -321,7 +321,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -353,7 +353,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -391,7 +391,7 @@ CreateTrigger(/*monitor_mode=*/true); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -418,7 +418,7 @@ CreateTrigger(/*monitor_mode=*/true); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -454,7 +454,7 @@ CreateTrigger(/*monitor_mode=*/false); EXPECT_CALL(*get_trigger_manager(), - StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _)) + StartCollectingThreatDetailsWithReason(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_CALL(*get_trigger_manager(), FinishCollectingThreatDetails(_, _, _, _, _, _)) @@ -491,7 +491,7 @@ GURL suspicious_url(kSuspiciousUrl); EXPECT_CALL(*get_trigger_manager(), StartCollectingThreatDetailsWithReason( - _, _, ResourceHasUrl(suspicious_url), _, _, _, _, _)) + _, _, ResourceHasUrl(suspicious_url), _, _, _, _, _, _)) .Times(1) .WillOnce(Return(true)); EXPECT_CALL(*get_trigger_manager(),
diff --git a/components/safe_browsing/content/browser/triggers/trigger_manager.cc b/components/safe_browsing/content/browser/triggers/trigger_manager.cc index 23197e1e..9fe3d39a 100644 --- a/components/safe_browsing/content/browser/triggers/trigger_manager.cc +++ b/components/safe_browsing/content/browser/triggers/trigger_manager.cc
@@ -147,12 +147,15 @@ const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options) { TriggerManagerReason unused_reason; return StartCollectingThreatDetailsWithReason( trigger_type, web_contents, resource, url_loader_factory, history_service, - referrer_chain_provider, error_display_options, &unused_reason); + get_user_population_callback, referrer_chain_provider, + error_display_options, &unused_reason); } bool TriggerManager::StartCollectingThreatDetailsWithReason( @@ -161,6 +164,8 @@ const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options, TriggerManagerReason* reason) { @@ -178,7 +183,8 @@ bool should_trim_threat_details = trigger_type == TriggerType::AD_SAMPLE; collectors->threat_details = ThreatDetails::NewThreatDetails( ui_manager_, web_contents, resource, url_loader_factory, history_service, - referrer_chain_provider, should_trim_threat_details, + get_user_population_callback, referrer_chain_provider, + should_trim_threat_details, base::BindOnce(&TriggerManager::ThreatDetailsDone, weak_factory_.GetWeakPtr())); return true;
diff --git a/components/safe_browsing/content/browser/triggers/trigger_manager.h b/components/safe_browsing/content/browser/triggers/trigger_manager.h index edb23b7..d191758b 100644 --- a/components/safe_browsing/content/browser/triggers/trigger_manager.h +++ b/components/safe_browsing/content/browser/triggers/trigger_manager.h
@@ -132,6 +132,8 @@ const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options, TriggerManagerReason* out_reason); @@ -144,6 +146,8 @@ const security_interstitials::UnsafeResource& resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, const SBErrorOptions& error_display_options);
diff --git a/components/safe_browsing/content/browser/triggers/trigger_manager_unittest.cc b/components/safe_browsing/content/browser/triggers/trigger_manager_unittest.cc index 584e35d2..a84455b3 100644 --- a/components/safe_browsing/content/browser/triggers/trigger_manager_unittest.cc +++ b/components/safe_browsing/content/browser/triggers/trigger_manager_unittest.cc
@@ -47,6 +47,8 @@ const security_interstitials::UnsafeResource& unsafe_resource, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, history::HistoryService* history_service, + base::RepeatingCallback<ChromeUserPopulation()> + get_user_population_callback, ReferrerChainProvider* referrer_chain_provider, bool trim_to_ad_tags, ThreatDetailsDoneCallback done_callback) override { @@ -121,7 +123,7 @@ TriggerManager::GetSBErrorDisplayOptions(pref_service_, web_contents); return trigger_manager_.StartCollectingThreatDetails( trigger_type, web_contents, security_interstitials::UnsafeResource(), - nullptr, nullptr, nullptr, options); + nullptr, nullptr, base::NullCallback(), nullptr, options); } bool FinishCollectingThreatDetails(const TriggerType trigger_type,
diff --git a/components/safe_browsing/content/browser/ui_manager_unittest.cc b/components/safe_browsing/content/browser/ui_manager_unittest.cc index 12ea2f87..b087986 100644 --- a/components/safe_browsing/content/browser/ui_manager_unittest.cc +++ b/components/safe_browsing/content/browser/ui_manager_unittest.cc
@@ -122,6 +122,7 @@ "cpn_safe_browsing"), // help_center_article_link true, // should_trigger_reporting /*history_service=*/nullptr, + /*get_user_population_callback=*/base::NullCallback(), /*navigation_observer_manager=*/nullptr, /*metrics_collector=*/nullptr, /*trigger_manager=*/nullptr) {
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc index ad32a53..ced9006c6 100644 --- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -1150,6 +1150,10 @@ report_request.SetBoolean("show_download_in_folder", report.show_download_in_folder()); } + if (report.has_population()) { + report_request.SetKey("population", + SerializeChromeUserPopulation(report.population())); + } std::string serialized; if (report.SerializeToString(&serialized)) { std::string base64_encoded;
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service.cc index 1a2c309..8983315 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service.cc
@@ -127,10 +127,6 @@ variations_); } -bool RealTimeUrlLookupService::CanAttachReferrerChain() const { - return true; -} - int RealTimeUrlLookupService::GetReferrerUserGestureLimit() const { return kDefaultRealTimeUrlLookupReferrerLength; }
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service.h b/components/safe_browsing/core/browser/realtime/url_lookup_service.h index 6d12225..fb421e2c 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service.h +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service.h
@@ -83,7 +83,6 @@ GURL GetRealTimeLookupUrl() const override; net::NetworkTrafficAnnotationTag GetTrafficAnnotationTag() const override; bool CanPerformFullURLLookupWithToken() const override; - bool CanAttachReferrerChain() const override; int GetReferrerUserGestureLimit() const override; bool CanSendPageLoadToken() const override; void GetAccessToken(
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc index 582abe66..05b9d1b4 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc
@@ -524,7 +524,7 @@ request->population().user_population() == ChromeUserPopulation::ENHANCED_PROTECTION); - if (CanAttachReferrerChain() && referrer_chain_provider_) { + if (referrer_chain_provider_) { referrer_chain_provider_->IdentifyReferrerChainByPendingEventURL( SanitizeURL(url), GetReferrerUserGestureLimit(), request->mutable_referrer_chain());
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h index 20c68d20..a94b088 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h
@@ -148,9 +148,6 @@ // Returns true if real time URL lookup with GAIA token is enabled. virtual bool CanPerformFullURLLookupWithToken() const = 0; - // Returns true if referrer chain should be attached to requests. - virtual bool CanAttachReferrerChain() const = 0; - // Returns the user gesture limit of the referrer chain. virtual int GetReferrerUserGestureLimit() const = 0;
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc index 06a3b9b..f809a749 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
@@ -242,7 +242,6 @@ return TRAFFIC_ANNOTATION_FOR_TESTS; } bool CanPerformFullURLLookupWithToken() const override { return false; } - bool CanAttachReferrerChain() const override { return false; } int GetReferrerUserGestureLimit() const override { return 0; } bool CanSendPageLoadToken() const override { return false; } void GetAccessToken(
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index d662dfd..a160f8f 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -114,10 +114,6 @@ "SafeBrowsingDisableConsumerCsdForEnterprise", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kRealTimeUrlLookupReferrerChainForEnterprise{ - "SafeBrowsingRealTimeUrlLookupReferrerChainForEnterprise", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kSafeBrowsingPageLoadToken{ "SafeBrowsingPageLoadToken", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -177,7 +173,6 @@ {&kFileTypePoliciesTag, true}, {&kOmitNonUserGesturesFromReferrerChain, true}, {&kPasswordProtectionForSignedInUsers, true}, - {&kRealTimeUrlLookupReferrerChainForEnterprise, true}, {&kSafeBrowsingPageLoadToken, true}, {&kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, true}, {&kSafeBrowsingRemoveCookiesInAuthRequests, true},
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h index 9b86754..0e598848 100644 --- a/components/safe_browsing/core/common/features.h +++ b/components/safe_browsing/core/common/features.h
@@ -119,10 +119,6 @@ // Controls the daily quota for the suspicious site trigger. extern const base::Feature kSuspiciousSiteTriggerQuotaFeature; -// Controls whether the referrer chain is attached to real time requests for -// enterprise. -extern const base::Feature kRealTimeUrlLookupReferrerChainForEnterprise; - // Controls whether to send sample pings of Protego allowlist domains on // the allowlist to Safe Browsing. extern const base::Feature kSendSampledPingsForProtegoAllowlistDomains;
diff --git a/components/safe_browsing/core/common/proto/csd.proto b/components/safe_browsing/core/common/proto/csd.proto index 9152f7e..0c10ff88 100644 --- a/components/safe_browsing/core/common/proto/csd.proto +++ b/components/safe_browsing/core/common/proto/csd.proto
@@ -1384,7 +1384,7 @@ // A Detailed Safebrowsing Report from clients. Chrome safebrowsing reports are // only sent by Chrome users who have opted into extended Safe Browsing. // This proto is replacing ClientMalwareReportRequest. -// Next tag: 26 +// Next tag: 27 message ClientSafeBrowsingReportRequest { // Note: A lot of the "optional" fields would make sense to be // "required" instead. However, having them as optional allows the @@ -1560,6 +1560,8 @@ // The SafetyNet ID of the Android device. // Deprecated, not launched. optional string safety_net_id = 25 [deprecated = true]; + + optional ChromeUserPopulation population = 26; } // An HTML Element on the page (eg: iframe, div, script, etc).
diff --git a/components/search_engines/template_url_service_unittest.cc b/components/search_engines/template_url_service_unittest.cc index d9252a2..8cb8da3 100644 --- a/components/search_engines/template_url_service_unittest.cc +++ b/components/search_engines/template_url_service_unittest.cc
@@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "components/search_engines/template_url_service.h" + #include <stddef.h> #include <memory> -#include "components/search_engines/template_url_service.h" +#include "base/threading/platform_thread.h" #include "testing/gtest/include/gtest/gtest.h" class TemplateURLServiceUnitTest : public testing::Test {
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index e195313..a29d9ef0 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -253,6 +253,12 @@ signal_filter_processor_->OnSignalListUpdated(); model_execution_scheduler_->OnNewModelInfoReady(segment_info); + + // Update the service status for proxy. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&SegmentationPlatformServiceImpl::OnServiceStatusChanged, + weak_ptr_factory_.GetWeakPtr())); } void SegmentationPlatformServiceImpl::OnExecuteDatabaseMaintenanceTasks() { @@ -261,15 +267,12 @@ void SegmentationPlatformServiceImpl::OnServiceStatusChanged() { int status = static_cast<int>(ServiceStatus::kUninitialized); - if (IsInitializationFinished()) { - if (segment_info_database_initialized_) - status |= static_cast<int>(ServiceStatus::kSegmentationInfoDbInitialized); - if (signal_database_initialized_) - status |= static_cast<int>(ServiceStatus::kSignalDbInitialized); - if (signal_storage_config_initialized_) { - status |= - static_cast<int>(ServiceStatus::kSignalStorageConfigInitialized); - } + if (segment_info_database_initialized_) + status |= static_cast<int>(ServiceStatus::kSegmentationInfoDbInitialized); + if (signal_database_initialized_) + status |= static_cast<int>(ServiceStatus::kSignalDbInitialized); + if (signal_storage_config_initialized_) { + status |= static_cast<int>(ServiceStatus::kSignalStorageConfigInitialized); } proxy_->OnServiceStatusChanged(IsInitializationFinished(), status);
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc index 24243366..9c8e9c6 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "components/segmentation_platform/internal/segmentation_platform_service_impl.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/files/file_path.h" @@ -42,12 +43,15 @@ #include "components/segmentation_platform/internal/signals/signal_filter_processor.h" #include "components/segmentation_platform/internal/signals/user_action_signal_handler.h" #include "components/segmentation_platform/public/config.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) #include "components/segmentation_platform/internal/execution/model_execution_manager_impl.h" #endif // BUILDFLAG(BUILD_WITH_TFLITE_LIB +using ::testing::_; + namespace segmentation_platform { namespace { @@ -94,6 +98,19 @@ } // namespace +// A mock of the ServiceProxy::Observer. +class MockServiceProxyObserver : public ServiceProxy::Observer { + public: + MockServiceProxyObserver() = default; + ~MockServiceProxyObserver() override = default; + + MOCK_METHOD(void, OnServiceStatusChanged, (bool, int), (override)); + MOCK_METHOD(void, + OnSegmentInfoAvailable, + ((const std::vector<std::pair<std::string, std::string>>&)), + (override)); +}; + class SegmentationPlatformServiceImplTest : public testing::Test { public: SegmentationPlatformServiceImplTest() = default; @@ -126,6 +143,8 @@ std::move(segment_db), std::move(signal_db), std::move(segment_storage_config_db), &model_provider_, &pref_service_, task_runner_, &test_clock_, std::move(configs)); + segmentation_platform_service_impl_->GetServiceProxy()->AddObserver( + &observer_); } void TearDown() override { @@ -206,10 +225,12 @@ base::SimpleTestClock test_clock_; std::unique_ptr<SegmentationPlatformServiceImpl> segmentation_platform_service_impl_; + MockServiceProxyObserver observer_; }; TEST_F(SegmentationPlatformServiceImplTest, InitializationFlow) { // Let the DB loading complete successfully. + EXPECT_CALL(observer_, OnServiceStatusChanged(true, 7)); segment_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); signal_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); segment_storage_config_db_->InitStatusCallback( @@ -273,6 +294,11 @@ AssertCachedSegment(kTestSegmentationKey2, false); AssertCachedSegment(kTestSegmentationKey3, false); + // ServiceProxy will load new segment info from the DB. + EXPECT_CALL(observer_, OnSegmentInfoAvailable(_)); + task_environment_.RunUntilIdle(); + segment_db_->LoadCallback(true); + mem_impl->OnSegmentationModelUpdated( OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_VOICE, metadata); segment_db_->GetCallback(true); @@ -285,6 +311,11 @@ EXPECT_EQ( 2, histogram_tester.GetBucketCount( "SegmentationPlatform.Signals.ListeningCount.HistogramValue", 1)); + + // ServiceProxy will load new segment info from the DB. + EXPECT_CALL(observer_, OnSegmentInfoAvailable(_)); + task_environment_.RunUntilIdle(); + segment_db_->LoadCallback(true); #endif // BUILDFLAG(BUILD_WITH_TFLITE_LIB) // Database maintenance tasks should try to cleanup the signals after a short @@ -326,6 +357,7 @@ TEST_F(SegmentationPlatformServiceImplEmptyConfigTest, InitializationFlow) { // Let the DB loading complete successfully. + EXPECT_CALL(observer_, OnServiceStatusChanged(true, 7)); segment_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); signal_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); segment_storage_config_db_->InitStatusCallback( @@ -359,6 +391,7 @@ TEST_F(SegmentationPlatformServiceImplMultiClientTest, InitializationFlow) { // Let the DB loading complete successfully. + EXPECT_CALL(observer_, OnServiceStatusChanged(true, 7)); segment_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); signal_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); segment_storage_config_db_->InitStatusCallback(
diff --git a/components/segmentation_platform/internal/selection/segment_selector_impl.h b/components/segmentation_platform/internal/selection/segment_selector_impl.h index 70f665df..a7614ab6 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_impl.h +++ b/components/segmentation_platform/internal/selection/segment_selector_impl.h
@@ -43,6 +43,10 @@ void GetSelectedSegment(SegmentSelectionCallback callback) override; SegmentSelectionResult GetCachedSegmentResult() override; + // Helper function to update the selected segment in the prefs. Auto-extends + // the selection if the new result is unknown. + void UpdateSelectedSegment(OptimizationTarget new_selection); + // ModelExecutionScheduler::Observer overrides. // Called whenever a model eval completes. Runs segment selection to find the @@ -72,10 +76,6 @@ const std::vector<std::pair<OptimizationTarget, proto::SegmentInfo>>& all_segments); - // Helper function to update the selected segment in the prefs. Auto-extends - // the selection if the new result is unknown. - void UpdateSelectedSegment(OptimizationTarget new_selection); - // The database storing metadata and results. raw_ptr<SegmentInfoDatabase> segment_database_;
diff --git a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc b/components/segmentation_platform/internal/selection/segment_selector_unittest.cc index 11ba9bf5..e02af0ef 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc +++ b/components/segmentation_platform/internal/selection/segment_selector_unittest.cc
@@ -316,4 +316,34 @@ ASSERT_EQ(result, segment_selector_->GetCachedSegmentResult()); } +// Tests that prefs are properly updated after calling UpdateSelectedSegment(). +TEST_F(SegmentSelectorTest, UpdateSelectedSegment) { + SetUpWithConfig(CreateTestConfig()); + EXPECT_CALL(signal_storage_config_, MeetsSignalCollectionRequirement(_)) + .WillRepeatedly(Return(true)); + + OptimizationTarget segment_id = + OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; + float mapping[][2] = {{0.2, 1}, {0.5, 3}, {0.7, 4}}; + InitializeMetadataForSegment(segment_id, mapping, 3); + + OptimizationTarget segment_id2 = + OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_SHARE; + float mapping2[][2] = {{0.3, 1}, {0.4, 4}}; + InitializeMetadataForSegment(segment_id2, mapping2, 2); + + segment_database_->AddPredictionResult(segment_id, 0.6, clock_.Now()); + segment_database_->AddPredictionResult(segment_id2, 0.5, clock_.Now()); + + clock_.Advance(base::Days(1)); + segment_selector_->OnModelExecutionCompleted(segment_id); + ASSERT_TRUE(prefs_->selection.has_value()); + ASSERT_EQ(segment_id2, prefs_->selection->segment_id); + + // Update the selected segment to |segment_id|. + segment_selector_->UpdateSelectedSegment(segment_id); + ASSERT_TRUE(prefs_->selection.has_value()); + ASSERT_EQ(segment_id, prefs_->selection->segment_id); +} + } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/service_proxy_impl.cc b/components/segmentation_platform/internal/service_proxy_impl.cc index 81757ae..9b9dae0 100644 --- a/components/segmentation_platform/internal/service_proxy_impl.cc +++ b/components/segmentation_platform/internal/service_proxy_impl.cc
@@ -58,10 +58,14 @@ void ServiceProxyImpl::OnServiceStatusChanged(bool is_initialized, int status_flag) { + bool changed = (is_service_initialized_ != is_initialized) || + (service_status_flag_ != status_flag); is_service_initialized_ = is_initialized; service_status_flag_ = status_flag; - for (Observer& obs : observers_) - obs.OnServiceStatusChanged(is_initialized, status_flag); + if (changed) { + for (Observer& obs : observers_) + obs.OnServiceStatusChanged(is_initialized, status_flag); + } if (segment_db_ && (static_cast<int>(ServiceStatus::kSegmentationInfoDbInitialized) &
diff --git a/components/send_tab_to_self/features.cc b/components/send_tab_to_self/features.cc index 8c9c2277..3625c4d 100644 --- a/components/send_tab_to_self/features.cc +++ b/components/send_tab_to_self/features.cc
@@ -31,14 +31,10 @@ #endif }; -const base::Feature kSendTabToSelfV2{ - "SendTabToSelfV2", #if defined(OS_ANDROID) || defined(OS_IOS) - base::FEATURE_DISABLED_BY_DEFAULT -#else - base::FEATURE_ENABLED_BY_DEFAULT +const base::Feature kSendTabToSelfV2{"SendTabToSelfV2", + base::FEATURE_DISABLED_BY_DEFAULT}; #endif -}; bool IsReceivingEnabledByUserOnThisDevice(PrefService* prefs) { // TODO(crbug.com/1015322): SyncPrefs is used directly instead of methods in
diff --git a/components/send_tab_to_self/features.h b/components/send_tab_to_self/features.h index aedaf032..38cfcc9f9 100644 --- a/components/send_tab_to_self/features.h +++ b/components/send_tab_to_self/features.h
@@ -6,6 +6,7 @@ #define COMPONENTS_SEND_TAB_TO_SELF_FEATURES_H_ #include "base/feature_list.h" +#include "build/build_config.h" class PrefService; @@ -20,9 +21,14 @@ // below the device list when sharing. extern const base::Feature kSendTabToSelfManageDevicesLink; +#if defined(OS_ANDROID) || defined(OS_IOS) // If this feature is enabled, show received tabs in a new UI next to the // profile icon rather than in a system notification. +// +// V2 is the default on desktop and the V1 code path has been deleted there, so +// this base::Feature no longer exists on desktop platforms. extern const base::Feature kSendTabToSelfV2; +#endif // OS_ANDROID || OS_IOS // Returns whether the receiving components of the feature is enabled on this // device. This doesn't rely on the SendTabToSelfSyncService to be actively up
diff --git a/components/services/app_service/public/mojom/BUILD.gn b/components/services/app_service/public/mojom/BUILD.gn index b2a043d..76718d3 100644 --- a/components/services/app_service/public/mojom/BUILD.gn +++ b/components/services/app_service/public/mojom/BUILD.gn
@@ -6,13 +6,13 @@ mojom("types") { sources = [ "types.mojom" ] + webui_module_path = "/" public_deps = [ "//mojo/public/mojom/base", "//skia/public/mojom", "//ui/gfx/geometry/mojom", "//ui/gfx/image/mojom", - "//ui/gfx/image/mojom", "//ui/gfx/mojom", "//ui/gfx/range/mojom", "//url/mojom:url_mojom_gurl", @@ -21,6 +21,7 @@ mojom("mojom") { sources = [ "app_service.mojom" ] + webui_module_path = "/" public_deps = [ ":types" ] }
diff --git a/components/sessions/core/tab_restore_service_helper.cc b/components/sessions/core/tab_restore_service_helper.cc index 62ac841..3de954e 100644 --- a/components/sessions/core/tab_restore_service_helper.cc +++ b/components/sessions/core/tab_restore_service_helper.cc
@@ -30,6 +30,7 @@ #include "components/sessions/core/live_tab.h" #include "components/sessions/core/live_tab_context.h" #include "components/sessions/core/serialized_navigation_entry.h" +#include "components/sessions/core/session_constants.h" #include "components/sessions/core/session_id.h" #include "components/sessions/core/session_types.h" #include "components/sessions/core/tab_restore_service_client.h" @@ -38,6 +39,60 @@ #include "components/tab_groups/tab_group_visual_data.h" namespace sessions { +namespace { + +// Specifies what entries are added. +enum class AddBehavior { + // Adds the current entry, and entries preceeding it. + kCurrentAndPreceedingEntries, + + // Adds entries after the current. + kEntriesFollowingCurrentEntry, +}; + +// Adds serialized navigation entries from a LiveTab. +void AddSerializedNavigationEntries( + LiveTab* live_tab, + AddBehavior behavior, + std::vector<SerializedNavigationEntry>& navigations) { + // It is assumed this is called for back navigations first, at which point the + // vector should be empty. This is necessary as back navigations are added + // in reverse order and then the vector is reversed. + DCHECK(behavior == AddBehavior::kEntriesFollowingCurrentEntry || + navigations.empty()); + const int max_index = live_tab->GetEntryCount(); + const int delta = + (behavior == AddBehavior::kCurrentAndPreceedingEntries) ? -1 : 1; + int current_index = live_tab->GetCurrentEntryIndex(); + if (behavior == AddBehavior::kEntriesFollowingCurrentEntry) + ++current_index; + int added_count = 0; + while (current_index >= 0 && current_index < max_index && + added_count <= gMaxPersistNavigationCount) { + SerializedNavigationEntry entry = live_tab->GetEntryAtIndex(current_index); + current_index += delta; + // Reader Mode is meant to be considered a "mode" that users can only enter + // using a button in the omnibox, so it does not show up in recently closed + // tabs, session sync, or chrome://history. Remove Reader Mode pages from + // the navigations. + if (entry.virtual_url().SchemeIs(dom_distiller::kDomDistillerScheme)) + continue; + + // As this code was identified as doing a lot of allocations, push_back is + // always used and the vector is reversed for `kCurrentAndPreceedingEntries` + // when done. Doing this instead of inserting at the beginning results in + // less memory operations. + navigations.push_back(std::move(entry)); + ++added_count; + } + // Iteration for `kCurrentAndPreceedingEntries` happens in descending order. + // This results in the entries being added in reverse order. Use + // std::reverse() so the entries end up in ascending order. + if (behavior == AddBehavior::kCurrentAndPreceedingEntries) + std::reverse(navigations.begin(), navigations.end()); +} + +} // namespace // TabRestoreServiceHelper::Observer ------------------------------------------- @@ -754,30 +809,19 @@ int index, LiveTabContext* context, LiveTab* live_tab) { - int max_entry_count = - live_tab->IsInitialBlankNavigation() ? 0 : live_tab->GetEntryCount(); - tab->navigations.resize(static_cast<int>(max_entry_count)); - int actual_entry_count = 0; - int current_navigation_index = live_tab->GetCurrentEntryIndex(); - for (int i = 0; i < max_entry_count; ++i) { - SerializedNavigationEntry entry = live_tab->GetEntryAtIndex(i); - // Reader Mode is meant to be considered a "mode" that users can only enter - // using a button in the omnibox, so it does not show up in recently closed - // tabs, session sync, or chrome://history. Remove Reader Mode pages from - // the navigations. - if (!entry.virtual_url().SchemeIs(dom_distiller::kDomDistillerScheme)) { - tab->navigations[actual_entry_count++] = entry; - } else if (current_navigation_index >= i) { - // The page removed was behind the current navigation index, so - // decrement the current navigation index. - current_navigation_index--; + tab->current_navigation_index = 0; + if (!live_tab->IsInitialBlankNavigation() && live_tab->GetEntryCount() > 0) { + AddSerializedNavigationEntries( + live_tab, AddBehavior::kCurrentAndPreceedingEntries, tab->navigations); + if (!tab->navigations.empty()) { + tab->current_navigation_index = + static_cast<int>(tab->navigations.size()) - 1; } + AddSerializedNavigationEntries( + live_tab, AddBehavior::kEntriesFollowingCurrentEntry, tab->navigations); } - if (actual_entry_count != max_entry_count) - tab->navigations.resize(static_cast<int>(actual_entry_count)); tab->timestamp = TimeNow(); - tab->current_navigation_index = current_navigation_index; tab->tabstrip_index = index; tab->extension_app_id = client_->GetExtensionAppIDForTab(live_tab); tab->user_agent_override = live_tab->GetUserAgentOverride();
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm index 9a768a8..de8d047f 100644 --- a/components/signin/ios/browser/account_consistency_service.mm +++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -137,7 +137,10 @@ // Handles the AddAccount request depending on |has_cookie_changed|. void HandleAddAccountRequest(GURL url, BOOL has_cookie_changed); - bool show_consistency_promo_ = false; + // The consistency web sign-in needs to be shown once the page is loaded. + // It is required to avoid having the keyboard showing up on top of the web + // sign-in dialog. + bool show_consistency_web_signin_ = false; AccountConsistencyService* account_consistency_service_; // Weak. AccountReconcilor* account_reconcilor_; // Weak. signin::IdentityManager* identity_manager_; @@ -199,11 +202,6 @@ {url, GURL(kGoogleUrl)}); } - // Reset boolean that tracks displaying the sign-in consistency promo. This - // ensures that the promo is cancelled once navigation has started and the - // WKWebView is cancelling previous navigations. - show_consistency_promo_ = false; - if (!gaia::IsGaiaSignonRealm(url.DeprecatedGetOriginAsURL())) { std::move(callback).Run(PolicyDecision::Allow()); return; @@ -218,7 +216,7 @@ NSString* x_autologin_header = [[http_response allHeaderFields] objectForKey:[NSString stringWithUTF8String:signin::kAutoLoginHeader]]; if (x_autologin_header) { - show_consistency_promo_ = true; + show_consistency_web_signin_ = true; } std::move(callback).Run(PolicyDecision::Allow()); return; @@ -254,13 +252,6 @@ // have been restored. return; } - } else if (!identity_manager_->GetAccountsWithRefreshTokens().empty()) { - show_consistency_promo_ = true; - // Allows the URL response to load before showing the consistency promo. - // The promo should always be displayed in the foreground of Gaia - // sign-on. - std::move(callback).Run(PolicyDecision::Allow()); - return; } [delegate_ onAddAccount]; break; @@ -312,11 +303,11 @@ return; } - if (show_consistency_promo_ && + if (show_consistency_web_signin_ && gaia::IsGaiaSignonRealm(url.DeprecatedGetOriginAsURL())) { [delegate_ onShowConsistencyPromo:url webState:web_state]; - show_consistency_promo_ = false; } + show_consistency_web_signin_ = false; } void AccountConsistencyService::AccountConsistencyHandler::WebStateDestroyed(
diff --git a/components/signin/public/identity_manager/ubertoken_fetcher.h b/components/signin/public/identity_manager/ubertoken_fetcher.h index 178f1ac..cc47332 100644 --- a/components/signin/public/identity_manager/ubertoken_fetcher.h +++ b/components/signin/public/identity_manager/ubertoken_fetcher.h
@@ -5,9 +5,9 @@ #ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_UBERTOKEN_FETCHER_H_ #define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_UBERTOKEN_FETCHER_H_ -#include <memory> +#include <string> -#include "base/bind.h" +#include "base/callback_forward.h" class GoogleServiceAuthError;
diff --git a/components/strings/components_strings_kk.xtb b/components/strings/components_strings_kk.xtb index c946be6..0a00344a 100644 --- a/components/strings/components_strings_kk.xtb +++ b/components/strings/components_strings_kk.xtb
@@ -1763,7 +1763,7 @@ <translation id="6660413144148052430">орын</translation> <translation id="6662457027866368246">Бірінші орам</translation> <translation id="666259744093848177">(x86_64 үшін аударылған)</translation> -<translation id="6663846344464066639">Қосылған қолдар</translation> +<translation id="6663846344464066639">Алақандарды біріктіру</translation> <translation id="6665553082534466207">Оң жағын үш рет тесу</translation> <translation id="6671697161687535275">Chromium жүйесінен нысан ұсынысын алып тастау керек пе?</translation> <translation id="6685834062052613830">Жүйеден шығып, орнатуды аяқтаңыз</translation>
diff --git a/components/test/data/payments/payment_request_iframe.html b/components/test/data/payments/payment_request_iframe.html index 5b5027d..12a894e 100644 --- a/components/test/data/payments/payment_request_iframe.html +++ b/components/test/data/payments/payment_request_iframe.html
@@ -1,6 +1,8 @@ <!DOCTYPE html> <script> -new PaymentRequest( - [{supportedMethods: 'basic-card'}], - {total: {label: 'Tots', amount: {currency: 'USD', value: '1.00'}}}).show(); +function triggerPaymentRequest() { + new PaymentRequest( + [{supportedMethods: 'basic-card'}], + {total: {label: 'Tots', amount: {currency: 'USD', value: '1.00'}}}).show(); +} </script>
diff --git a/components/test/data/payments/secure_payment_confirmation.html b/components/test/data/payments/secure_payment_confirmation.html index 95c39fd..66b9d13 100644 --- a/components/test/data/payments/secure_payment_confirmation.html +++ b/components/test/data/payments/secure_payment_confirmation.html
@@ -15,5 +15,8 @@ <script src="can_make_payment_checker.js"></script> <script src="has_enrolled_instrument_checker.js"></script> <script src="secure_payment_confirmation.js"></script> + +<!-- For tests that test SPC in an iframe. Not always used. --> +<iframe id="test" allow="payment *"></iframe> </body> </html>
diff --git a/components/test/data/payments/iframe_receiver.html b/components/test/data/payments/secure_payment_confirmation_iframe.html similarity index 76% rename from components/test/data/payments/iframe_receiver.html rename to components/test/data/payments/secure_payment_confirmation_iframe.html index 84a6286d..870dbd3 100644 --- a/components/test/data/payments/iframe_receiver.html +++ b/components/test/data/payments/secure_payment_confirmation_iframe.html
@@ -8,9 +8,9 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1"> -<title>Iframe Receiver</title> +<title>Secure Payment Confirmation iframe</title> </head> <body> -<script src="iframe_receiver.js"></script> +<script src="secure_payment_confirmation_iframe.js"></script> </body> </html>
diff --git a/components/test/data/payments/iframe_receiver.js b/components/test/data/payments/secure_payment_confirmation_iframe.js similarity index 84% rename from components/test/data/payments/iframe_receiver.js rename to components/test/data/payments/secure_payment_confirmation_iframe.js index 47b6212..b56eb6d 100644 --- a/components/test/data/payments/iframe_receiver.js +++ b/components/test/data/payments/secure_payment_confirmation_iframe.js
@@ -4,14 +4,6 @@ * found in the LICENSE file. */ -window.onmessage = (e) => { - requestPayment(e.data).then((result) => { - e.source.postMessage(result, e.origin); - }).catch((error) => { - e.source.postMessage(error, e.origin); - }); -}; - /** * Requests a secure payment confirmation payment for the given credential * identifier. @@ -20,7 +12,7 @@ * @return {Promise<string>} - Either the clientDataJSON string or an error * message. */ -async function requestPayment(credentialId) { +async function requestPayment(credentialId) { // eslint-disable-line no-unused-vars, max-len try { const request = new PaymentRequest( [{supportedMethods: 'secure-payment-confirmation',
diff --git a/components/translate/content/browser/per_frame_content_translate_driver.cc b/components/translate/content/browser/per_frame_content_translate_driver.cc index cc3c926..8e0422b 100644 --- a/components/translate/content/browser/per_frame_content_translate_driver.cc +++ b/components/translate/content/browser/per_frame_content_translate_driver.cc
@@ -326,8 +326,8 @@ } } -void PerFrameContentTranslateDriver::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void PerFrameContentTranslateDriver:: + DocumentOnLoadCompletedInPrimaryMainFrame() { if (translate::IsSubFrameLanguageDetectionEnabled() && translate::IsTranslatableURL(web_contents()->GetLastCommittedURL())) { StartLanguageDetection();
diff --git a/components/translate/content/browser/per_frame_content_translate_driver.h b/components/translate/content/browser/per_frame_content_translate_driver.h index 00a6f46..992deac 100644 --- a/components/translate/content/browser/per_frame_content_translate_driver.h +++ b/components/translate/content/browser/per_frame_content_translate_driver.h
@@ -59,8 +59,7 @@ void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void OnPageLanguageDetermined(const LanguageDetectionDetails& details, bool page_level_translation_critiera_met);
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc index d57290a..6fd454e 100644 --- a/components/translate/core/browser/translate_prefs.cc +++ b/components/translate/core/browser/translate_prefs.cc
@@ -386,7 +386,7 @@ // To avoid code duplication, set |offset| to max int and re-use the logic // to move |language| up in the list as far as possible. offset = std::numeric_limits<int>::max(); - FALLTHROUGH; + [[fallthrough]]; case kUp: if (pos == languages.begin()) return;
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc index dec4eca..38e1f7b 100644 --- a/components/translate/core/browser/translate_prefs_unittest.cc +++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_timeouts.h" +#include "base/threading/platform_thread.h" #include "base/values.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h"
diff --git a/components/url_formatter/elide_url.cc b/components/url_formatter/elide_url.cc index 62f4783..bef1672 100644 --- a/components/url_formatter/elide_url.cc +++ b/components/url_formatter/elide_url.cc
@@ -8,6 +8,7 @@ #include "base/check_op.h" #include "base/i18n/rtl.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" @@ -119,7 +120,7 @@ // Get sub domain. const size_t domain_start_index = url_host->find(*url_domain); - std::u16string kWwwPrefix = u"www."; + constexpr base::StringPiece16 kWwwPrefix = u"www."; if (domain_start_index != std::u16string::npos) *url_subdomain = url_host->substr(0, domain_start_index); if ((*url_subdomain == kWwwPrefix || url_subdomain->empty() || @@ -217,7 +218,7 @@ // domain is now C: - this is a nice hack for eliding to work pleasantly. if (url.SchemeIsFile()) { // Split the path string using ":" - const std::u16string kColon(1, ':'); + constexpr base::StringPiece16 kColon(u":", 1); std::vector<std::u16string> file_path_split = base::SplitString( url_path, kColon, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); if (file_path_split.size() > 1) { // File is of type "file:///C:/.." @@ -225,7 +226,8 @@ url_domain.clear(); url_subdomain.clear(); - url_host = url_domain = file_path_split.at(0).substr(1) + kColon; + url_host = url_domain = + base::StrCat({file_path_split.at(0).substr(1), kColon}); url_path_query_etc = url_path = file_path_split.at(1); } } @@ -365,24 +367,22 @@ if (!url.is_valid() || url.is_empty() || !url.IsStandard()) return url_formatter::FormatUrl(url); - const std::u16string colon(u":"); - const std::u16string scheme_separator( - base::ASCIIToUTF16(url::kStandardSchemeSeparator)); + constexpr base::StringPiece16 colon(u":"); if (url.SchemeIsFile()) { - return base::ASCIIToUTF16(url::kFileScheme) + scheme_separator + - base::UTF8ToUTF16(url.path()); + return base::StrCat({url::kFileScheme16, url::kStandardSchemeSeparator16, + base::UTF8ToUTF16(url.path())}); } if (url.SchemeIsFileSystem()) { const GURL* inner_url = url.inner_url(); if (inner_url->SchemeIsFile()) { - return base::ASCIIToUTF16(url::kFileSystemScheme) + colon + - FormatUrlForSecurityDisplay(*inner_url) + - base::UTF8ToUTF16(url.path()); + return base::StrCat({url::kFileSystemScheme16, colon, + FormatUrlForSecurityDisplay(*inner_url), + base::UTF8ToUTF16(url.path())}); } - return base::ASCIIToUTF16(url::kFileSystemScheme) + colon + - FormatUrlForSecurityDisplay(*inner_url); + return base::StrCat({url::kFileSystemScheme16, colon, + FormatUrlForSecurityDisplay(*inner_url)}); } const GURL origin = url.DeprecatedGetOriginAsURL(); @@ -390,15 +390,17 @@ base::StringPiece host = origin.host_piece(); std::u16string result; - if (ShouldShowScheme(scheme, scheme_display)) - result = base::UTF8ToUTF16(scheme) + scheme_separator; + if (ShouldShowScheme(scheme, scheme_display)) { + result = base::StrCat( + {base::UTF8ToUTF16(scheme), url::kStandardSchemeSeparator16}); + } result += HostForDisplay(host); const int port = origin.IntPort(); const int default_port = url::DefaultPortForScheme( scheme.data(), static_cast<int>(scheme.length())); if (port != url::PORT_UNSPECIFIED && port != default_port) - result += colon + base::UTF8ToUTF16(origin.port_piece()); + result += base::StrCat({colon, base::UTF8ToUTF16(origin.port_piece())}); return result; } @@ -411,20 +413,20 @@ if (scheme.empty() && host.empty()) return std::u16string(); - const std::u16string colon(u":"); - const std::u16string scheme_separator( - base::ASCIIToUTF16(url::kStandardSchemeSeparator)); + constexpr base::StringPiece16 colon(u":"); std::u16string result; - if (ShouldShowScheme(scheme, scheme_display)) - result = base::UTF8ToUTF16(scheme) + scheme_separator; + if (ShouldShowScheme(scheme, scheme_display)) { + result = base::StrCat( + {base::UTF8ToUTF16(scheme), url::kStandardSchemeSeparator16}); + } result += HostForDisplay(host); int port = static_cast<int>(origin.port()); const int default_port = url::DefaultPortForScheme( scheme.data(), static_cast<int>(scheme.length())); if (port != 0 && port != default_port) - result += colon + base::NumberToString16(origin.port()); + result += base::StrCat({colon, base::NumberToString16(origin.port())}); return result; }
diff --git a/components/url_pattern_index/url_pattern.cc b/components/url_pattern_index/url_pattern.cc index 9a6b2da3..cc639bf 100644 --- a/components/url_pattern_index/url_pattern.cc +++ b/components/url_pattern_index/url_pattern.cc
@@ -377,10 +377,10 @@ switch (pattern.anchor_left()) { case proto::ANCHOR_TYPE_SUBDOMAIN: out << '|'; - FALLTHROUGH; + [[fallthrough]]; case proto::ANCHOR_TYPE_BOUNDARY: out << '|'; - FALLTHROUGH; + [[fallthrough]]; default: break; }
diff --git a/components/url_pattern_index/url_pattern_index.cc b/components/url_pattern_index/url_pattern_index.cc index b678fce..387c93ca 100644 --- a/components/url_pattern_index/url_pattern_index.cc +++ b/components/url_pattern_index/url_pattern_index.cc
@@ -255,7 +255,7 @@ switch (rule_.source_type()) { case proto::SOURCE_TYPE_ANY: options_ |= flat::OptionFlag_APPLIES_TO_THIRD_PARTY; - FALLTHROUGH; + [[fallthrough]]; case proto::SOURCE_TYPE_FIRST_PARTY: options_ |= flat::OptionFlag_APPLIES_TO_FIRST_PARTY; break;
diff --git a/components/variations/variations_murmur_hash.cc b/components/variations/variations_murmur_hash.cc index b4ce83a..caa4f0a 100644 --- a/components/variations/variations_murmur_hash.cc +++ b/components/variations/variations_murmur_hash.cc
@@ -61,10 +61,10 @@ switch (length & 3) { case 3: k1 |= data[num_full_blocks] & 0xFF0000; - FALLTHROUGH; + [[fallthrough]]; case 2: k1 |= data[num_full_blocks] & 0xFF00; - FALLTHROUGH; + [[fallthrough]]; case 1: k1 |= data[num_full_blocks] & 0xFF; }
diff --git a/components/viz/host/gpu_host_impl.cc b/components/viz/host/gpu_host_impl.cc index c91136d56..3e9e744 100644 --- a/components/viz/host/gpu_host_impl.cc +++ b/components/viz/host/gpu_host_impl.cc
@@ -476,12 +476,7 @@ if (!params_.disable_gpu_shader_disk_cache) { CreateChannelCache(gpu::kDisplayCompositorClientId); - - bool use_gr_shader_cache = base::FeatureList::IsEnabled( - features::kDefaultEnableOopRasterization) || - features::IsUsingSkiaRenderer(); - if (use_gr_shader_cache) - CreateChannelCache(gpu::kGrShaderCacheClientId); + CreateChannelCache(gpu::kGrShaderCacheClientId); } }
diff --git a/components/viz/service/DEPS b/components/viz/service/DEPS index 53f869e..b963bb7 100644 --- a/components/viz/service/DEPS +++ b/components/viz/service/DEPS
@@ -18,9 +18,3 @@ "+ui/ozone/buildflags.h", "+ui/ozone/public", ] - -specific_include_rules = { - "ExternalBeginFrameSourceAndroid.java": [ - "+ui/android/java/src/org/chromium/ui/VSyncMonitor.java", - ] -}
diff --git a/components/viz/service/display/ca_layer_overlay.cc b/components/viz/service/display/ca_layer_overlay.cc index a834b3d2..3f6a3c7c 100644 --- a/components/viz/service/display/ca_layer_overlay.cc +++ b/components/viz/service/display/ca_layer_overlay.cc
@@ -17,6 +17,7 @@ #include "components/viz/service/display/display_resource_provider.h" #include "gpu/GLES2/gl2extchromium.h" #include "third_party/skia/include/core/SkDeferredDisplayList.h" +#include "ui/base/cocoa/remote_layer_api.h" namespace viz { @@ -351,6 +352,16 @@ scoped_refptr<CALayerOverlaySharedState> most_recent_overlay_shared_state_; }; +// Control using the CoreAnimation renderer, which is the path that replaces +// all quads with CALayers. +base::Feature kCARenderer{"CoreAnimationRenderer", + base::FEATURE_ENABLED_BY_DEFAULT}; + +// Control using the CoreAnimation renderer, which is the path that replaces +// all quads with CALayers. +base::Feature kHDRUnderlays{"CoreAnimationHDRUnderlays", + base::FEATURE_ENABLED_BY_DEFAULT}; + } // namespace CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {} @@ -362,8 +373,10 @@ CALayerOverlay& CALayerOverlay::operator=(const CALayerOverlay& other) = default; -CALayerOverlayProcessor::CALayerOverlayProcessor(bool enable_ca_overlay) - : enable_ca_overlay_(enable_ca_overlay) { +CALayerOverlayProcessor::CALayerOverlayProcessor() + : overlays_allowed_(ui::RemoteLayerAPISupported()), + enable_ca_renderer_(base::FeatureList::IsEnabled(kCARenderer)), + enable_hdr_underlays_(base::FeatureList::IsEnabled(kHDRUnderlays)) { max_quad_list_size_ = kTooManyQuads; if (base::FeatureList::IsEnabled(features::kMacCAOverlayQuad)) { const int max_num = features::kMacCAOverlayQuadMaxNum.Get(); @@ -432,9 +445,12 @@ gfx::ProtectedVideoType::kHardwareProtected) force_quad_to_overlay = true; - // Put HDR videos into an overlay - if (resource_provider->GetColorSpace(texture_quad->resource_id()).IsHDR()) - force_quad_to_overlay = true; + // Put HDR videos into an underlay. + if (enable_hdr_underlays_) { + if (resource_provider->GetColorSpace(texture_quad->resource_id()) + .IsHDR()) + force_quad_to_overlay = true; + } } if (force_quad_to_overlay) { @@ -465,7 +481,7 @@ size_t num_visible_quads = quad_list.size(); // Skip overlay processing - if (!enable_ca_overlay_) { + if (!overlays_allowed_ || !enable_ca_renderer_) { result = CA_LAYER_FAILED_OVERLAY_DISABLED; } else if (!render_pass->copy_requests.empty()) { result = CA_LAYER_FAILED_COPY_REQUESTS;
diff --git a/components/viz/service/display/ca_layer_overlay.h b/components/viz/service/display/ca_layer_overlay.h index 9c41055..c06d56c 100644 --- a/components/viz/service/display/ca_layer_overlay.h +++ b/components/viz/service/display/ca_layer_overlay.h
@@ -95,8 +95,7 @@ // CALayerOverlay into OverlayCandidate. class VIZ_SERVICE_EXPORT CALayerOverlayProcessor { public: - explicit CALayerOverlayProcessor(bool enable_ca_overlay); - + CALayerOverlayProcessor(); CALayerOverlayProcessor(const CALayerOverlayProcessor&) = delete; CALayerOverlayProcessor& operator=(const CALayerOverlayProcessor&) = delete; @@ -146,7 +145,17 @@ void SaveCALayerResult(int result); - const bool enable_ca_overlay_; + // Set to false if the APIs required for overlays are not present, or the + // feature has been disabled. + const bool overlays_allowed_; + + // Controls the feature of replacying all quads with overlays is enabled. + const bool enable_ca_renderer_; + + // Controls the feature of putting HDR videos into underlays if the + // CARenderer fails (so that we can use the tone mapping provided by macOS). + const bool enable_hdr_underlays_; + size_t max_quad_list_size_ = 0; int ca_layer_result_ = 0; };
diff --git a/components/viz/service/display/frame_rate_decider.cc b/components/viz/service/display/frame_rate_decider.cc index b5c392d..e1deba9c 100644 --- a/components/viz/service/display/frame_rate_decider.cc +++ b/components/viz/service/display/frame_rate_decider.cc
@@ -212,11 +212,15 @@ // ideal refresh rate. base::TimeDelta new_preferred_interval = UnspecifiedFrameInterval(); if (*min_frame_sink_interval != BeginFrameArgs::MinInterval()) { + base::TimeDelta min_delta = base::TimeDelta::Max(); for (auto supported_interval : supported_intervals_) { - // Pick the display interval which is closest to the preferred interval. - if ((*min_frame_sink_interval - supported_interval).magnitude() < - (*min_frame_sink_interval - new_preferred_interval).magnitude()) { + // Pick the display interval which is closest to the preferred interval + // and less than or equal to the min_frame_sink_interval. + base::TimeDelta delta = (*min_frame_sink_interval - supported_interval); + if (AreAlmostEqual(*min_frame_sink_interval, supported_interval) || + (delta.is_positive() && delta < min_delta)) { new_preferred_interval = supported_interval; + min_delta = delta.magnitude(); } } }
diff --git a/components/viz/service/display/frame_rate_decider_unittest.cc b/components/viz/service/display/frame_rate_decider_unittest.cc index 8db6a25..8a68c6b 100644 --- a/components/viz/service/display/frame_rate_decider_unittest.cc +++ b/components/viz/service/display/frame_rate_decider_unittest.cc
@@ -286,6 +286,23 @@ frame_rate_decider_->OnSurfaceWillBeDrawn(surface2); } EXPECT_EQ(display_interval_, min_supported_interval * 2); + + FrameSinkId frame_sink_id3(1u, 3u); + preferred_intervals_[frame_sink_id3] = min_supported_interval * 1.8; + auto* surface3 = CreateAndDrawSurface(frame_sink_id3); + UpdateFrame(surface1); + UpdateFrame(surface2); + UpdateFrame(surface3); + { + FrameRateDecider::ScopedAggregate scope(frame_rate_decider_.get()); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface1); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface2); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface3); + } + // Even though surface3 has a frame interval that is closer to + // min_supported_interval * 2, we need to pick a smaller interval + // so that frames from that surface are not dropped. + EXPECT_EQ(display_interval_, min_supported_interval); } TEST_F(FrameRateDeciderTest, TogglesAfterMinNumOfFrames) {
diff --git a/components/viz/service/display/overlay_processor_mac.cc b/components/viz/service/display/overlay_processor_mac.cc index 4d4886ff..b4658a1 100644 --- a/components/viz/service/display/overlay_processor_mac.cc +++ b/components/viz/service/display/overlay_processor_mac.cc
@@ -7,32 +7,18 @@ #include <utility> #include <vector> -#include "base/feature_list.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/output_surface.h" -#include "ui/base/cocoa/remote_layer_api.h" #include "ui/gfx/geometry/rect_conversions.h" namespace viz { -namespace { -// Control using the CoreAnimation renderer, which is the path that replaces -// all quads with CALayers. -base::Feature kCoreAnimationRenderer{"CoreAnimationRenderer", - base::FEATURE_ENABLED_BY_DEFAULT}; - -bool AllowCoreAnimationRenderer() { - return ui::RemoteLayerAPISupported() && - base::FeatureList::IsEnabled(kCoreAnimationRenderer); -} -} // namespace - OverlayProcessorMac::OverlayProcessorMac() - : ca_layer_overlay_processor_(std::make_unique<CALayerOverlayProcessor>( - AllowCoreAnimationRenderer())) {} + : ca_layer_overlay_processor_(std::make_unique<CALayerOverlayProcessor>()) { +} OverlayProcessorMac::OverlayProcessorMac( std::unique_ptr<CALayerOverlayProcessor> ca_layer_overlay_processor)
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index da0221a..bf5dddcf 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -2173,7 +2173,9 @@ quad_alpha = 1.f; DCHECK(cf); } - paint.setColorFilter(cf->makeComposed(paint.refColorFilter())); + // |cf| could be null if alpha in |quad->background_color| is 0. + if (cf) + paint.setColorFilter(cf->makeComposed(paint.refColorFilter())); } if (needs_color_conversion_filter) { @@ -2210,8 +2212,9 @@ quad->tex_coord_rect, gfx::RectF(quad->rect), params->visible_rect); bool translate_only = params->content_device_transform.matrix().isTranslate(); - UMA_HISTOGRAM_BOOLEAN("SkiaRenderer.DrawTileDrawQuad.CDT.TranslateOnly", - translate_only); + UMA_HISTOGRAM_BOOLEAN( + "Compositing.SkiaRenderer.DrawTileDrawQuad.CDT.IsTranslateOnly", + translate_only); if (builder.paint_op_buffer()) { DCHECK(!rpdq_params); DrawPaintOpBuffer(builder.paint_op_buffer(), builder.clear_color(), quad,
diff --git a/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java b/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java index 29b137d..6b863ff9 100644 --- a/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java +++ b/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java
@@ -4,41 +4,49 @@ package org.chromium.components.viz.service.frame_sinks; -import org.chromium.base.ContextUtils; +import android.view.Choreographer; + +import org.chromium.base.TraceEvent; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; import org.chromium.base.annotations.NativeMethods; -import org.chromium.ui.VSyncMonitor; /** * Provides a VSyncMonitor backed BeginFrameSource. */ @JNINamespace("viz") @MainDex -public class ExternalBeginFrameSourceAndroid { +public class ExternalBeginFrameSourceAndroid implements Choreographer.FrameCallback { + private static final long NANOSECONDS_PER_SECOND = 1000000000; + private static final long NANOSECONDS_PER_MICROSECOND = 1000; + + // Conservative guess about vsync's consecutivity. + // If true, next tick is guaranteed to be consecutive. + private boolean mConsecutiveVSync; + private boolean mInsideVSync; + + // Display refresh rate as reported by the system. + private long mRefreshPeriodNano; + private boolean mUseEstimatedRefreshRate; + + private boolean mHaveRequestInFlight; + + private final Choreographer mChoreographer; + private long mGoodStartingPointNano; + private final long mNativeExternalBeginFrameSourceAndroid; private boolean mVSyncNotificationsEnabled; - private final VSyncMonitor mVSyncMonitor; - private final VSyncMonitor.Listener mVSyncListener = new VSyncMonitor.Listener() { - @Override - public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) { - if (!mVSyncNotificationsEnabled) { - return; - } - ExternalBeginFrameSourceAndroidJni.get().onVSync(mNativeExternalBeginFrameSourceAndroid, - ExternalBeginFrameSourceAndroid.this, vsyncTimeMicros, - mVSyncMonitor.getVSyncPeriodInMicroseconds()); - mVSyncMonitor.requestUpdate(); - } - }; @CalledByNative private ExternalBeginFrameSourceAndroid( long nativeExternalBeginFrameSourceAndroid, float refreshRate) { + updateRefreshRate(refreshRate); + + mChoreographer = Choreographer.getInstance(); + mGoodStartingPointNano = getCurrentNanoTime(); + mNativeExternalBeginFrameSourceAndroid = nativeExternalBeginFrameSourceAndroid; - mVSyncMonitor = - new VSyncMonitor(ContextUtils.getApplicationContext(), mVSyncListener, refreshRate); } @CalledByNative @@ -49,13 +57,58 @@ mVSyncNotificationsEnabled = enabled; if (mVSyncNotificationsEnabled) { - mVSyncMonitor.requestUpdate(); + postCallback(); } } @CalledByNative private void updateRefreshRate(float refreshRate) { - mVSyncMonitor.updateRefreshRate(refreshRate); + mUseEstimatedRefreshRate = refreshRate < 30; + if (refreshRate <= 0) refreshRate = 60; + mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate); + } + + private void postCallback() { + if (mHaveRequestInFlight) return; + mHaveRequestInFlight = true; + mConsecutiveVSync = mInsideVSync; + mChoreographer.postFrameCallback(this); + } + + @Override + public void doFrame(long frameTimeNanos) { + TraceEvent.begin("VSync"); + try { + if (mUseEstimatedRefreshRate && mConsecutiveVSync) { + // Display.getRefreshRate() is unreliable on some platforms. + // Adjust refresh period- initial value is based on Display.getRefreshRate() + // after that it asymptotically approaches the real value. + long lastRefreshDurationNano = frameTimeNanos - mGoodStartingPointNano; + float lastRefreshDurationWeight = 0.1f; + mRefreshPeriodNano += (long) (lastRefreshDurationWeight + * (lastRefreshDurationNano - mRefreshPeriodNano)); + } + mGoodStartingPointNano = frameTimeNanos; + mInsideVSync = true; + assert mHaveRequestInFlight; + mHaveRequestInFlight = false; + + if (!mVSyncNotificationsEnabled) { + return; + } + ExternalBeginFrameSourceAndroidJni.get().onVSync(mNativeExternalBeginFrameSourceAndroid, + ExternalBeginFrameSourceAndroid.this, + frameTimeNanos / NANOSECONDS_PER_MICROSECOND, + mRefreshPeriodNano / NANOSECONDS_PER_MICROSECOND); + postCallback(); + } finally { + mInsideVSync = false; + TraceEvent.end("VSync"); + } + } + + private long getCurrentNanoTime() { + return System.nanoTime(); } @NativeMethods @@ -64,4 +117,4 @@ ExternalBeginFrameSourceAndroid caller, long vsyncTimeMicros, long vsyncPeriodMicros); } -}; +}
diff --git a/components/viz/service/main/viz_compositor_thread_runner.h b/components/viz/service/main/viz_compositor_thread_runner.h index c25dfc44..6db9cd8 100644 --- a/components/viz/service/main/viz_compositor_thread_runner.h +++ b/components/viz/service/main/viz_compositor_thread_runner.h
@@ -6,6 +6,7 @@ #define COMPONENTS_VIZ_SERVICE_MAIN_VIZ_COMPOSITOR_THREAD_RUNNER_H_ #include "base/callback.h" +#include "base/threading/platform_thread.h" #include "services/viz/privileged/mojom/viz_main.mojom.h" namespace base {
diff --git a/components/winhttp/network_fetcher.cc b/components/winhttp/network_fetcher.cc index ca2035e..c246ec30 100644 --- a/components/winhttp/network_fetcher.cc +++ b/components/winhttp/network_fetcher.cc
@@ -76,7 +76,7 @@ void NetworkFetcher::CompleteFetch() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!file_.IsValid()) { - std::move(fetch_complete_callback_).Run(); + std::move(fetch_complete_callback_).Run(response_code_); return; } base::ThreadPool::PostTaskAndReply( @@ -295,9 +295,8 @@ WINHTTP_HEADER_NAME_BY_INDEX, &all); VLOG(3) << "response headers: " << all; - int response_code = 0; net_error_ = QueryHeadersInt(request_handle_.get(), WINHTTP_QUERY_STATUS_CODE, - WINHTTP_HEADER_NAME_BY_INDEX, &response_code); + WINHTTP_HEADER_NAME_BY_INDEX, &response_code_); if (FAILED(net_error_)) { CompleteFetch(); return; @@ -312,7 +311,7 @@ return; } - std::move(fetch_started_callback_).Run(response_code, content_length); + std::move(fetch_started_callback_).Run(response_code_, content_length); // Start reading the body of response. net_error_ = ReadData();
diff --git a/components/winhttp/network_fetcher.h b/components/winhttp/network_fetcher.h index 0265922..b2655f2 100644 --- a/components/winhttp/network_fetcher.h +++ b/components/winhttp/network_fetcher.h
@@ -34,7 +34,7 @@ // as it is accessed from the main thread and the worker threads in WinHTTP. class NetworkFetcher : public base::RefCountedThreadSafe<NetworkFetcher> { public: - using FetchCompleteCallback = base::OnceCallback<void()>; + using FetchCompleteCallback = base::OnceCallback<void(int response_code)>; using FetchStartedCallback = base::OnceCallback<void(int response_code, int64_t content_length)>; using FetchProgressCallback = base::RepeatingCallback<void(int64_t current)>; @@ -138,6 +138,7 @@ WriteDataCallback write_data_callback_; HRESULT net_error_ = S_OK; std::vector<char> read_buffer_; + int response_code_ = 0; std::string post_response_body_; base::FilePath file_path_; base::File file_;
diff --git a/components/winhttp/network_fetcher_unittest.cc b/components/winhttp/network_fetcher_unittest.cc index 0b301aa94..37fa6bc 100644 --- a/components/winhttp/network_fetcher_unittest.cc +++ b/components/winhttp/network_fetcher_unittest.cc
@@ -31,9 +31,9 @@ /*fetch_started_callback*/ base::BindOnce([](int response_code, int64_t content_length) {}), /*fetch_progress_callback*/ base::BindRepeating([](int64_t current) {}), - /*fetch_complete_callback*/ base::BindLambdaForTesting([&run_loop]() { - run_loop.Quit(); - })); + /*fetch_complete_callback*/ + base::BindLambdaForTesting( + [&run_loop](int response_code) { run_loop.Quit(); })); run_loop.Run(); EXPECT_EQ(network_fetcher->GetNetError(), E_INVALIDARG); } @@ -51,9 +51,9 @@ /*fetch_started_callback*/ base::BindOnce([](int response_code, int64_t content_length) {}), /*fetch_progress_callback*/ base::BindRepeating([](int64_t current) {}), - /*fetch_complete_callback*/ base::BindLambdaForTesting([&run_loop]() { - run_loop.Quit(); - })); + /*fetch_complete_callback*/ + base::BindLambdaForTesting( + [&run_loop](int response_code) { run_loop.Quit(); })); run_loop.Run(); EXPECT_EQ(network_fetcher->GetNetError(), E_INVALIDARG); }
diff --git a/components/zucchini/abs32_utils.cc b/components/zucchini/abs32_utils.cc index ad1c85e3..7bf1700 100644 --- a/components/zucchini/abs32_utils.cc +++ b/components/zucchini/abs32_utils.cc
@@ -89,12 +89,12 @@ Abs32RvaExtractorWin32::Abs32RvaExtractorWin32( ConstBufferView image, AbsoluteAddress&& addr, - const std::vector<offset_t>& abs32_locations, + const std::deque<offset_t>& abs32_locations, offset_t lo, offset_t hi) : image_(image), addr_(std::move(addr)) { CHECK_LE(lo, hi); - auto find_and_check = [this](const std::vector<offset_t>& locations, + auto find_and_check = [this](const std::deque<offset_t>& locations, offset_t offset) { auto it = std::lower_bound(locations.begin(), locations.end(), offset); // Ensure that |offset| does not straddle a reference body. @@ -167,12 +167,12 @@ size_t RemoveUntranslatableAbs32(ConstBufferView image, AbsoluteAddress&& addr, const AddressTranslator& translator, - std::vector<offset_t>* locations) { + std::deque<offset_t>* locations) { AddressTranslator::RvaToOffsetCache target_rva_checker(translator); Abs32RvaExtractorWin32 extractor(image, std::move(addr), *locations, 0, image.size()); Abs32ReaderWin32 reader(std::move(extractor), translator); - std::vector<offset_t>::iterator write_it = locations->begin(); + std::deque<offset_t>::iterator write_it = locations->begin(); // |reader| reads |locations| while |write_it| modifies it. However, there's // no conflict since read occurs before write, and can skip ahead. for (auto ref = reader.GetNext(); ref.has_value(); ref = reader.GetNext()) @@ -184,7 +184,7 @@ } size_t RemoveOverlappingAbs32Locations(uint32_t width, - std::vector<offset_t>* locations) { + std::deque<offset_t>* locations) { if (locations->size() <= 1) return 0;
diff --git a/components/zucchini/abs32_utils.h b/components/zucchini/abs32_utils.h index 07503b5..f528e754e 100644 --- a/components/zucchini/abs32_utils.h +++ b/components/zucchini/abs32_utils.h
@@ -8,7 +8,7 @@ #include <stddef.h> #include <stdint.h> -#include <vector> +#include <deque> #include "components/zucchini/address_translator.h" #include "components/zucchini/buffer_view.h" @@ -70,7 +70,7 @@ // length |addr.width()|) in |abs32_locations|. Abs32RvaExtractorWin32(ConstBufferView image, AbsoluteAddress&& addr, - const std::vector<offset_t>& abs32_locations, + const std::deque<offset_t>& abs32_locations, offset_t lo, offset_t hi); Abs32RvaExtractorWin32(Abs32RvaExtractorWin32&&); @@ -83,8 +83,8 @@ private: ConstBufferView image_; AbsoluteAddress addr_; - std::vector<offset_t>::const_iterator cur_abs32_; - std::vector<offset_t>::const_iterator end_abs32_; + std::deque<offset_t>::const_iterator cur_abs32_; + std::deque<offset_t>::const_iterator end_abs32_; }; // A reader for Win32 abs32 references that filters and translates results from @@ -130,12 +130,12 @@ size_t RemoveUntranslatableAbs32(ConstBufferView image, AbsoluteAddress&& addr, const AddressTranslator& translator, - std::vector<offset_t>* locations); + std::deque<offset_t>* locations); // Given a sorted list of abs32 |locations|, removes all elements whose body // (with |width| given) overlaps with the body of a previous element. size_t RemoveOverlappingAbs32Locations(uint32_t width, - std::vector<offset_t>* locations); + std::deque<offset_t>* locations); } // namespace zucchini
diff --git a/components/zucchini/abs32_utils_unittest.cc b/components/zucchini/abs32_utils_unittest.cc index ddbb685..3e02bba 100644 --- a/components/zucchini/abs32_utils_unittest.cc +++ b/components/zucchini/abs32_utils_unittest.cc
@@ -192,7 +192,7 @@ constexpr uint32_t kRvaBegin = 0x00C00000U; struct { std::vector<uint8_t> data32; - std::vector<offset_t> abs32_locations; // Assumtion: Sorted. + std::deque<offset_t> abs32_locations; // Assumption: Sorted. offset_t lo; // Assumption: In range, does not straddle |abs32_location|. offset_t hi; // Assumption: Also >= |lo|. std::vector<Reference> expected_refs; @@ -230,7 +230,7 @@ {{0x3U, 0x9U}}}, // No location given. {ParseHexString("FF FF FF FF 0C 00 C0 A0 00 00 C0 A0 FF FF FF FF"), - std::vector<offset_t>(), 0x0U, 0x10U, std::vector<Reference>()}, + std::deque<offset_t>(), 0x0U, 0x10U, std::vector<Reference>()}, // Simple alternation. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF " "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"), @@ -308,8 +308,8 @@ "06 00 C0 A0 26 59 41 31 02 00 C0 A0 26 59 41 31 " "FF FF FF BF 26 59 41 31 FF FF FF FF FF FF FF FF " "02 00 C0 A0 26 59 41 31 07 00 C0 A0 26 59 41 31"); - std::vector<offset_t> abs32_locations = {0x8U, 0x10U, 0x18U, 0x20U, - 0x28U, 0x30U, 0x38U, 0x40U}; + std::deque<offset_t> abs32_locations = {0x8U, 0x10U, 0x18U, 0x20U, + 0x28U, 0x30U, 0x38U, 0x40U}; offset_t lo = 0x10U; offset_t hi = 0x38U; std::vector<Reference> expected_refs = { @@ -336,7 +336,7 @@ std::vector<uint8_t> data(32U, 0xFFU); ConstBufferView image(data.data(), data.size()); - auto try_make = [&](std::vector<offset_t>&& abs32_locations, offset_t lo, + auto try_make = [&](std::deque<offset_t>&& abs32_locations, offset_t lo, offset_t hi) { Abs32RvaExtractorWin32 extractor(image, {bitness, kImageBase}, abs32_locations, lo, hi); @@ -359,7 +359,7 @@ bitness = kBit64; try_make({6U, 22U}, 0U, 32U); // |lo| > |hi|. - EXPECT_DEATH(try_make(std::vector<offset_t>(), 32U, 31U), ""); + EXPECT_DEATH(try_make(std::deque<offset_t>(), 32U, 31U), ""); try_make({6U, 22U}, 0U, 14U); try_make({6U, 22U}, 0U, 30U); try_make({6U, 22U}, 6U, 32U); @@ -468,10 +468,10 @@ const offset_t kAbsB = 0x54; // a:00000000 (bad: underflow) const offset_t kAbsC = 0x58; // a:2BCD1A18 = r:1A18 = 0x1C - std::vector<offset_t> locations = {kAbs1, kAbs2, kAbs3, kAbs4, kAbs5, kAbs6, - kAbs7, kAbs8, kAbs9, kAbsA, kAbsB, kAbsC}; - std::vector<offset_t> exp_locations = {kAbs1, kAbs2, kAbs3, kAbs4, - kAbs5, kAbs6, kAbs9, kAbsC}; + std::deque<offset_t> locations = {kAbs1, kAbs2, kAbs3, kAbs4, kAbs5, kAbs6, + kAbs7, kAbs8, kAbs9, kAbsA, kAbsB, kAbsC}; + std::deque<offset_t> exp_locations = {kAbs1, kAbs2, kAbs3, kAbs4, + kAbs5, kAbs6, kAbs9, kAbsC}; size_t exp_num_removed = locations.size() - exp_locations.size(); size_t num_removed = RemoveUntranslatableAbs32(image, {kBitness, kImageBase}, translator, &locations); @@ -483,8 +483,8 @@ // Make |width| a state to reduce repetition. uint32_t width = WidthOf(kBit32); - auto run_test = [&width](const std::vector<offset_t>& expected_locations, - std::vector<offset_t>&& locations) { + auto run_test = [&width](const std::deque<offset_t>& expected_locations, + std::deque<offset_t>&& locations) { ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end())); size_t expected_removals = locations.size() - expected_locations.size(); size_t removals = RemoveOverlappingAbs32Locations(width, &locations); @@ -494,7 +494,7 @@ // 32-bit tests. width = WidthOf(kBit32); - run_test(std::vector<offset_t>(), std::vector<offset_t>()); + run_test(std::deque<offset_t>(), std::deque<offset_t>()); run_test({4U}, {4U}); run_test({4U, 10U}, {4U, 10U}); run_test({4U, 8U}, {4U, 8U}); @@ -518,7 +518,7 @@ // 64-bit tests. width = WidthOf(kBit64); - run_test(std::vector<offset_t>(), std::vector<offset_t>()); + run_test(std::deque<offset_t>(), std::deque<offset_t>()); run_test({4U}, {4U}); run_test({4U, 20U}, {4U, 20U}); run_test({4U, 12U}, {4U, 12U});
diff --git a/components/zucchini/disassembler_elf.h b/components/zucchini/disassembler_elf.h index a821920..8b834fa2 100644 --- a/components/zucchini/disassembler_elf.h +++ b/components/zucchini/disassembler_elf.h
@@ -238,7 +238,7 @@ std::vector<const typename Traits::Elf_Shdr*> exec_headers_; // Sorted file offsets of abs32 locations. - std::vector<offset_t> abs32_locations_; + std::deque<offset_t> abs32_locations_; }; // Disassembler for ELF with Intel architectures.
diff --git a/components/zucchini/disassembler_win32.h b/components/zucchini/disassembler_win32.h index fdfdbb0c..d711215e 100644 --- a/components/zucchini/disassembler_win32.h +++ b/components/zucchini/disassembler_win32.h
@@ -114,7 +114,7 @@ BufferRegion reloc_region_ = {kInvalidOffset, 0U}; std::vector<offset_t> reloc_block_offsets_; offset_t reloc_end_ = 0; - std::vector<offset_t> abs32_locations_; + std::deque<offset_t> abs32_locations_; // Using std::deque to reduce peak memory footprint. std::deque<offset_t> rel32_locations_;
diff --git a/components/zucchini/rel32_finder.cc b/components/zucchini/rel32_finder.cc index 1ad89107..cdffb7c0 100644 --- a/components/zucchini/rel32_finder.cc +++ b/components/zucchini/rel32_finder.cc
@@ -14,7 +14,7 @@ Abs32GapFinder::Abs32GapFinder(ConstBufferView image, ConstBufferView region, - const std::vector<offset_t>& abs32_locations, + const std::deque<offset_t>& abs32_locations, size_t abs32_width) : base_(image.begin()), region_end_(region.end()),
diff --git a/components/zucchini/rel32_finder.h b/components/zucchini/rel32_finder.h index 3ebeb95b..1c507b0 100644 --- a/components/zucchini/rel32_finder.h +++ b/components/zucchini/rel32_finder.h
@@ -7,7 +7,7 @@ #include <stddef.h> -#include <vector> +#include <deque> #include "components/zucchini/address_translator.h" #include "components/zucchini/arm_utils.h" @@ -47,7 +47,7 @@ // which must be part of |image|. Abs32GapFinder(ConstBufferView image, ConstBufferView region, - const std::vector<offset_t>& abs32_locations, + const std::deque<offset_t>& abs32_locations, size_t abs32_width); Abs32GapFinder(const Abs32GapFinder&) = delete; const Abs32GapFinder& operator=(const Abs32GapFinder&) = delete; @@ -63,8 +63,8 @@ const ConstBufferView::const_iterator base_; const ConstBufferView::const_iterator region_end_; ConstBufferView::const_iterator cur_lo_; - const std::vector<offset_t>::const_iterator abs32_end_; - std::vector<offset_t>::const_iterator abs32_cur_; + const std::deque<offset_t>::const_iterator abs32_end_; + std::deque<offset_t>::const_iterator abs32_cur_; const size_t abs32_width_; ConstBufferView gap_; };
diff --git a/components/zucchini/rel32_finder_unittest.cc b/components/zucchini/rel32_finder_unittest.cc index 7e4a21ed..c1e42492 100644 --- a/components/zucchini/rel32_finder_unittest.cc +++ b/components/zucchini/rel32_finder_unittest.cc
@@ -8,6 +8,7 @@ #include <stdint.h> #include <algorithm> +#include <deque> #include <iterator> #include <string> #include <utility> @@ -32,7 +33,7 @@ // Common test code that returns the resulting segments as a string. auto run_test = [&](size_t rlo, size_t rhi, - std::vector<offset_t> abs32_locations, + std::deque<offset_t> abs32_locations, std::ptrdiff_t abs32_width) -> std::string { CHECK_LE(rlo, kRegionTotal); CHECK_LE(rhi, kRegionTotal); @@ -263,8 +264,8 @@ ConstBufferView image = ConstBufferView::FromRange(std::begin(kDataX86), std::end(kDataX86)); - std::vector<offset_t> abs32_locations(std::begin(kAbs32X86), - std::end(kAbs32X86)); + std::deque<offset_t> abs32_locations(std::begin(kAbs32X86), + std::end(kAbs32X86)); std::vector<TruncatedResults> results; Abs32GapFinder gap_finder(image, image, abs32_locations, @@ -427,8 +428,8 @@ ConstBufferView image = ConstBufferView::FromRange(std::begin(kDataX64), std::end(kDataX64)); - std::vector<offset_t> abs32_locations(std::begin(kAbs32X64), - std::end(kAbs32X64)); + std::deque<offset_t> abs32_locations(std::begin(kAbs32X64), + std::end(kAbs32X64)); std::vector<TruncatedResults> results; Abs32GapFinder gap_finder(image, image, abs32_locations, @@ -478,7 +479,7 @@ template <class REL32_FINDER> std::vector<typename REL32_FINDER::Result> ArmExtractRel32( ConstBufferView image, - const std::vector<offset_t>& abs32_locations, + const std::deque<offset_t>& abs32_locations, int abs32_width, REL32_FINDER&& rel32_finder) { std::vector<typename REL32_FINDER::Result> results; @@ -552,8 +553,8 @@ ConstBufferView image = ConstBufferView::FromRange( std::begin(kDataAarch32ArmMode), std::end(kDataAarch32ArmMode)); - std::vector<offset_t> abs32_locations(std::begin(kAbs32Aarch32ArmMode), - std::end(kAbs32Aarch32ArmMode)); + std::deque<offset_t> abs32_locations(std::begin(kAbs32Aarch32ArmMode), + std::end(kAbs32Aarch32ArmMode)); AddressTranslator translator(GetTrivialTranslator(image.size())); Rel32FinderAArch32 rel32_finder(image, translator, /* is_thumb2 */ false); @@ -653,8 +654,8 @@ ConstBufferView image = ConstBufferView::FromRange( std::begin(kDataAarch32Thumb2Mode), std::end(kDataAarch32Thumb2Mode)); - std::vector<offset_t> abs32_locations(std::begin(kAbs32Aarch32Thumb2Mode), - std::end(kAbs32Aarch32Thumb2Mode)); + std::deque<offset_t> abs32_locations(std::begin(kAbs32Aarch32Thumb2Mode), + std::end(kAbs32Aarch32Thumb2Mode)); AddressTranslator translator(GetTrivialTranslator(image.size())); Rel32FinderAArch32 rel32_finder(image, translator, /* is_thumb2 */ true); @@ -728,8 +729,8 @@ ConstBufferView image = ConstBufferView::FromRange(std::begin(kDataAarch64), std::end(kDataAarch64)); - std::vector<offset_t> abs32_locations(std::begin(kAbs32Aarch64), - std::end(kAbs32Aarch64)); + std::deque<offset_t> abs32_locations(std::begin(kAbs32Aarch64), + std::end(kAbs32Aarch64)); AddressTranslator translator(GetTrivialTranslator(image.size())); Rel32FinderAArch64 rel32_finder(image, translator);
diff --git a/content/BUILD.gn b/content/BUILD.gn index 87ececf3..4f6391ff 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn
@@ -97,6 +97,7 @@ "//gpu/ipc/common:vulkan_interface_webui_js", "//ui/base/mojom:mojom_js", "//ui/gfx/geometry/mojom:mojom_js", + "//ui/gfx/image/mojom:mojom_js", "//ui/gfx/range/mojom:mojom_js", "//url/mojom:url_mojom_origin_js", "//url/mojom:url_mojom_origin_webui_js",
diff --git a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h new file mode 100644 index 0000000..e3267b5 --- /dev/null +++ b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h
@@ -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. + +#ifndef CONTENT_APP_SHIM_REMOTE_COCOA_WEB_CONTENTS_OCCLUSION_CHECKER_MAC_H_ +#define CONTENT_APP_SHIM_REMOTE_COCOA_WEB_CONTENTS_OCCLUSION_CHECKER_MAC_H_ + +#import <AppKit/AppKit.h> + +#import "content/app_shim_remote_cocoa/web_contents_view_cocoa.h" +#include "content/common/web_contents_ns_view_bridge.mojom.h" + +@interface WebContentsOcclusionCheckerMac : NSObject + ++ (instancetype)sharedInstance; +// Updates the visibility of the webContentsViewCocoa in `window`. +- (void)updateWebContentsVisibilityInWindow:(NSWindow*)window; +// Computes and updates the visibility of the `webContentsViewCocoa`. +- (void)updateWebContentsVisibility:(WebContentsViewCocoa*)webContentsViewCocoa; + +@end + +#endif // CONTENT_APP_SHIM_REMOTE_COCOA_WEB_CONTENTS_OCCLUSION_CHECKER_MAC_H_
diff --git a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm new file mode 100644 index 0000000..8f0cdcbc --- /dev/null +++ b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm
@@ -0,0 +1,349 @@ +// 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 "content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h" + +#include "base/auto_reset.h" +#include "base/feature_list.h" +#import "base/mac/scoped_objc_class_swizzler.h" +#include "base/no_destructor.h" + +namespace { + +const base::mac::ScopedObjCClassSwizzler* GetWindowClassSwizzler() { + static const base::NoDestructor<base::mac::ScopedObjCClassSwizzler> + window_class_swizzler([NSWindow class], + [WebContentsOcclusionCheckerMac class], + @selector(orderWindow:relativeTo:)); + return window_class_swizzler.get(); +} + +const base::Feature kMacWebContentsOcclusion{"MacWebContentsOcclusion", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::FeatureParam<bool> kEnhancedWindowOcclusionDetection{ + &kMacWebContentsOcclusion, "EnhancedWindowOcclusionDetection", false}; +const base::FeatureParam<bool> kDisplaySleepAndAppHideDetection{ + &kMacWebContentsOcclusion, "DisplaySleepAndAppHideDetection", false}; + +} // namespace + +@interface WebContentsOcclusionCheckerMac () { + NSWindow* _windowResizingMovingOrClosing; + NSWindow* _windowReceivingFullscreenTransitionNotifications; + BOOL _displaysAreAsleep; + BOOL _applicationReceivedHiddenNotification; +} +// Computes and returns the `window`'s visibility state, a hybrid of +// macOS's and our manual occlusion calculation. +- (remote_cocoa::mojom::Visibility)contentVisibilityStateForWindow: + (NSWindow*)window; +- (void)updateWebContentsVisibilityInWindow:(NSWindow*)window; + +@end + +@implementation WebContentsOcclusionCheckerMac + ++ (instancetype)sharedInstance { + static WebContentsOcclusionCheckerMac* sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + GetWindowClassSwizzler(); + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + + [self setUpNotifications]; + + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +// Alternative implementation of orderWindow:relativeTo:. Replaces +// NSWindow's version, allowing the occlusion checker to learn about +// window ordering events. +- (void)orderWindow:(NSWindowOrderingMode)orderingMode + relativeTo:(NSInteger)otherWindowNumber { + // Super. + GetWindowClassSwizzler() + ->InvokeOriginal<void, NSWindowOrderingMode, NSInteger>( + self, _cmd, orderingMode, otherWindowNumber); + + // The window order has changed so update web contents visibility. + [[WebContentsOcclusionCheckerMac sharedInstance] + notifyUpdateWebContentsVisibility]; +} + +- (void)setUpNotifications { + NSNotificationCenter* notificationCenter = + [NSNotificationCenter defaultCenter]; + + [notificationCenter + addObserver:self + selector:@selector(notifyUpdateWebContentsVisibility) + name:NSApplicationDidChangeOcclusionStateNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowWillMove:) + name:NSWindowWillMoveNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowDidMove:) + name:NSWindowDidMoveNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(notifyUpdateWebContentsVisibility) + name:NSWindowDidMoveNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowWillStartLiveResize:) + name:NSWindowWillStartLiveResizeNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowWillEndLiveResize) + name:NSWindowDidEndLiveResizeNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowChangedOcclusionState:) + name:NSWindowDidChangeOcclusionStateNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:nil]; + + [notificationCenter addObserver:self + selector:@selector(fullscreenTransitionStarted:) + name:NSWindowWillEnterFullScreenNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(fullscreenTransitionComplete:) + name:NSWindowDidEnterFullScreenNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(fullscreenTransitionStarted:) + name:NSWindowWillExitFullScreenNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(fullscreenTransitionComplete:) + name:NSWindowDidExitFullScreenNotification + object:nil]; + + [notificationCenter addObserver:self + selector:@selector(applicationDidHide) + name:NSApplicationDidHideNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(applicationDidUnhide) + name:NSApplicationDidUnhideNotification + object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] + addObserver:self + selector:@selector(displaysDidSleep:) + name:NSWorkspaceScreensDidSleepNotification + object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] + addObserver:self + selector:@selector(displaysDidWake:) + name:NSWorkspaceScreensDidWakeNotification + object:nil]; +} + +- (void)windowWillClose:(NSNotification*)notification { + base::AutoReset<NSWindow*> tmp(&_windowResizingMovingOrClosing, + [notification object]); + [self notifyUpdateWebContentsVisibility]; +} + +- (void)windowWillMove:(NSNotification*)notification { + base::AutoReset<NSWindow*> tmp(&_windowResizingMovingOrClosing, + [notification object]); + [self notifyUpdateWebContentsVisibility]; +} + +- (void)windowDidMove:(NSNotification*)notification { + [self notifyUpdateWebContentsVisibility]; +} + +- (void)windowWillStartLiveResize:(NSNotification*)notification { + _windowResizingMovingOrClosing = [notification object]; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)windowWillEndLiveResize { + _windowResizingMovingOrClosing = nil; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)windowChangedOcclusionState:(NSNotification*)notification { + [self updateWebContentsVisibilityInWindow:[notification object]]; +} + +- (void)displaysDidSleep:(NSNotification*)notification { + // Ignore if display sleep and application hide detection are disabled by the + // experiment. + if (!kDisplaySleepAndAppHideDetection.Get()) { + return; + } + + _displaysAreAsleep = YES; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)displaysDidWake:(NSNotification*)notification { + // Ignore if display sleep and application hide detection are disabled by the + // experiment. + if (!kDisplaySleepAndAppHideDetection.Get()) { + return; + } + + _displaysAreAsleep = NO; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)applicationDidHide { + // Ignore if display sleep and application hide detection are disabled by the + // experiment. + if (!kDisplaySleepAndAppHideDetection.Get()) { + return; + } + + // Use the reception of this notification as an indication of the + // application's hidden state because [[NSRunningApplication + // currentApplication] isHidden] does not appear to return true when this + // notification fires. + _applicationReceivedHiddenNotification = YES; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)applicationDidUnhide { + // Ignore if display sleep and application hide detection are disabled by the + // experiment. + if (!kDisplaySleepAndAppHideDetection.Get()) { + return; + } + + _applicationReceivedHiddenNotification = NO; + [self notifyUpdateWebContentsVisibility]; +} + +- (void)fullscreenTransitionStarted:(NSNotification*)notification { + _windowReceivingFullscreenTransitionNotifications = [notification object]; +} + +- (void)fullscreenTransitionComplete:(NSNotification*)notification { + _windowReceivingFullscreenTransitionNotifications = nil; +} + +- (void)notifyUpdateWebContentsVisibility { + for (NSWindow* window in [[NSApplication sharedApplication] orderedWindows]) { + [self updateWebContentsVisibilityInWindow:window]; + } +} + +- (void)updateWebContentsVisibilityInWindow:(NSWindow*)window { + // The fullscreen transition causes spurious occlusion notifications. + // See https://crbug.com/1081229 + if (window == _windowReceivingFullscreenTransitionNotifications) + return; + + // If there's no web contents in the window there's nothing to do. + NSArray<WebContentsViewCocoa*>* webContentsViewCocoaInWindow = + [window webContentsViewCocoa]; + if (webContentsViewCocoaInWindow.count == 0) { + return; + } + + remote_cocoa::mojom::Visibility windowVisibilityState = + [self contentVisibilityStateForWindow:window]; + + for (WebContentsViewCocoa* webContentsViewCocoa in + webContentsViewCocoaInWindow) { + remote_cocoa::mojom::Visibility visibilityState = + [webContentsViewCocoa isHiddenOrHasHiddenAncestor] + ? remote_cocoa::mojom::Visibility::kHidden + : windowVisibilityState; + [webContentsViewCocoa updateWebContentsVisibility:visibilityState]; + } +} + +- (remote_cocoa::mojom::Visibility)contentVisibilityStateForWindow: + (NSWindow*)window { + if (_displaysAreAsleep || _applicationReceivedHiddenNotification || + [window isMiniaturized] || ![window isVisible]) { + return remote_cocoa::mojom::Visibility::kHidden; + } + + BOOL windowOccluded = + !([window occlusionState] & NSWindowOcclusionStateVisible); + if (windowOccluded) { + // If macOS says the window is occluded, take that answer. + return remote_cocoa::mojom::Visibility::kOccluded; + } + + // If manual occlusion detection is disabled in the experiement, return the + // answer from macOS. + if (!kEnhancedWindowOcclusionDetection.Get()) { + return remote_cocoa::mojom::Visibility::kVisible; + } + + NSRect windowFrame = [window frame]; + + NSArray<NSWindow*>* windowsFromFrontToBack = + [[NSApplication sharedApplication] orderedWindows]; + + // Determine if there's a window occluding our window. + for (NSWindow* nextWindow in windowsFromFrontToBack) { + if (![nextWindow isVisible]) { + continue; + } + + // If we come to our window in the list we're done. + if (nextWindow == window) { + break; + } + + // If the next window is closing, moving, or resizing, treat it as if it + // doesn't exist so that if it currently occludes our web contents we + // transition from kOccluded to kVisible. That way our content, if it + // becomes visible, is fresh. We'll recompute our visibility status after + // the resize, move, or close completes. + if (nextWindow == _windowResizingMovingOrClosing) { + continue; + } + + // Ideally we'd compute the region which is the sum of all windows above us + // and see if it completely contains our web contents. Unfortunately we + // don't have a library that can perform general purpose region arithmetic. + // For example if we have windows A and B side-by-side at first glance it + // might seem like enough to just union the two frames. The problem is the + // small regions at the top and bottom of the windows where the curved + // corners meet. If A and B cover C we can't know if a portion of C shows + // through these regions. The best we can do is see if any single browser + // window above completely contains our frame. + if (NSContainsRect([nextWindow frame], windowFrame)) { + return remote_cocoa::mojom::Visibility::kOccluded; + } + } + + return remote_cocoa::mojom::Visibility::kVisible; +} + +- (void)updateWebContentsVisibility: + (WebContentsViewCocoa*)webContentsViewCocoa { + remote_cocoa::mojom::Visibility contentVisibilityState = + [self contentVisibilityStateForWindow:[webContentsViewCocoa window]]; + + [webContentsViewCocoa updateWebContentsVisibility:contentVisibilityState]; +} + +@end
diff --git a/content/app_shim_remote_cocoa/web_contents_view_cocoa.h b/content/app_shim_remote_cocoa/web_contents_view_cocoa.h index eb42756..4070e79a 100644 --- a/content/app_shim_remote_cocoa/web_contents_view_cocoa.h +++ b/content/app_shim_remote_cocoa/web_contents_view_cocoa.h
@@ -7,6 +7,7 @@ #include "base/mac/scoped_nsobject.h" #include "content/common/content_export.h" +#include "content/common/web_contents_ns_view_bridge.mojom.h" #import "ui/base/cocoa/base_view.h" #import "ui/base/cocoa/views_hostable.h" @@ -69,8 +70,14 @@ image:(NSImage*)image offset:(NSPoint)offset; - (void)clearViewsHostableView; -- (void)updateWebContentsVisibility; +- (void)updateWebContentsVisibility: + (remote_cocoa::mojom::Visibility)visibilityState; - (void)viewDidBecomeFirstResponder:(NSNotification*)notification; @end +@interface NSWindow (WebContentsViewCocoa) +// Returns all the WebContentsViewCocoas in the window. +- (NSArray<WebContentsViewCocoa*>*)webContentsViewCocoa; +@end + #endif // CONTENT_APP_SHIM_REMOTE_COCOA_WEB_CONTENTS_VIEW_COCOA_H_
diff --git a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm index af343838d..b4fc6bb 100644 --- a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm +++ b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm
@@ -7,9 +7,9 @@ #import "content/browser/web_contents/web_contents_view_mac.h" #import "base/mac/mac_util.h" +#import "content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h" #import "content/app_shim_remote_cocoa/web_drag_source_mac.h" #import "content/browser/web_contents/web_drag_dest_mac.h" -#include "content/common/web_contents_ns_view_bridge.mojom.h" #import "third_party/mozilla/NSPasteboard+Utils.h" #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/custom_data_helper.h" @@ -22,7 +22,6 @@ using remote_cocoa::mojom::DraggingInfo; using remote_cocoa::mojom::SelectionDirection; -using remote_cocoa::mojom::Visibility; using content::DropData; namespace { @@ -104,8 +103,11 @@ //////////////////////////////////////////////////////////////////////////////// // WebContentsViewCocoa -@implementation WebContentsViewCocoa { - BOOL _inFullScreenTransition; +@implementation WebContentsViewCocoa + ++ (void)initialize { + // Create the WebContentsOcclusionCheckerMac shared instance. + [WebContentsOcclusionCheckerMac sharedInstance]; } - (instancetype)initWithViewsHostableView:(ui::ViewsHostableView*)v { @@ -362,17 +364,10 @@ _host->OnBecameFirstResponder(direction); } -- (void)updateWebContentsVisibility { - if (!_host || _inFullScreenTransition) - return; - Visibility visibility = Visibility::kVisible; - if ([self isHiddenOrHasHiddenAncestor] || ![self window]) - visibility = Visibility::kHidden; - else if ([[self window] occlusionState] & NSWindowOcclusionStateVisible) - visibility = Visibility::kVisible; - else - visibility = Visibility::kOccluded; - _host->OnWindowVisibilityChanged(visibility); +- (void)updateWebContentsVisibility: + (remote_cocoa::mojom::Visibility)visibility { + if (_host) + _host->OnWindowVisibilityChanged(visibility); } - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { @@ -391,74 +386,22 @@ [subview setFrame:[self bounds]]; } -- (void)viewWillMoveToWindow:(NSWindow*)newWindow { - NSWindow* oldWindow = [self window]; - NSNotificationCenter* notificationCenter = - [NSNotificationCenter defaultCenter]; - - _inFullScreenTransition = NO; - if (oldWindow) { - NSArray* notificationsToRemove = @[ - NSWindowDidChangeOcclusionStateNotification, - NSWindowWillEnterFullScreenNotification, - NSWindowDidEnterFullScreenNotification, - NSWindowWillExitFullScreenNotification, - NSWindowDidExitFullScreenNotification - ]; - for (NSString* notificationName in notificationsToRemove) { - [notificationCenter removeObserver:self - name:notificationName - object:oldWindow]; - } - } - if (newWindow) { - [notificationCenter addObserver:self - selector:@selector(windowChangedOcclusionState:) - name:NSWindowDidChangeOcclusionStateNotification - object:newWindow]; - // The fullscreen transition causes spurious occlusion notifications. - // See https://crbug.com/1081229 - [notificationCenter addObserver:self - selector:@selector(fullscreenTransitionStarted:) - name:NSWindowWillEnterFullScreenNotification - object:newWindow]; - [notificationCenter addObserver:self - selector:@selector(fullscreenTransitionComplete:) - name:NSWindowDidEnterFullScreenNotification - object:newWindow]; - [notificationCenter addObserver:self - selector:@selector(fullscreenTransitionStarted:) - name:NSWindowWillExitFullScreenNotification - object:newWindow]; - [notificationCenter addObserver:self - selector:@selector(fullscreenTransitionComplete:) - name:NSWindowDidExitFullScreenNotification - object:newWindow]; - } -} - -- (void)windowChangedOcclusionState:(NSNotification*)notification { - [self updateWebContentsVisibility]; -} - -- (void)fullscreenTransitionStarted:(NSNotification*)notification { - _inFullScreenTransition = YES; -} - -- (void)fullscreenTransitionComplete:(NSNotification*)notification { - _inFullScreenTransition = NO; -} - - (void)viewDidMoveToWindow { - [self updateWebContentsVisibility]; + if ([self window] == nil) { + [self updateWebContentsVisibility:remote_cocoa::mojom::Visibility::kHidden]; + } else { + [[WebContentsOcclusionCheckerMac sharedInstance] + updateWebContentsVisibility:self]; + } } - (void)viewDidHide { - [self updateWebContentsVisibility]; + [self updateWebContentsVisibility:remote_cocoa::mojom::Visibility::kHidden]; } - (void)viewDidUnhide { - [self updateWebContentsVisibility]; + [[WebContentsOcclusionCheckerMac sharedInstance] + updateWebContentsVisibility:self]; } // ViewsHostable protocol implementation. @@ -467,3 +410,31 @@ } @end + +@implementation NSWindow (WebContentsViewCocoa) + +// Collects the WebContentsViewCocoas contained in the view hierarchy +// rooted at `view` in the array `webContents`. +- (void)_addWebContentsViewCocoasFromView:(NSView*)view + toArray: + (NSMutableArray<WebContentsViewCocoa*>*) + webContents { + for (NSView* subview in [view subviews]) { + if ([subview isKindOfClass:[WebContentsViewCocoa class]]) { + [webContents addObject:(WebContentsViewCocoa*)subview]; + } else { + [self _addWebContentsViewCocoasFromView:subview toArray:webContents]; + } + } +} + +- (NSArray<WebContentsViewCocoa*>*)webContentsViewCocoa { + NSMutableArray<WebContentsViewCocoa*>* webContents = [NSMutableArray array]; + + [self _addWebContentsViewCocoasFromView:[self contentView] + toArray:webContents]; + + return webContents; +} + +@end
diff --git a/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm new file mode 100644 index 0000000..380d144 --- /dev/null +++ b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm
@@ -0,0 +1,717 @@ +// 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 "base/mac/scoped_nsobject.h" +#include "base/test/scoped_feature_list.h" +#import "content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/content_browser_test.h" + +using remote_cocoa::mojom::DraggingInfo; +using remote_cocoa::mojom::DraggingInfoPtr; +using remote_cocoa::mojom::SelectionDirection; +using content::DropData; + +namespace { +const base::Feature kMacWebContentsOcclusion{"MacWebContentsOcclusion", + base::FEATURE_DISABLED_BY_DEFAULT}; +const char kEnhancedWindowOcclusionDetection[] = + "EnhancedWindowOcclusionDetection"; +const char kDisplaySleepAndAppHideDetection[] = + "DisplaySleepAndAppHideDetection"; + +} // namespace + +// An NSWindow subclass that enables programmatic setting of macOS occlusion and +// miniaturize states. +@interface WebContentsHostWindowForOcclusionTesting : NSWindow { + BOOL _miniaturizedForTesting; +} +@property(assign, nonatomic) BOOL occludedForTesting; +@end + +@implementation WebContentsHostWindowForOcclusionTesting + +@synthesize occludedForTesting = _occludedForTesting; + +- (NSWindowOcclusionState)occlusionState { + return _occludedForTesting ? 0 : NSWindowOcclusionStateVisible; +} + +- (void)miniaturize:(id)sender { + // Miniaturizing a window doesn't immediately take effect (isMiniaturized + // returns false) so fake it with a flag and removal from window list. + _miniaturizedForTesting = YES; + [self orderOut:nil]; +} + +- (void)deminiaturize:(id)sender { + _miniaturizedForTesting = NO; + [self orderFront:nil]; +} + +- (BOOL)isMiniaturized { + return _miniaturizedForTesting; +} + +@end + +namespace content { + +// A stub class for WebContentsNSViewHost. +class WebContentsNSViewHostStub + : public remote_cocoa::mojom::WebContentsNSViewHost { + public: + WebContentsNSViewHostStub() {} + + void OnMouseEvent(bool motion, bool exited) override {} + + void OnBecameFirstResponder(SelectionDirection direction) override {} + + void OnWindowVisibilityChanged( + remote_cocoa::mojom::Visibility visibility) override { + _visibility = visibility; + } + + remote_cocoa::mojom::Visibility WebContentsVisibility() { + return _visibility; + } + + void SetDropData(const ::content::DropData& drop_data) override {} + + bool DraggingEntered(DraggingInfoPtr dragging_info, + uint32_t* out_result) override { + return false; + } + + void DraggingEntered(DraggingInfoPtr dragging_info, + DraggingEnteredCallback callback) override {} + + void DraggingExited() override {} + + void DraggingUpdated(DraggingInfoPtr dragging_info, + DraggingUpdatedCallback callback) override {} + + bool PerformDragOperation(DraggingInfoPtr dragging_info, + bool* out_result) override { + return false; + } + + void PerformDragOperation(DraggingInfoPtr dragging_info, + PerformDragOperationCallback callback) override {} + + bool DragPromisedFileTo(const ::base::FilePath& file_path, + const ::content::DropData& drop_data, + const ::GURL& download_url, + ::base::FilePath* out_file_path) override { + return false; + } + + void DragPromisedFileTo(const ::base::FilePath& file_path, + const ::content::DropData& drop_data, + const ::GURL& download_url, + DragPromisedFileToCallback callback) override {} + + void EndDrag(uint32_t drag_operation, + const ::gfx::PointF& local_point, + const ::gfx::PointF& screen_point) override {} + + private: + remote_cocoa::mojom::Visibility _visibility; +}; + +// Sets up occlusion tests. +class WindowOcclusionBrowserTestMac : public ContentBrowserTest { + public: + // Creates |window_a| with a visible (i.e. unoccluded) WebContentsViewCocoa. + void InitWindowA() { + const NSRect kWindowAContentRect = NSMakeRect(0.0, 0.0, 80.0, 60.0); + const NSWindowStyleMask kWindowStyleMask = NSWindowStyleMaskClosable; + window_a.reset([[WebContentsHostWindowForOcclusionTesting alloc] + initWithContentRect:kWindowAContentRect + styleMask:kWindowStyleMask + backing:NSBackingStoreBuffered + defer:YES]); + NSRect window_frame = [NSWindow frameRectForContentRect:kWindowAContentRect + styleMask:kWindowStyleMask]; + window_frame.origin = NSMakePoint(20.0, 200.0); + [window_a setFrame:window_frame display:NO]; + [window_a setTitle:@"window_a"]; + [window_a setReleasedWhenClosed:NO]; + + const NSRect kWebContentsFrame = NSMakeRect(0.0, 0.0, 10.0, 10.0); + window_a_web_contents_view_cocoa.reset( + [[WebContentsViewCocoa alloc] initWithFrame:kWebContentsFrame]); + [[window_a contentView] addSubview:window_a_web_contents_view_cocoa]; + + // Set up a fake host so we can check the occlusion status. + [window_a_web_contents_view_cocoa setHost:&_host_a]; + + // Bring the browser window onscreen. + OrderWindowFront(window_a); + + // Init visibility state. + SetWindowAWebContentsVisibility(remote_cocoa::mojom::Visibility::kVisible); + } + + void InitWindowB(NSRect window_frame = NSZeroRect) { + const NSRect kWindowBContentRect = NSMakeRect(0.0, 0.0, 40.0, 40.0); + const NSWindowStyleMask kWindowStyleMask = NSWindowStyleMaskClosable; + window_b.reset([[WebContentsHostWindowForOcclusionTesting alloc] + initWithContentRect:kWindowBContentRect + styleMask:kWindowStyleMask + backing:NSBackingStoreBuffered + defer:YES]); + [window_b setTitle:@"window_b"]; + [window_b setReleasedWhenClosed:NO]; + + if (NSIsEmptyRect(window_frame)) { + window_frame.size = [NSWindow frameRectForContentRect:kWindowBContentRect + styleMask:kWindowStyleMask] + .size; + } + [window_b setFrame:window_frame display:NO]; + + OrderWindowFront(window_b); + } + + void OrderWindowFront(NSWindow* window) { + [window orderWindow:NSWindowAbove relativeTo:0]; + ASSERT_TRUE([window isVisible]); + } + + void OrderWindowOut(NSWindow* window) { + [window orderWindow:NSWindowOut relativeTo:0]; + ASSERT_FALSE([window isVisible]); + } + + remote_cocoa::mojom::Visibility WindowAWebContentsVisibility() { + return _host_a.WebContentsVisibility(); + } + + void SetWindowAWebContentsVisibility( + remote_cocoa::mojom::Visibility visibility) { + _host_a.OnWindowVisibilityChanged(visibility); + } + + void TearDownInProcessBrowserTestFixture() override { + [window_a_web_contents_view_cocoa setHost:nullptr]; + } + + base::scoped_nsobject<WebContentsHostWindowForOcclusionTesting> window_a; + base::scoped_nsobject<WebContentsViewCocoa> window_a_web_contents_view_cocoa; + base::scoped_nsobject<WebContentsHostWindowForOcclusionTesting> window_b; + + private: + WebContentsNSViewHostStub _host_a; +}; + +class WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature + : public WindowOcclusionBrowserTestMac { + public: + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature() { + _features.InitAndEnableFeatureWithParameters( + kMacWebContentsOcclusion, + {{kEnhancedWindowOcclusionDetection, "true"}}); + } + + private: + base::test::ScopedFeatureList _features; +}; + +class WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature + : public WindowOcclusionBrowserTestMac { + public: + WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature() { + _features.InitAndEnableFeatureWithParameters( + kMacWebContentsOcclusion, {{kDisplaySleepAndAppHideDetection, "true"}}); + } + + private: + base::test::ScopedFeatureList _features; +}; + +// Test that enhanced occlusion detection doesn't work if the feature's not +// enabled. +IN_PROC_BROWSER_TEST_F(WindowOcclusionBrowserTestMac, + ManualOcclusionDetectionDisabled) { + InitWindowA(); + + // Create a second window and place it exactly over window_a. The window + // should still be considered visible. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Test that display sleep and app hide detection don't work if the feature's +// not enabled. +IN_PROC_BROWSER_TEST_F(WindowOcclusionBrowserTestMac, + OcclusionDetectionOnDisplaySleepAndAppHideDisabled) { + EXPECT_TRUE([[NSWorkspace sharedWorkspace] notificationCenter]); + + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Fake a display sleep notification. + [[[NSWorkspace sharedWorkspace] notificationCenter] + postNotificationName:NSWorkspaceScreensDidSleepNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Fake an application hide notification. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSApplicationDidHideNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Test that we properly handle occlusion notifications from macOS. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + MacOSOcclusionNotifications) { + InitWindowA(); + + [window_a setOccludedForTesting:YES]; + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + [window_a setOccludedForTesting:NO]; + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + ManualOcclusionDetection) { + InitWindowA(); + + // Create a second window and place it exactly over window_a. Unlike macOS, + // our manual occlusion detection will determine window_a is occluded. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + // Move window_b slightly in different directions and check the occlusion + // state of window_a's web contents. + const NSSize window_offsets[] = { + {1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {0.0, -1.0}}; + NSRect window_b_frame = [window_b frame]; + for (size_t i = 0; i < base::size(window_offsets); i++) { + // Move window b so that it no longer completely covers + // window_a's webcontents. + NSRect offset_window_frame = NSOffsetRect( + window_b_frame, window_offsets[i].width, window_offsets[i].height); + [window_b setFrame:offset_window_frame display:YES]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Move it back. + [window_b setFrame:window_b_frame display:YES]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + } +} + +// Checks manual occlusion detection as windows change display order. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + ManualOcclusionDetectionOnWindowOrderChange) { + InitWindowA(); + + // Size and position the second window so that it exactly covers the + // first. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + OrderWindowFront(window_a); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + OrderWindowFront(window_b); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); +} + +// Checks that window_a, occluded by window_b, transitions to kVisible while the +// user resizes window_b. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + ManualOcclusionDetectionOnWindowLiveResize) { + InitWindowA(); + + // Size and position the second window so that it exactly covers the + // first. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + // Fake the start of a live resize. window_a's web contents should + // become kVisible because resizing window_b may expose whatever's + // behind it. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowWillStartLiveResizeNotification + object:window_b + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Fake the resize end, which should return window_a to kOccluded because + // it's still completely covered by window_b. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidEndLiveResizeNotification + object:window_b + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); +} + +// Checks that window_a, occluded by window_b, transitions to kVisible when +// window_b is set to close. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + ManualOcclusionDetectionOnWindowClose) { + InitWindowA(); + + // Size and position the second window so that it exactly covers the + // first. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + // Close window b. + [window_b close]; + ASSERT_FALSE([window_b isVisible]); + + // window_a's web contents should be kVisible, so that it's properly + // updated when window_b goes offscreen. + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Checks that window_a, occluded by window_b and window_c, remains kOccluded +// when window_b is set to close. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + ManualOcclusionDetectionOnMiddleWindowClose) { + InitWindowA(); + + // Size and position the second window so that it exactly covers the + // first. + InitWindowB([window_a frame]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + // Create a window_c on top of them both. + const NSRect kWindowCContentRect = NSMakeRect(0.0, 0.0, 80.0, 60.0); + base::scoped_nsobject<NSWindow> window_c( + [[WebContentsHostWindowForOcclusionTesting alloc] + initWithContentRect:kWindowCContentRect + styleMask:NSWindowStyleMaskClosable + backing:NSBackingStoreBuffered + defer:YES]); + [window_c setTitle:@"window_a"]; + [window_c setReleasedWhenClosed:NO]; + + // Configure it for the test. + [window_c setFrame:[window_a frame] display:NO]; + OrderWindowFront(window_c); + + // Close window_b. + [window_b close]; + ASSERT_FALSE([window_b isVisible]); + + // window_a's web contents should remain kOccluded because of window_c. + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); +} + +// Checks that web contents are marked kHidden on display sleep. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature, + OcclusionDetectionOnDisplaySleep) { + EXPECT_TRUE([[NSWorkspace sharedWorkspace] notificationCenter]); + + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Fake a display sleep notification. + [[[NSWorkspace sharedWorkspace] notificationCenter] + postNotificationName:NSWorkspaceScreensDidSleepNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // Fake a display wake notification. + [[[NSWorkspace sharedWorkspace] notificationCenter] + postNotificationName:NSWorkspaceScreensDidWakeNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Checks that web contents are marked kHidden on app hide. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature, + OcclusionDetectionOnApplicationHide) { + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Fake an application hide notification. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSApplicationDidHideNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // Fake an application unhide notification. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSApplicationDidUnhideNotification + object:nil + userInfo:nil]; + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Checks that occlusion updates are ignored in between fullscreen transition +// notifications. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + IgnoreOcclusionUpdatesBetweenWindowFullscreenTransitionNotifications) { + InitWindowA(); + + SetWindowAWebContentsVisibility(remote_cocoa::mojom::Visibility::kHidden); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // Fake a fullscreen transition notification. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowWillEnterFullScreenNotification + object:window_a + userInfo:nil]; + + // Updating visibility should have no effect while in transition. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // End the transition. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidEnterFullScreenNotification + object:window_a + userInfo:nil]; + + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Reset. + SetWindowAWebContentsVisibility(remote_cocoa::mojom::Visibility::kHidden); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // Fake the exit transition start. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowWillExitFullScreenNotification + object:window_a + userInfo:nil]; + + // Updating visibility should have no effect while in transition. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // End the transition. + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidExitFullScreenNotification + object:window_a + userInfo:nil]; + + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidChangeOcclusionStateNotification + object:window_a + userInfo:nil]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Tests that each web contents in a window receives an updated occlusion +// state updated. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + OcclusionDetectionForMultipleWebContents) { + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Create a second web contents. + const NSRect kWebContentsBFrame = NSMakeRect(0.0, 0.0, 10.0, 10.0); + WebContentsViewCocoa* web_contents_b = + [[WebContentsViewCocoa alloc] initWithFrame:kWebContentsBFrame]; + [[window_a contentView] addSubview:web_contents_b]; + WebContentsNSViewHostStub host_2; + [web_contents_b setHost:&host_2]; + host_2.OnWindowVisibilityChanged(remote_cocoa::mojom::Visibility::kVisible); + + const NSRect kWebContentsCFrame = NSMakeRect(0.0, 20.0, 10.0, 10.0); + WebContentsViewCocoa* web_contents_c = + [[WebContentsViewCocoa alloc] initWithFrame:kWebContentsCFrame]; + [[window_a contentView] addSubview:web_contents_c]; + WebContentsNSViewHostStub host_3; + [web_contents_c setHost:&host_3]; + host_3.OnWindowVisibilityChanged(remote_cocoa::mojom::Visibility::kVisible); + + // Add window_b to occlude window_a and its web contentses. + InitWindowB([window_a frame]); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + EXPECT_EQ(host_2.WebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + EXPECT_EQ(host_3.WebContentsVisibility(), + remote_cocoa::mojom::Visibility::kOccluded); + + // Close window b, which should expose the web contentses. + [window_b close]; + ASSERT_FALSE([window_b isVisible]); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + EXPECT_EQ(host_2.WebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + EXPECT_EQ(host_3.WebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + [web_contents_b setHost:nullptr]; + [web_contents_c setHost:nullptr]; +} + +// Checks that web contentses are marked kHidden on WebContentsViewCocoa hide. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + OcclusionDetectionOnWebContentsViewCocoaHide) { + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + [window_a_web_contents_view_cocoa setHidden:YES]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + [window_a_web_contents_view_cocoa setHidden:NO]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Hiding the superview should have the same effect. + [[window_a_web_contents_view_cocoa superview] setHidden:YES]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + [[window_a_web_contents_view_cocoa superview] setHidden:NO]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Checks that web contentses are marked kHidden on WebContentsViewCocoa removal +// from the view hierarchy. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + OcclusionDetectionOnWebContentsViewCocoaRemoveFromSuperview) { + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + [window_a_web_contents_view_cocoa removeFromSuperview]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + // Adding it back should make it visible. + [[window_a contentView] addSubview:window_a_web_contents_view_cocoa]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + // Try the same with its superview. + const NSRect kTmpViewFrame = NSMakeRect(0.0, 0.0, 10.0, 10.0); + base::scoped_nsobject<NSView> tmpView( + [[NSView alloc] initWithFrame:kTmpViewFrame]); + [[window_a contentView] addSubview:tmpView]; + [window_a_web_contents_view_cocoa removeFromSuperview]; + [tmpView addSubview:window_a_web_contents_view_cocoa]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + [tmpView removeFromSuperview]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + [[window_a contentView] addSubview:tmpView]; + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +// Checks that web contentses are marked kHidden on window miniaturize. +IN_PROC_BROWSER_TEST_F( + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, + OcclusionDetectionOnWindowMiniaturize) { + InitWindowA(); + + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); + + [window_a miniaturize:nil]; + EXPECT_TRUE([window_a isMiniaturized]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kHidden); + + [window_a deminiaturize:nil]; + EXPECT_FALSE([window_a isMiniaturized]); + EXPECT_EQ(WindowAWebContentsVisibility(), + remote_cocoa::mojom::Visibility::kVisible); +} + +} // namespace content
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index acd190c..5a97956 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -396,8 +396,6 @@ "attribution_reporting/attribution_page_metrics.h", "attribution_reporting/attribution_policy.cc", "attribution_reporting/attribution_policy.h", - "attribution_reporting/attribution_report.cc", - "attribution_reporting/attribution_report.h", "attribution_reporting/attribution_storage.cc", "attribution_reporting/attribution_storage.h", "attribution_reporting/attribution_storage_delegate_impl.cc", @@ -408,6 +406,8 @@ "attribution_reporting/attribution_storage_sql_migrations.h", "attribution_reporting/attribution_utils.cc", "attribution_reporting/attribution_utils.h", + "attribution_reporting/event_attribution_report.cc", + "attribution_reporting/event_attribution_report.h", "attribution_reporting/rate_limit_table.cc", "attribution_reporting/rate_limit_table.h", "attribution_reporting/send_result.h", @@ -1026,6 +1026,8 @@ "indexed_db/transaction_impl.h", "installedapp/installed_app_provider_impl.cc", "installedapp/installed_app_provider_impl.h", + "interest_group/ad_auction_result_metrics.cc", + "interest_group/ad_auction_result_metrics.h", "interest_group/ad_auction_service_impl.cc", "interest_group/ad_auction_service_impl.h", "interest_group/auction_process_manager.cc", @@ -2919,6 +2921,8 @@ "../app_shim_remote_cocoa/render_widget_host_view_cocoa.mm", "../app_shim_remote_cocoa/sharing_service_picker.h", "../app_shim_remote_cocoa/sharing_service_picker.mm", + "../app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h", + "../app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm", "../app_shim_remote_cocoa/web_contents_view_cocoa.h", "../app_shim_remote_cocoa/web_contents_view_cocoa.mm", ]
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index abd5bf58..a474127 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -843,11 +843,15 @@ class NativeWinEventWaiter { public: NativeWinEventWaiter(BrowserAccessibilityManager* manager, - const std::string& match_pattern) + const std::string& match_pattern, + ui::AXApiType::Type type = ui::AXApiType::kWinIA2) : event_recorder_( - AXInspectFactory::CreatePlatformRecorder(manager, - base::GetCurrentProcId())), - match_pattern_(match_pattern) { + AXInspectFactory::CreateRecorder(type, + manager, + base::GetCurrentProcId(), + {})), + match_pattern_(match_pattern), + browser_accessibility_manager_(manager) { event_recorder_->ListenToEvents(base::BindRepeating( &NativeWinEventWaiter::OnEvent, base::Unretained(this))); } @@ -860,10 +864,16 @@ void Wait() { run_loop_.Run(); } + ~NativeWinEventWaiter() { + browser_accessibility_manager_->SignalEndOfTest(); + event_recorder_->WaitForDoneRecording(); + } + private: std::unique_ptr<ui::AXEventRecorder> event_recorder_; std::string match_pattern_; base::RunLoop run_loop_; + BrowserAccessibilityManager* browser_accessibility_manager_; }; // Helper class that reproduces a specific crash when UIA parent navigation @@ -5404,6 +5414,35 @@ EXPECT_NE(nullptr, text_pattern_unknown.Get()); } +IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest, + AsyncContentLoadedEventOnDocumentLoad) { + // Load the page. + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kLoadComplete); + EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + BrowserAccessibilityManager* browser_accessibility_manager = + web_contents->GetOrCreateRootBrowserAccessibilityManager(); + + NativeWinEventWaiter win_event_waiter( + browser_accessibility_manager, + "AsyncContentLoaded on role=document, name=Accessibility Test", + ui::AXApiType::kWinUIA); + + const char url_str[] = + "data:text/html," + "<!doctype html>" + "<html><head><title>Accessibility Test</title></head>" + "<body>" + "<button>This is a button</button>" + "</body></html>"; + GURL url(url_str); + EXPECT_TRUE(NavigateToURL(shell(), url)); + win_event_waiter.Wait(); +} + IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestOffsetsOfSelectionAll) { LoadInitialAccessibilityTreeFromHtml(R"HTML( <p>Hello world.</p>
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 7182a01..72ea529 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -67,7 +67,6 @@ // Private WebKit accessibility attributes. NSString* const NSAccessibilityBlockQuoteLevelAttribute = @"AXBlockQuoteLevel"; -NSString* const NSAccessibilityDOMClassList = @"AXDOMClassList"; NSString* const NSAccessibilityDropEffectsAttribute = @"AXDropEffects"; NSString* const NSAccessibilityEditableAncestorAttribute = @"AXEditableAncestor"; @@ -702,7 +701,6 @@ {NSAccessibilityDisclosureLevelAttribute, @"disclosureLevel"}, {NSAccessibilityDisclosedRowsAttribute, @"disclosedRows"}, {NSAccessibilityDropEffectsAttribute, @"dropEffects"}, - {NSAccessibilityDOMClassList, @"domClassList"}, {NSAccessibilityEditableAncestorAttribute, @"editableAncestor"}, {NSAccessibilityElementBusyAttribute, @"elementBusy"}, {NSAccessibilityEnabledAttribute, @"enabled"}, @@ -1040,23 +1038,6 @@ return nil; } -- (NSArray*)domClassList { - if (![self instanceActive]) - return nil; - - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; - - std::string classes; - if (_owner->GetStringAttribute(ax::mojom::StringAttribute::kClassName, - &classes)) { - std::vector<std::string> split_classes = base::SplitString( - classes, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (const auto& className : split_classes) - [ret addObject:(base::SysUTF8ToNSString(className))]; - } - return ret; -} - - (id)editableAncestor { if (![self instanceActive]) return nil; @@ -2952,7 +2933,6 @@ NSAccessibilityChildrenAttribute, NSAccessibilityIdentifierChromeAttribute, NSAccessibilityDescriptionAttribute, - NSAccessibilityDOMClassList, NSAccessibilityElementBusyAttribute, NSAccessibilityEnabledAttribute, NSAccessibilityEndTextMarkerAttribute,
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 07a97dd..64fbf21 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -169,6 +169,7 @@ if (load_complete_pending_ && can_fire_events && GetRoot()) { load_complete_pending_ = false; FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, GetRoot()); + FireUiaAccessibilityEvent(UIA_AsyncContentLoadedEventId, GetRoot()); } if (!can_fire_events && !load_complete_pending_ && @@ -358,6 +359,7 @@ break; case ui::AXEventGenerator::Event::LOAD_COMPLETE: FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, node); + FireUiaAccessibilityEvent(UIA_AsyncContentLoadedEventId, node); break; case ui::AXEventGenerator::Event::LAYOUT_INVALIDATED: FireUiaAccessibilityEvent(UIA_LayoutInvalidatedEventId, node);
diff --git a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc index fdf54e9d..b167749 100644 --- a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc
@@ -201,6 +201,10 @@ RunTypedTest<kMacAttributes>("ax-details-elements.html"); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityScriptTest, AXDOMClassList) { + RunTypedTest<kMacAttributes>("ax-dom-class-list.html"); +} + IN_PROC_BROWSER_TEST_P(DumpAccessibilityScriptTest, AXDOMIdentifier) { RunTypedTest<kMacAttributes>("ax-dom-identifier.html"); }
diff --git a/content/browser/aggregation_service/aggregatable_report.cc b/content/browser/aggregation_service/aggregatable_report.cc index e315a7e8..8fdb917 100644 --- a/content/browser/aggregation_service/aggregatable_report.cc +++ b/content/browser/aggregation_service/aggregatable_report.cc
@@ -327,6 +327,11 @@ key_id(std::move(key_id)) {} AggregatableReport::AggregationServicePayload::AggregationServicePayload( + const AggregatableReport::AggregationServicePayload& other) = default; +AggregatableReport::AggregationServicePayload& +AggregatableReport::AggregationServicePayload::operator=( + const AggregatableReport::AggregationServicePayload& other) = default; +AggregatableReport::AggregationServicePayload::AggregationServicePayload( AggregatableReport::AggregationServicePayload&& other) = default; AggregatableReport::AggregationServicePayload& AggregatableReport::AggregationServicePayload::operator=( @@ -339,6 +344,12 @@ AggregatableReportSharedInfo shared_info) : payloads_(std::move(payloads)), shared_info_(std::move(shared_info)) {} +AggregatableReport::AggregatableReport(const AggregatableReport& other) = + default; + +AggregatableReport& AggregatableReport::operator=( + const AggregatableReport& other) = default; + AggregatableReport::AggregatableReport(AggregatableReport&& other) = default; AggregatableReport& AggregatableReport::operator=(AggregatableReport&& other) = @@ -425,11 +436,10 @@ std::move(report_request.shared_info_)); } -base::Value::DictStorage AggregatableReport::GetAsJson() && { +base::Value::DictStorage AggregatableReport::GetAsJson() const { base::Value::DictStorage value; - value.emplace(kPrivacyBudgetKeyKey, - std::move(shared_info_.privacy_budget_key)); + value.emplace(kPrivacyBudgetKeyKey, shared_info_.privacy_budget_key); // Encoded as a string representing the number of milliseconds since the Unix // epoch, ignoring leap seconds. @@ -446,7 +456,7 @@ payload_dict_value.SetStringKey("origin", payload.origin.Serialize()); payload_dict_value.SetStringKey("payload", base::Base64Encode(payload.payload)); - payload_dict_value.SetStringKey("key_id", std::move(payload.key_id)); + payload_dict_value.SetStringKey("key_id", payload.key_id); payloads_list_value.Append(std::move(payload_dict_value)); }
diff --git a/content/browser/aggregation_service/aggregatable_report.h b/content/browser/aggregation_service/aggregatable_report.h index a5418c9..fe6d0db 100644 --- a/content/browser/aggregation_service/aggregatable_report.h +++ b/content/browser/aggregation_service/aggregatable_report.h
@@ -74,6 +74,9 @@ AggregationServicePayload(url::Origin origin, std::vector<uint8_t> payload, std::string key_id); + AggregationServicePayload(const AggregationServicePayload& other); + AggregationServicePayload& operator=( + const AggregationServicePayload& other); AggregationServicePayload(AggregationServicePayload&& other); AggregationServicePayload& operator=(AggregationServicePayload&& other); ~AggregationServicePayload(); @@ -140,7 +143,8 @@ AggregatableReport(std::vector<AggregationServicePayload> payloads, AggregatableReportSharedInfo shared_info); - // Move-only. + AggregatableReport(const AggregatableReport& other); + AggregatableReport& operator=(const AggregatableReport& other); AggregatableReport(AggregatableReport&& other); AggregatableReport& operator=(AggregatableReport&& other); ~AggregatableReport(); @@ -171,9 +175,8 @@ // ] // } // Note that APIs may wish to add additional key-value pairs to this returned - // value. `this` is required to be an rvalue to avoid unnecessary copies; this - // method should only need to be called once. - base::Value::DictStorage GetAsJson() &&; + // value. + base::Value::DictStorage GetAsJson() const; // TODO(crbug.com/1247409): Expose static method to validate that a // base::Value appears to represent a valid report.
diff --git a/content/browser/aggregation_service/aggregatable_report_unittest.cc b/content/browser/aggregation_service/aggregatable_report_unittest.cc index b0046d4..163325e 100644 --- a/content/browser/aggregation_service/aggregatable_report_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_unittest.cc
@@ -484,7 +484,7 @@ /*privacy_budget_key=*/"example_pbk"); AggregatableReport report(std::move(payloads), std::move(shared_info)); - base::Value::DictStorage report_json_value = std::move(report).GetAsJson(); + base::Value::DictStorage report_json_value = report.GetAsJson(); std::string report_json_string; base::JSONWriter::Write(base::Value(report_json_value), &report_json_string); @@ -514,7 +514,7 @@ /*privacy_budget_key=*/"example_pbk"); AggregatableReport report(std::move(payloads), std::move(shared_info)); - base::Value::DictStorage report_json_value = std::move(report).GetAsJson(); + base::Value::DictStorage report_json_value = report.GetAsJson(); std::string report_json_string; base::JSONWriter::Write(base::Value(report_json_value), &report_json_string);
diff --git a/content/browser/aggregation_service/aggregation_service.h b/content/browser/aggregation_service/aggregation_service.h index 8b32788..cfc09d81 100644 --- a/content/browser/aggregation_service/aggregation_service.h +++ b/content/browser/aggregation_service/aggregation_service.h
@@ -46,7 +46,7 @@ // Sends an aggregatable report to the reporting endpoint `url`. virtual void SendReport(const GURL& url, - AggregatableReport report, + const AggregatableReport& report, SendCallback callback) = 0; // Sends the contents of an aggregatable report to the reporting endpoint
diff --git a/content/browser/aggregation_service/aggregation_service_impl.cc b/content/browser/aggregation_service/aggregation_service_impl.cc index 54d30ed1..c913313 100644 --- a/content/browser/aggregation_service/aggregation_service_impl.cc +++ b/content/browser/aggregation_service/aggregation_service_impl.cc
@@ -88,10 +88,9 @@ } void AggregationServiceImpl::SendReport(const GURL& url, - AggregatableReport report, + const AggregatableReport& report, SendCallback callback) { - SendReport(url, base::Value(std::move(report).GetAsJson()), - std::move(callback)); + SendReport(url, base::Value(report.GetAsJson()), std::move(callback)); } void AggregationServiceImpl::SendReport(const GURL& url,
diff --git a/content/browser/aggregation_service/aggregation_service_impl.h b/content/browser/aggregation_service/aggregation_service_impl.h index e543ac9..bf010d8 100644 --- a/content/browser/aggregation_service/aggregation_service_impl.h +++ b/content/browser/aggregation_service/aggregation_service_impl.h
@@ -56,7 +56,7 @@ void AssembleReport(AggregatableReportRequest report_request, AssemblyCallback callback) override; void SendReport(const GURL& url, - AggregatableReport report, + const AggregatableReport& report, SendCallback callback) override; void SendReport(const GURL& url, const base::Value& contents,
diff --git a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc index 9bb4a672..e1d83c5b 100644 --- a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc +++ b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc
@@ -117,9 +117,9 @@ })); } - void SendReport(const GURL& url, AggregatableReport report) { + void SendReport(const GURL& url, const AggregatableReport& report) { service()->SendReport( - url, std::move(report), + url, report, base::BindLambdaForTesting([&](AggregationService::SendStatus status) { last_send_status_ = status; })); @@ -221,7 +221,7 @@ AggregatableReport report(std::move(payloads), std::move(shared_info)); - SendReport(GURL("https://example.com/reports"), std::move(report)); + SendReport(GURL("https://example.com/reports"), report); sender()->TriggerResponse(/*report_id=*/0, AggregatableReportSender::RequestStatus::kOk);
diff --git a/content/browser/attribution_reporting/attribution_internals_browsertest.cc b/content/browser/attribution_reporting/attribution_internals_browsertest.cc index cbe9df52..346a162 100644 --- a/content/browser/attribution_reporting/attribution_internals_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
@@ -14,9 +14,9 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "content/browser/attribution_reporting/attribution_manager.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/send_result.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -67,7 +67,7 @@ .WillByDefault(InvokeCallback<std::vector<StorableSource>>({})); ON_CALL(manager_, GetPendingReportsForWebUI) - .WillByDefault(InvokeCallback<std::vector<AttributionReport>>({})); + .WillByDefault(InvokeCallback<std::vector<EventAttributionReport>>({})); } void ClickRefreshButton() { @@ -356,7 +356,7 @@ SendResult(SendResult::Status::kFailure, /*http_response_code=*/0)); ON_CALL(manager_, GetPendingReportsForWebUI) - .WillByDefault(InvokeCallback<std::vector<AttributionReport>>( + .WillByDefault(InvokeCallback<std::vector<EventAttributionReport>>( {ReportBuilder(SourceBuilder(now) .SetSourceType(StorableSource::SourceType::kEvent) .SetAttributionLogic( @@ -494,12 +494,12 @@ OverrideWebUIAttributionManager(); - AttributionReport report = ReportBuilder(SourceBuilder(now).Build()) - .SetReportTime(now) - .SetPriority(7) - .Build(); + EventAttributionReport report = ReportBuilder(SourceBuilder(now).Build()) + .SetReportTime(now) + .SetPriority(7) + .Build(); EXPECT_CALL(manager_, GetPendingReportsForWebUI) - .WillOnce(InvokeCallback<std::vector<AttributionReport>>({report})); + .WillOnce(InvokeCallback<std::vector<EventAttributionReport>>({report})); report.set_report_time(report.report_time() + base::Hours(1)); manager_.NotifyReportSent(report, SendResult(SendResult::Status::kSent, @@ -602,11 +602,9 @@ EXPECT_TRUE(NavigateToURL(shell(), GURL(kAttributionInternalsUrl))); EXPECT_CALL(manager_, GetPendingReportsForWebUI) - .WillOnce(InvokeCallback<std::vector<AttributionReport>>( - {ReportBuilder(SourceBuilder(base::Time::Now()).Build()) - .SetPriority(7) - .Build()})) - .WillOnce(InvokeCallback<std::vector<AttributionReport>>({})); + .WillOnce(InvokeCallback<std::vector<EventAttributionReport>>( + {ReportBuilder(SourceBuilder().Build()).SetPriority(7).Build()})) + .WillOnce(InvokeCallback<std::vector<EventAttributionReport>>({})); EXPECT_CALL(manager_, SendReportsForWebUI) .WillOnce([](base::OnceClosure done) { std::move(done).Run(); });
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc index 108e59d..1efa8e62 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -13,8 +13,8 @@ #include "base/notreached.h" #include "base/time/time.h" #include "content/browser/attribution_reporting/attribution_manager_impl.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/send_result.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/storage_partition_impl.h" @@ -78,7 +78,7 @@ } mojom::WebUIAttributionReportPtr WebUIAttributionReport( - const AttributionReport& report, + const EventAttributionReport& report, int http_response_code, mojom::WebUIAttributionReport::Status status) { return mojom::WebUIAttributionReport::New( @@ -93,10 +93,10 @@ void ForwardReportsToWebUI( mojom::AttributionInternalsHandler::GetReportsCallback web_ui_callback, - std::vector<AttributionReport> pending_reports) { + std::vector<EventAttributionReport> pending_reports) { std::vector<mojom::WebUIAttributionReportPtr> web_ui_reports; web_ui_reports.reserve(pending_reports.size()); - for (const AttributionReport& report : pending_reports) { + for (const EventAttributionReport& report : pending_reports) { web_ui_reports.push_back(WebUIAttributionReport( report, /*http_response_code=*/0, mojom::WebUIAttributionReport::Status::kPending)); @@ -212,7 +212,7 @@ } void AttributionInternalsHandlerImpl::OnReportSent( - const AttributionReport& report, + const EventAttributionReport& report, const SendResult& info) { mojom::WebUIAttributionReport::Status status; switch (info.status) {
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.h b/content/browser/attribution_reporting/attribution_internals_handler_impl.h index 7d0fc9d..dfb1348 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.h +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.h
@@ -68,7 +68,7 @@ void OnReportsChanged() override; void OnSourceDeactivated( const AttributionStorage::DeactivatedSource& deactivated_source) override; - void OnReportSent(const AttributionReport& report, + void OnReportSent(const EventAttributionReport& report, const SendResult& info) override; void OnReportDropped( const AttributionStorage::CreateReportResult& result) override;
diff --git a/content/browser/attribution_reporting/attribution_manager.h b/content/browser/attribution_reporting/attribution_manager.h index 570e54d..4e21516 100644 --- a/content/browser/attribution_reporting/attribution_manager.h +++ b/content/browser/attribution_reporting/attribution_manager.h
@@ -10,8 +10,8 @@ #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/observer_list_types.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" namespace base { class Time; @@ -59,7 +59,7 @@ virtual void OnSourceDeactivated( const AttributionStorage::DeactivatedSource& source) {} - virtual void OnReportSent(const AttributionReport& report, + virtual void OnReportSent(const EventAttributionReport& report, const SendResult& info) {} virtual void OnReportDropped( @@ -88,7 +88,8 @@ // Get all pending reports that are currently stored in this partition. Used // for populating WebUI. virtual void GetPendingReportsForWebUI( - base::OnceCallback<void(std::vector<AttributionReport>)> callback) = 0; + base::OnceCallback<void(std::vector<EventAttributionReport>)> + callback) = 0; // Sends all pending reports immediately, and runs |done| once they have all // been sent.
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc index f64c6af..dd83689 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -18,10 +18,10 @@ #include "base/time/time.h" #include "content/browser/attribution_reporting/attribution_network_sender_impl.h" #include "content/browser/attribution_reporting/attribution_policy.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage_delegate_impl.h" #include "content/browser/attribution_reporting/attribution_storage_sql.h" #include "content/browser/attribution_reporting/attribution_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/send_result.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" @@ -102,7 +102,8 @@ } // Called when |report| is to be sent over network, for logging metrics. -void LogMetricsOnReportSend(const AttributionReport& report, base::Time now) { +void LogMetricsOnReportSend(const EventAttributionReport& report, + base::Time now) { // Use a large time range to capture users that might not open the browser for // a long time while a conversion report is pending. Revisit this range if it // is non-ideal for real world data. @@ -282,7 +283,7 @@ } void AttributionManagerImpl::GetPendingReportsForWebUI( - base::OnceCallback<void(std::vector<AttributionReport>)> callback) { + base::OnceCallback<void(std::vector<EventAttributionReport>)> callback) { GetAndHandleReports(std::move(callback), /*max_report_time=*/base::Time::Max(), /*limit=*/1000); } @@ -390,7 +391,7 @@ } void AttributionManagerImpl::OnGetReportsToSend( - std::vector<AttributionReport> reports) { + std::vector<EventAttributionReport> reports) { if (reports.empty() || network_connection_tracker_->IsOffline()) return; @@ -407,14 +408,14 @@ void AttributionManagerImpl::OnGetReportsToSendFromWebUI( base::OnceClosure done, - std::vector<AttributionReport> reports) { + std::vector<EventAttributionReport> reports) { if (reports.empty() || network_connection_tracker_->IsOffline()) { std::move(done).Run(); return; } base::Time now = base::Time::Now(); - for (AttributionReport& report : reports) { + for (EventAttributionReport& report : reports) { report.set_report_time(now); } @@ -422,11 +423,12 @@ SendReports(std::move(reports), /*log_metrics=*/false, std::move(barrier)); } -void AttributionManagerImpl::SendReports(std::vector<AttributionReport> reports, - bool log_metrics, - base::RepeatingClosure done) { +void AttributionManagerImpl::SendReports( + std::vector<EventAttributionReport> reports, + bool log_metrics, + base::RepeatingClosure done) { const base::Time now = base::Time::Now(); - for (AttributionReport& report : reports) { + for (EventAttributionReport& report : reports) { DCHECK(report.report_id().has_value()); DCHECK_LE(report.report_time(), now); @@ -467,13 +469,13 @@ } void AttributionManagerImpl::MarkReportCompleted( - AttributionReport::Id report_id) { + EventAttributionReport::Id report_id) { size_t num_removed = reports_being_sent_.erase(report_id); DCHECK_EQ(num_removed, 1u); } void AttributionManagerImpl::OnReportSent(base::OnceClosure done, - AttributionReport report, + EventAttributionReport report, SendResult info) { DCHECK(report.report_id().has_value()); @@ -504,7 +506,7 @@ .Then(base::BindOnce( [](base::OnceClosure done, base::WeakPtr<AttributionManagerImpl> manager, - AttributionReport::Id report_id, base::Time new_report_time, + EventAttributionReport::Id report_id, base::Time new_report_time, bool success) { std::move(done).Run(); @@ -523,7 +525,7 @@ .Then(base::BindOnce( [](base::OnceClosure done, base::WeakPtr<AttributionManagerImpl> manager, - AttributionReport::Id report_id, bool success) { + EventAttributionReport::Id report_id, bool success) { std::move(done).Run(); RecordDeleteEvent(success ? DeleteEvent::kSucceeded : DeleteEvent::kFailed);
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h index 13266fe..604132a5 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -19,8 +19,8 @@ #include "base/threading/sequence_bound.h" #include "base/timer/wall_clock_timer.h" #include "content/browser/attribution_reporting/attribution_manager.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/common/content_export.h" #include "services/network/public/cpp/network_connection_tracker.h" #include "storage/browser/quota/special_storage_policy.h" @@ -110,7 +110,7 @@ void GetActiveSourcesForWebUI( base::OnceCallback<void(std::vector<StorableSource>)> callback) override; void GetPendingReportsForWebUI( - base::OnceCallback<void(std::vector<AttributionReport>)> callback) + base::OnceCallback<void(std::vector<EventAttributionReport>)> callback) override; void SendReportsForWebUI(base::OnceClosure done) override; const AttributionPolicy& GetAttributionPolicy() const override; @@ -138,7 +138,7 @@ // |max_report_time|, and calls |handler_function| on them; use a negative // number for no limit. using ReportsHandlerFunc = - base::OnceCallback<void(std::vector<AttributionReport>)>; + base::OnceCallback<void(std::vector<EventAttributionReport>)>; void GetAndHandleReports(ReportsHandlerFunc handler_function, base::Time max_report_time, int limit); @@ -146,18 +146,18 @@ void UpdateGetReportsToSendTimer(absl::optional<base::Time> time); void StartGetReportsToSendTimer(); void GetReportsToSend(); - void OnGetReportsToSend(std::vector<AttributionReport> reports); + void OnGetReportsToSend(std::vector<EventAttributionReport> reports); void OnGetReportsToSendFromWebUI(base::OnceClosure done, - std::vector<AttributionReport> reports); + std::vector<EventAttributionReport> reports); - void SendReports(std::vector<AttributionReport> reports, + void SendReports(std::vector<EventAttributionReport> reports, bool log_metrics, base::RepeatingClosure done); void OnReportSent(base::OnceClosure done, - AttributionReport report, + EventAttributionReport report, SendResult info); - void MarkReportCompleted(AttributionReport::Id report_id); + void MarkReportCompleted(EventAttributionReport::Id report_id); void OnReportStored(AttributionStorage::CreateReportResult result); @@ -170,7 +170,7 @@ void HandleTriggerInternal(StorableTrigger trigger); // Friend to expose the AttributionStorage for certain tests. - friend std::vector<AttributionReport> GetAttributionsToReportForTesting( + friend std::vector<EventAttributionReport> GetAttributionsToReportForTesting( AttributionManagerImpl* manager, base::Time max_report_time); @@ -194,7 +194,7 @@ // Set of all conversion IDs that are currently being sent, deleted, or // updated. The number of concurrent conversion reports being sent at any time // is expected to be small, so a `flat_set` is used. - base::flat_set<AttributionReport::Id> reports_being_sent_; + base::flat_set<EventAttributionReport::Id> reports_being_sent_; base::ObserverList<Observer> observers_;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc index fbcb687..9128f50 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -24,9 +24,9 @@ #include "base/test/mock_callback.h" #include "base/time/time.h" #include "build/build_config.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/send_result.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" @@ -93,7 +93,7 @@ MOCK_METHOD(void, OnReportSent, - (const AttributionReport& report, const SendResult& info), + (const EventAttributionReport& report, const SendResult& info), (override)); MOCK_METHOD(void, @@ -196,11 +196,11 @@ return result; } - std::vector<AttributionReport> StoredReports() { - std::vector<AttributionReport> result; + std::vector<EventAttributionReport> StoredReports() { + std::vector<EventAttributionReport> result; base::RunLoop loop; - attribution_manager_->GetPendingReportsForWebUI( - base::BindLambdaForTesting([&](std::vector<AttributionReport> reports) { + attribution_manager_->GetPendingReportsForWebUI(base::BindLambdaForTesting( + [&](std::vector<EventAttributionReport> reports) { result = std::move(reports); loop.Quit(); })); @@ -230,7 +230,7 @@ }; TEST_F(AttributionManagerImplTest, ImpressionRegistered_ReturnedToWebUI) { - auto impression = SourceBuilder(base::Time::Now()) + auto impression = SourceBuilder() .SetExpiry(kImpressionExpiry) .SetSourceEventId(100) .Build(); @@ -240,7 +240,7 @@ } TEST_F(AttributionManagerImplTest, ExpiredImpression_NotReturnedToWebUI) { - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetSourceEventId(100) .Build()); @@ -250,7 +250,7 @@ } TEST_F(AttributionManagerImplTest, ImpressionConverted_ReportReturnedToWebUI) { - auto impression = SourceBuilder(base::Time::Now()) + auto impression = SourceBuilder() .SetExpiry(kImpressionExpiry) .SetSourceEventId(100) .Build(); @@ -259,7 +259,7 @@ auto conversion = DefaultTrigger(); attribution_manager_->HandleTrigger(conversion); - AttributionReport expected_report = + EventAttributionReport expected_report = ReportBuilder(impression) .SetTriggerData(conversion.trigger_data()) .SetConversionTime(base::Time::Now()) @@ -268,7 +268,7 @@ // The external report ID is randomly generated by the storage delegate, // so zero it out here to avoid flakiness. - std::vector<AttributionReport> reports = StoredReports(); + std::vector<EventAttributionReport> reports = StoredReports(); for (auto& report : reports) { report.SetExternalReportIdForTesting(DefaultExternalReportID()); } @@ -277,7 +277,7 @@ TEST_F(AttributionManagerImplTest, ImpressionConverted_ReportSent) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); // Make sure the report is not sent earlier than its report time. @@ -302,21 +302,21 @@ const auto origin_b = url::Origin::Create(url_b); const auto origin_c = url::Origin::Create(url_c); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_a) .Build()); attribution_manager_->HandleTrigger( TriggerBuilder().SetReportingOrigin(origin_a).Build()); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_b) .Build()); attribution_manager_->HandleTrigger( TriggerBuilder().SetReportingOrigin(origin_b).Build()); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_c) .Build()); @@ -349,7 +349,7 @@ const auto origin_a = url::Origin::Create(url_a); const auto origin_b = url::Origin::Create(url_b); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_a) .Build()); @@ -358,7 +358,7 @@ task_environment_.FastForwardBy(base::Microseconds(1)); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_b) .Build()); @@ -382,7 +382,7 @@ TEST_F(AttributionManagerImplTest, SenderStillHandlingReport_NotSentAgain) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); EXPECT_THAT(network_sender_->calls(), SizeIs(1)); @@ -399,7 +399,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); @@ -432,7 +432,7 @@ const auto origin_a = url::Origin::Create(url_a); const auto origin_b = url::Origin::Create(url_b); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_a) .Build()); @@ -440,7 +440,7 @@ TriggerBuilder().SetReportingOrigin(origin_a).Build()); task_environment_.FastForwardBy(base::Minutes(10)); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) + attribution_manager_->HandleSource(SourceBuilder() .SetExpiry(kImpressionExpiry) .SetReportingOrigin(origin_b) .Build()); @@ -466,7 +466,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); @@ -493,7 +493,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow - @@ -528,7 +528,7 @@ TEST_F(AttributionManagerImplTest, ReportExpiredAtStartup_Sent) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); ShutdownManager(); @@ -547,7 +547,7 @@ TEST_F(AttributionManagerImplTest, ReportSent_Deleted) { base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); EXPECT_THAT(network_sender_->calls(), SizeIs(1)); @@ -570,47 +570,39 @@ EXPECT_CALL( observer, - OnReportSent(Property(&AttributionReport::source, + OnReportSent(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 1u)), _)); EXPECT_CALL( observer, - OnReportSent(Property(&AttributionReport::source, + OnReportSent(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 2u)), _)); EXPECT_CALL( observer, - OnReportSent(Property(&AttributionReport::source, + OnReportSent(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 3u)), _)); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(1) - .SetExpiry(kImpressionExpiry) - .Build()); + attribution_manager_->HandleSource( + SourceBuilder().SetSourceEventId(1).SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); // This one should be stored, as its status is `kDropped`. - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(2) - .SetExpiry(kImpressionExpiry) - .Build()); + attribution_manager_->HandleSource( + SourceBuilder().SetSourceEventId(2).SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(3) - .SetExpiry(kImpressionExpiry) - .Build()); + attribution_manager_->HandleSource( + SourceBuilder().SetSourceEventId(3).SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); // This one shouldn't be stored, as it will be retried. - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(4) - .SetExpiry(kImpressionExpiry) - .Build()); + attribution_manager_->HandleSource( + SourceBuilder().SetSourceEventId(4).SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); @@ -643,11 +635,11 @@ EXPECT_CALL( observer, - OnReportDropped( - AllOf(Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::priority, 1))), - Property(&CreateReportResult::status, - CreateReportStatus::kSuccessDroppedLowerPriority)))); + OnReportDropped(AllOf( + Property(&CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::priority, 1))), + Property(&CreateReportResult::status, + CreateReportStatus::kSuccessDroppedLowerPriority)))); EXPECT_CALL(checkpoint, Call(2)); @@ -655,7 +647,7 @@ observer, OnReportDropped(AllOf( Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::priority, -5))), + Optional(Property(&EventAttributionReport::priority, -5))), Property(&CreateReportResult::status, CreateReportStatus::kPriorityTooLow)))); @@ -663,22 +655,22 @@ EXPECT_CALL( observer, - OnReportDropped( - AllOf(Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::priority, 2))), - Property(&CreateReportResult::status, - CreateReportStatus::kSuccessDroppedLowerPriority)))); + OnReportDropped(AllOf( + Property(&CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::priority, 2))), + Property(&CreateReportResult::status, + CreateReportStatus::kSuccessDroppedLowerPriority)))); EXPECT_CALL( observer, - OnReportDropped( - AllOf(Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::priority, 3))), - Property(&CreateReportResult::status, - CreateReportStatus::kSuccessDroppedLowerPriority)))); + OnReportDropped(AllOf( + Property(&CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::priority, 3))), + Property(&CreateReportResult::status, + CreateReportStatus::kSuccessDroppedLowerPriority)))); } attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); EXPECT_THAT(StoredSources(), SizeIs(1)); // `kNavigation` sources can have 3 reports, so none of these should result in @@ -744,7 +736,7 @@ TEST_F(AttributionManagerImplTest, ConversionsSentFromUI_ReportedImmediately) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(network_sender_->calls(), IsEmpty()); @@ -758,7 +750,7 @@ size_t callback_calls = 0; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(network_sender_->calls(), IsEmpty()); @@ -782,7 +774,7 @@ base::Time start_time = base::Time::Now(); attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); ShutdownManager(); @@ -797,7 +789,7 @@ // started. EXPECT_THAT( StoredReports(), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, start_time + kFirstReportingWindow + base::Milliseconds(1) + kExpiredReportOffset))); @@ -810,7 +802,7 @@ // Create a report that will be reported at t= 2 days. attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); ShutdownManager(); @@ -823,7 +815,7 @@ // Ensure that this report does not receive additional delay. EXPECT_THAT(StoredReports(), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, start_time + kFirstReportingWindow))); EXPECT_THAT(network_sender_->calls(), IsEmpty()); @@ -832,7 +824,7 @@ TEST_F(AttributionManagerImplTest, SessionOnlyOrigins_DataDeletedAtShutdown) { GURL session_only_origin("https://sessiononly.example"); auto impression = - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(url::Origin::Create(session_only_origin)) .Build(); @@ -857,18 +849,15 @@ url::Origin::Create(GURL("https://sessiononly.example")); // Create impressions which each have the session only origin as one of // impression/conversion/reporting origin. - auto impression1 = SourceBuilder(base::Time::Now()) - .SetImpressionOrigin(session_only_origin) - .Build(); - auto impression2 = SourceBuilder(base::Time::Now()) - .SetReportingOrigin(session_only_origin) - .Build(); - auto impression3 = SourceBuilder(base::Time::Now()) - .SetConversionOrigin(session_only_origin) - .Build(); + auto impression1 = + SourceBuilder().SetImpressionOrigin(session_only_origin).Build(); + auto impression2 = + SourceBuilder().SetReportingOrigin(session_only_origin).Build(); + auto impression3 = + SourceBuilder().SetConversionOrigin(session_only_origin).Build(); // Create one impression which is not session only. - auto impression4 = SourceBuilder(base::Time::Now()).Build(); + auto impression4 = SourceBuilder().Build(); mock_storage_policy_->AddSessionOnly(session_only_origin.GetURL()); @@ -894,7 +883,7 @@ // priority trigger. TEST_F(AttributionManagerImplTest, ConversionPrioritization_OneReportSent) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(base::Days(7)).Build()); + SourceBuilder().SetExpiry(base::Days(7)).Build()); EXPECT_THAT(StoredSources(), SizeIs(1)); attribution_manager_->HandleTrigger(TriggerBuilder().SetPriority(1).Build()); @@ -926,7 +915,7 @@ TEST_F(AttributionManagerImplTest, OnReportSent_RecordsDeleteEventMetric) { base::HistogramTester histograms; - attribution_manager_->HandleSource(SourceBuilder(base::Time::Now()).Build()); + attribution_manager_->HandleSource(SourceBuilder().Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); @@ -958,10 +947,8 @@ observation(&observer); observation.Observe(attribution_manager_.get()); - auto source1 = SourceBuilder(base::Time::Now()) - .SetExpiry(kImpressionExpiry) - .SetSourceEventId(7) - .Build(); + auto source1 = + SourceBuilder().SetExpiry(kImpressionExpiry).SetSourceEventId(7).Build(); Checkpoint checkpoint; { @@ -995,10 +982,8 @@ EXPECT_THAT(StoredReports(), SizeIs(1)); checkpoint.Call(2); - auto source2 = SourceBuilder(base::Time::Now()) - .SetExpiry(kImpressionExpiry) - .SetSourceEventId(9) - .Build(); + auto source2 = + SourceBuilder().SetExpiry(kImpressionExpiry).SetSourceEventId(9).Build(); attribution_manager_->HandleSource(source2); EXPECT_THAT(StoredSources(), SizeIs(1)); } @@ -1009,10 +994,8 @@ observation(&observer); observation.Observe(attribution_manager_.get()); - auto source1 = SourceBuilder(base::Time::Now()) - .SetExpiry(kImpressionExpiry) - .SetSourceEventId(7) - .Build(); + auto source1 = + SourceBuilder().SetExpiry(kImpressionExpiry).SetSourceEventId(7).Build(); Checkpoint checkpoint; { @@ -1104,7 +1087,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); @@ -1127,7 +1110,7 @@ TEST_F(AttributionManagerImplTest, Offline_NoReportSent) { attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); @@ -1143,7 +1126,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); task_environment_.FastForwardBy(kFirstReportingWindow); @@ -1157,7 +1140,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); // Prevent the report from being sent until after its original report time. @@ -1177,7 +1160,7 @@ base::HistogramTester histograms; attribution_manager_->HandleSource( - SourceBuilder(base::Time::Now()).SetExpiry(kImpressionExpiry).Build()); + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); attribution_manager_->SendReportsForWebUI(base::DoNothing());
diff --git a/content/browser/attribution_reporting/attribution_network_sender_impl_unittest.cc b/content/browser/attribution_reporting/attribution_network_sender_impl_unittest.cc index de6a54d..66414299 100644 --- a/content/browser/attribution_reporting/attribution_network_sender_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_network_sender_impl_unittest.cc
@@ -45,7 +45,7 @@ const char kReportUrl[] = "https://report.test/.well-known/attribution-reporting/report-attribution"; -AttributionReport DefaultReport() { +EventAttributionReport DefaultReport() { return ReportBuilder(SourceBuilder(base::Time()).Build()).Build(); } @@ -147,7 +147,7 @@ .SetSourceEventId(100) .SetSourceType(test_case.source_type) .Build(); - AttributionReport report = + EventAttributionReport report = ReportBuilder(impression).SetTriggerData(5).Build(); network_sender_->SendReport(report.ReportURL(), report.ReportBody(), base::DoNothing()); @@ -168,7 +168,7 @@ .SetReportingOrigin(url::Origin::Create(GURL("https://a.com"))) .SetConversionOrigin(url::Origin::Create(GURL("https://sub.b.com"))) .Build(); - AttributionReport report = ReportBuilder(impression).Build(); + EventAttributionReport report = ReportBuilder(impression).Build(); network_sender_->SendReport(report.ReportURL(), report.ReportBody(), base::DoNothing());
diff --git a/content/browser/attribution_reporting/attribution_storage.cc b/content/browser/attribution_reporting/attribution_storage.cc index 027e696d..a3da27c1 100644 --- a/content/browser/attribution_reporting/attribution_storage.cc +++ b/content/browser/attribution_reporting/attribution_storage.cc
@@ -15,7 +15,7 @@ CreateReportResult::CreateReportResult( Status status, - absl::optional<AttributionReport> dropped_report, + absl::optional<EventAttributionReport> dropped_report, absl::optional<DeactivatedSource::Reason> dropped_report_source_deactivation_reason, absl::optional<base::Time> report_time) @@ -50,8 +50,8 @@ return status_; } -const absl::optional<AttributionReport>& CreateReportResult::dropped_report() - const { +const absl::optional<EventAttributionReport>& +CreateReportResult::dropped_report() const { return dropped_report_; }
diff --git a/content/browser/attribution_reporting/attribution_storage.h b/content/browser/attribution_reporting/attribution_storage.h index b21f0e3..a64baea 100644 --- a/content/browser/attribution_reporting/attribution_storage.h +++ b/content/browser/attribution_reporting/attribution_storage.h
@@ -10,7 +10,7 @@ #include "base/callback_forward.h" #include "base/compiler_specific.h" -#include "content/browser/attribution_reporting/attribution_report.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -169,7 +169,7 @@ explicit CreateReportResult( Status status, - absl::optional<AttributionReport> dropped_report = absl::nullopt, + absl::optional<EventAttributionReport> dropped_report = absl::nullopt, absl::optional<DeactivatedSource::Reason> dropped_report_source_deactivation_reason = absl::nullopt, absl::optional<base::Time> report_time = absl::nullopt); @@ -183,7 +183,7 @@ Status status() const; - const absl::optional<AttributionReport>& dropped_report() const; + const absl::optional<EventAttributionReport>& dropped_report() const; absl::optional<base::Time> report_time() const; @@ -194,7 +194,7 @@ // Null unless `status` is `kSuccessDroppedLowerPriority`, // `kRateLimited`, `kPriorityTooLow`, or `kDroppedForNoise`. - absl::optional<AttributionReport> dropped_report_; + absl::optional<EventAttributionReport> dropped_report_; // Null unless `dropped_report_`'s source was deactivated. absl::optional<DeactivatedSource::Reason> @@ -214,7 +214,7 @@ // |max_report_time|. This call is logically const, and does not modify the // underlying storage. |limit| limits the number of reports to return; use // a negative number for no limit. - virtual std::vector<AttributionReport> GetAttributionsToReport( + virtual std::vector<EventAttributionReport> GetAttributionsToReport( base::Time max_report_time, int limit = -1) WARN_UNUSED_RESULT = 0; @@ -233,12 +233,12 @@ // Deletes the report with the given |report_id|. Returns // false if an error occurred. - virtual bool DeleteReport(AttributionReport::Id report_id) = 0; + virtual bool DeleteReport(EventAttributionReport::Id report_id) = 0; // Updates the number of failures associated with the given report, and sets // its report time to the given value. Should be called after a transient // failure to send the report so that it is retried later. - virtual bool UpdateReportForSendFailure(AttributionReport::Id report_id, + virtual bool UpdateReportForSendFailure(EventAttributionReport::Id report_id, base::Time new_report_time) = 0; // Adjusts the report time of all reports that should have been sent while the
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc index d9ca55c91a..0499d565 100644 --- a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
@@ -6,8 +6,8 @@ #include "base/guid.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,11 +17,11 @@ constexpr base::TimeDelta kDefaultExpiry = base::Days(30); -AttributionReport GetReport(base::Time impression_time, - base::Time conversion_time, - base::TimeDelta expiry = kDefaultExpiry, - StorableSource::SourceType source_type = - StorableSource::SourceType::kNavigation) { +EventAttributionReport GetReport(base::Time impression_time, + base::Time conversion_time, + base::TimeDelta expiry = kDefaultExpiry, + StorableSource::SourceType source_type = + StorableSource::SourceType::kNavigation) { return ReportBuilder(SourceBuilder(impression_time) .SetExpiry(expiry) .SetSourceType(source_type) @@ -34,7 +34,7 @@ TEST(AttributionStorageDelegateImplTest, ImmediateConversion_FirstWindowUsed) { base::Time impression_time = base::Time::Now(); - const AttributionReport report = + const EventAttributionReport report = GetReport(impression_time, /*conversion_time=*/impression_time); EXPECT_EQ(impression_time + base::Days(2), AttributionStorageDelegateImpl().GetReportTime( @@ -46,7 +46,8 @@ base::Time impression_time = base::Time::Now(); base::Time conversion_time = impression_time + base::Days(2) - base::Minutes(1); - const AttributionReport report = GetReport(impression_time, conversion_time); + const EventAttributionReport report = + GetReport(impression_time, conversion_time); EXPECT_EQ(impression_time + base::Days(7), AttributionStorageDelegateImpl().GetReportTime( report.source(), report.conversion_time())); @@ -60,7 +61,8 @@ // before the deadline. base::Time conversion_time = impression_time + base::Days(2) - base::Minutes(61); - const AttributionReport report = GetReport(impression_time, conversion_time); + const EventAttributionReport report = + GetReport(impression_time, conversion_time); EXPECT_EQ(impression_time + base::Days(2), AttributionStorageDelegateImpl().GetReportTime( report.source(), report.conversion_time())); @@ -72,8 +74,9 @@ base::Time conversion_time = impression_time + base::Hours(1); // Set the impression to expire before the two day window. - const AttributionReport report = GetReport(impression_time, conversion_time, - /*expiry=*/base::Hours(2)); + const EventAttributionReport report = + GetReport(impression_time, conversion_time, + /*expiry=*/base::Hours(2)); EXPECT_EQ(impression_time + base::Days(2), AttributionStorageDelegateImpl().GetReportTime( report.source(), report.conversion_time())); @@ -85,8 +88,9 @@ base::Time conversion_time = impression_time + base::Days(3); // Set the impression to expire before the two day window. - const AttributionReport report = GetReport(impression_time, conversion_time, - /*expiry=*/base::Days(4)); + const EventAttributionReport report = + GetReport(impression_time, conversion_time, + /*expiry=*/base::Days(4)); // The expiry window is reported one hour after expiry time. EXPECT_EQ(impression_time + base::Days(4) + base::Hours(1), @@ -100,8 +104,9 @@ base::Time conversion_time = impression_time + base::Days(7); // Set the impression to expire before the two day window. - const AttributionReport report = GetReport(impression_time, conversion_time, - /*expiry=*/base::Days(9)); + const EventAttributionReport report = + GetReport(impression_time, conversion_time, + /*expiry=*/base::Days(9)); // The expiry window is reported one hour after expiry time. EXPECT_EQ(impression_time + base::Days(9) + base::Hours(1), @@ -113,7 +118,7 @@ SourceTypeEvent_ExpiryLessThanTwoDays_TwoDaysUsed) { base::Time impression_time = base::Time::Now(); base::Time conversion_time = impression_time + base::Days(3); - const AttributionReport report = + const EventAttributionReport report = GetReport(impression_time, conversion_time, /*expiry=*/base::Days(1), StorableSource::SourceType::kEvent); EXPECT_EQ(impression_time + base::Days(2) + base::Hours(1), @@ -125,7 +130,7 @@ SourceTypeEvent_ExpiryGreaterThanTwoDays_ExpiryUsed) { base::Time impression_time = base::Time::Now(); base::Time conversion_time = impression_time + base::Days(3); - const AttributionReport report = + const EventAttributionReport report = GetReport(impression_time, conversion_time, /*expiry=*/base::Days(4), StorableSource::SourceType::kEvent); EXPECT_EQ(impression_time + base::Days(4) + base::Hours(1),
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 79ac515..265f5d5 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -20,8 +20,8 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage_sql_migrations.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/sql_utils.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" @@ -461,13 +461,13 @@ const base::Time report_time = delegate_->GetReportTime(source, conversion_time); - AttributionReport report(source, event_source_trigger_data, - /*conversion_time=*/conversion_time, - /*report_time=*/report_time, - /*priority=*/0, - /*external_report_id=*/ - delegate_->NewReportID(), - /*report_id=*/absl::nullopt); + EventAttributionReport report(source, event_source_trigger_data, + /*conversion_time=*/conversion_time, + /*report_time=*/report_time, + /*priority=*/0, + /*external_report_id=*/ + delegate_->NewReportID(), + /*report_id=*/absl::nullopt); if (!StoreReport(report, source_id)) return {}; @@ -489,10 +489,10 @@ // one should be stored. AttributionStorageSql::MaybeReplaceLowerPriorityReportResult AttributionStorageSql::MaybeReplaceLowerPriorityReport( - const AttributionReport& report, + const EventAttributionReport& report, int num_conversions, int64_t conversion_priority, - absl::optional<AttributionReport>& replaced_report) { + absl::optional<EventAttributionReport>& replaced_report) { DCHECK(report.source().impression_id().has_value()); DCHECK_GE(num_conversions, 0); @@ -537,7 +537,7 @@ } int64_t min_priority = min_priority_statement.ColumnInt64(0); - AttributionReport::Id conversion_id_with_min_priority( + EventAttributionReport::Id conversion_id_with_min_priority( min_priority_statement.ColumnInt64(1)); // If the new report's priority is less than all existing ones, or if its @@ -549,7 +549,7 @@ return MaybeReplaceLowerPriorityReportResult::kDropNewReport; } - absl::optional<AttributionReport> replaced = + absl::optional<EventAttributionReport> replaced = GetReport(conversion_id_with_min_priority); if (!replaced.has_value()) { return MaybeReplaceLowerPriorityReportResult::kError; @@ -657,11 +657,12 @@ const base::Time report_time = delegate_->GetReportTime(source_to_attribute->source, /*trigger_time=*/current_time); - AttributionReport report(std::move(source_to_attribute->source), trigger_data, - /*conversion_time=*/current_time, - /*report_time=*/report_time, trigger.priority(), - /*external_report_id=*/delegate_->NewReportID(), - /*report_id=*/absl::nullopt); + EventAttributionReport report(std::move(source_to_attribute->source), + trigger_data, + /*conversion_time=*/current_time, + /*report_time=*/report_time, trigger.priority(), + /*external_report_id=*/delegate_->NewReportID(), + /*report_id=*/absl::nullopt); switch ( rate_limit_table_.AttributionAllowed(db_.get(), report, current_time)) { @@ -679,7 +680,7 @@ return CreateReportResult(CreateReportStatus::kInternalError); } - absl::optional<AttributionReport> replaced_report; + absl::optional<EventAttributionReport> replaced_report; const auto maybe_replace_lower_priority_report_result = MaybeReplaceLowerPriorityReport(report, source_to_attribute->num_conversions, @@ -788,7 +789,7 @@ /*dropped_report_source_deactivation_reason=*/absl::nullopt, report_time); } -bool AttributionStorageSql::StoreReport(const AttributionReport& report, +bool AttributionStorageSql::StoreReport(const EventAttributionReport& report, StorableSource::Id source_id) { static constexpr char kStoreReportSql[] = "INSERT INTO conversions" @@ -810,12 +811,12 @@ // Helper to deserialize report rows. See `GetReport()` for the expected // ordering of columns used for the input to this function. -absl::optional<AttributionReport> ReadReportFromStatement( +absl::optional<EventAttributionReport> ReadReportFromStatement( sql::Statement& statement) { uint64_t trigger_data = DeserializeUint64(statement.ColumnInt64(0)); base::Time conversion_time = statement.ColumnTime(1); base::Time report_time = statement.ColumnTime(2); - AttributionReport::Id conversion_id(statement.ColumnInt64(3)); + EventAttributionReport::Id conversion_id(statement.ColumnInt64(3)); int64_t conversion_priority = statement.ColumnInt64(4); int failed_send_attempts = statement.ColumnInt(5); base::GUID external_report_id = @@ -846,7 +847,7 @@ return absl::nullopt; } - // Create the source and AttributionReport objects from the retrieved + // Create the source and EventAttributionReport objects from the retrieved // columns. StorableSource source(source_event_id, std::move(impression_origin), std::move(conversion_origin), @@ -854,18 +855,18 @@ expiry_time, *source_type, attribution_source_priority, *attribution_logic, source_id); - AttributionReport report(std::move(source), trigger_data, conversion_time, - report_time, conversion_priority, - std::move(external_report_id), conversion_id); + EventAttributionReport report( + std::move(source), trigger_data, conversion_time, report_time, + conversion_priority, std::move(external_report_id), conversion_id); report.set_failed_send_attempts(failed_send_attempts); return report; } } // namespace -std::vector<AttributionReport> AttributionStorageSql::GetAttributionsToReport( - base::Time max_report_time, - int limit) { +std::vector<EventAttributionReport> +AttributionStorageSql::GetAttributionsToReport(base::Time max_report_time, + int limit) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent)) return {}; @@ -888,9 +889,9 @@ statement.BindTime(0, max_report_time); statement.BindInt(1, limit); - std::vector<AttributionReport> reports; + std::vector<EventAttributionReport> reports; while (statement.Step()) { - absl::optional<AttributionReport> report = + absl::optional<EventAttributionReport> report = ReadReportFromStatement(statement); if (report.has_value()) reports.push_back(std::move(*report)); @@ -922,8 +923,8 @@ return absl::nullopt; } -absl::optional<AttributionReport> AttributionStorageSql::GetReport( - AttributionReport::Id conversion_id) { +absl::optional<EventAttributionReport> AttributionStorageSql::GetReport( + EventAttributionReport::Id conversion_id) { static constexpr char kGetReportSql[] = "SELECT C.conversion_data,C.conversion_time,C.report_time," "C.conversion_id,C.priority,C.failed_send_attempts,C.external_report_id," @@ -1001,7 +1002,7 @@ return delete_sources_from_paged_select(select_inactive_statement); } -bool AttributionStorageSql::DeleteReport(AttributionReport::Id report_id) { +bool AttributionStorageSql::DeleteReport(EventAttributionReport::Id report_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent)) return true; @@ -1009,7 +1010,7 @@ } bool AttributionStorageSql::DeleteReportInternal( - AttributionReport::Id report_id) { + EventAttributionReport::Id report_id) { static constexpr char kDeleteReportSql[] = "DELETE FROM conversions WHERE conversion_id = ?"; sql::Statement statement( @@ -1019,7 +1020,7 @@ } bool AttributionStorageSql::UpdateReportForSendFailure( - AttributionReport::Id conversion_id, + EventAttributionReport::Id conversion_id, base::Time new_report_time) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent)) @@ -1107,7 +1108,7 @@ statement.BindTime(1, delete_end); std::vector<StorableSource::Id> source_ids_to_delete; - std::vector<AttributionReport::Id> conversion_ids_to_delete; + std::vector<EventAttributionReport::Id> conversion_ids_to_delete; while (statement.Step()) { if (filter.Run(DeserializeOrigin(statement.ColumnString(0))) || filter.Run(DeserializeOrigin(statement.ColumnString(1))) || @@ -1140,7 +1141,7 @@ if (!DeleteSources(source_ids_to_delete)) return; - for (AttributionReport::Id conversion_id : conversion_ids_to_delete) { + for (EventAttributionReport::Id conversion_id : conversion_ids_to_delete) { if (!DeleteReportInternal(conversion_id)) return; }
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index 2fb1864..ec1fa86e3 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -83,13 +83,13 @@ int deactivated_source_return_limit = -1) override; CreateReportResult MaybeCreateAndStoreReport( const StorableTrigger& trigger) override; - std::vector<AttributionReport> GetAttributionsToReport( + std::vector<EventAttributionReport> GetAttributionsToReport( base::Time max_report_time, int limit = -1) override; absl::optional<base::Time> GetNextReportTime(base::Time time) override; std::vector<StorableSource> GetActiveSources(int limit = -1) override; - bool DeleteReport(AttributionReport::Id report_id) override; - bool UpdateReportForSendFailure(AttributionReport::Id report_id, + bool DeleteReport(EventAttributionReport::Id report_id) override; + bool UpdateReportForSendFailure(EventAttributionReport::Id report_id, base::Time new_report_time) override; absl::optional<base::Time> AdjustOfflineReportTimes( base::TimeDelta min_delay, @@ -124,7 +124,7 @@ // Deletes the report with `report_id` without checking the the DB // initialization status or the number of deleted rows. Returns false on // failure. - bool DeleteReportInternal(AttributionReport::Id report_id) + bool DeleteReportInternal(EventAttributionReport::Id report_id) VALID_CONTEXT_REQUIRED(sequence_checker_) WARN_UNUSED_RESULT; bool HasCapacityForStoringSource(const std::string& serialized_origin) @@ -159,13 +159,14 @@ kReplaceOldReport, }; MaybeReplaceLowerPriorityReportResult MaybeReplaceLowerPriorityReport( - const AttributionReport& report, + const EventAttributionReport& report, int num_conversions, int64_t conversion_priority, - absl::optional<AttributionReport>& replaced_report) + absl::optional<EventAttributionReport>& replaced_report) VALID_CONTEXT_REQUIRED(sequence_checker_) WARN_UNUSED_RESULT; - absl::optional<AttributionReport> GetReport(AttributionReport::Id report_id) + absl::optional<EventAttributionReport> GetReport( + EventAttributionReport::Id report_id) VALID_CONTEXT_REQUIRED(sequence_checker_) WARN_UNUSED_RESULT; absl::optional<std::vector<int64_t>> ReadDedupKeys( @@ -179,8 +180,8 @@ VALID_CONTEXT_REQUIRED(sequence_checker_) WARN_UNUSED_RESULT; // Stores |report| in the database, but uses |source_id| rather than - // |AttributionReport::impression::impression_id()|, which may be null. - bool StoreReport(const AttributionReport& report, + // |EventAttributionReport::impression::impression_id()|, which may be null. + bool StoreReport(const EventAttributionReport& report, StorableSource::Id source_id) VALID_CONTEXT_REQUIRED(sequence_checker_) WARN_UNUSED_RESULT;
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc index a33a0f6..99d96d4 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc
@@ -8,8 +8,8 @@ #include "base/guid.h" #include "base/metrics/histogram_functions.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/sql_utils.h" #include "content/browser/attribution_reporting/storable_source.h" #include "net/base/schemeful_site.h" @@ -29,8 +29,8 @@ } WARN_UNUSED_RESULT -AttributionReport::Id NextConversionId(AttributionReport::Id id) { - return AttributionReport::Id(*id + 1); +EventAttributionReport::Id NextConversionId(EventAttributionReport::Id id) { + return EventAttributionReport::Id(*id + 1); } struct ImpressionIdAndConversionOrigin { @@ -103,9 +103,9 @@ return impressions; } -std::vector<AttributionReport::Id> GetConversionIds( +std::vector<EventAttributionReport::Id> GetConversionIds( sql::Database* db, - AttributionReport::Id start_conversion_id) { + EventAttributionReport::Id start_conversion_id) { static constexpr char kGetConversionsSql[] = "SELECT conversion_id FROM conversions " "WHERE conversion_id >= ? " @@ -119,7 +119,7 @@ const int kNumConversions = 100; statement.BindInt(1, kNumConversions); - std::vector<AttributionReport::Id> conversion_ids; + std::vector<EventAttributionReport::Id> conversion_ids; while (statement.Step()) { conversion_ids.emplace_back(statement.ColumnInt64(0)); } @@ -1164,8 +1164,8 @@ // // We update a subset of rows at a time to avoid pulling the entire // conversions table into memory. - std::vector<AttributionReport::Id> conversion_ids = - GetConversionIds(db, AttributionReport::Id(0)); + std::vector<EventAttributionReport::Id> conversion_ids = + GetConversionIds(db, EventAttributionReport::Id(0)); static constexpr char kUpdateExternalReportIdSql[] = "UPDATE new_conversions SET external_report_id = ? " @@ -1175,7 +1175,7 @@ while (!conversion_ids.empty()) { // Perform the column updates for each row we pulled into memory. - for (AttributionReport::Id conversion_id : conversion_ids) { + for (EventAttributionReport::Id conversion_id : conversion_ids) { update_statement.Reset(/*clear_bound_vars=*/true); base::GUID external_report_id = delegate->NewReportID();
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc index f3d9087..09117841 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
@@ -15,8 +15,8 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" #include "sql/database.h" @@ -54,7 +54,7 @@ void CloseDatabase() { storage_.reset(); } void AddReportToStorage() { - storage_->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage_->StoreSource(SourceBuilder().Build()); storage_->MaybeCreateAndStoreReport(DefaultTrigger()); } @@ -133,7 +133,7 @@ // Storing an impression should create and initialize the database. OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); CloseDatabase(); // DB creation histograms should be recorded. @@ -318,9 +318,9 @@ TEST_F(AttributionStorageSqlTest, MaxSourcesPerOrigin) { OpenDatabase(); delegate()->set_max_sources_per_origin(2); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); + storage()->StoreSource(SourceBuilder().Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -338,7 +338,7 @@ TEST_F(AttributionStorageSqlTest, MaxAttributionsPerOrigin) { OpenDatabase(); delegate()->set_max_attributions_per_origin(2); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -371,7 +371,7 @@ url::Origin::Create(GURL("https://a.example/")); const url::Origin conversion_origin = url::Origin::Create(GURL("https://b.example/")); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetExpiry(base::Days(30)) .SetImpressionOrigin(impression_origin) .SetReportingOrigin(reporting_origin) @@ -401,7 +401,7 @@ EXPECT_THAT(storage()->GetActiveSources(), IsEmpty()); task_environment_.FastForwardBy(base::Days(1)); - EXPECT_TRUE(storage()->DeleteReport(AttributionReport::Id(1))); + EXPECT_TRUE(storage()->DeleteReport(EventAttributionReport::Id(1))); storage()->ClearData( base::Time::Min(), base::Time::Max(), base::BindRepeating(std::equal_to<url::Origin>(), impression_origin)); @@ -431,7 +431,7 @@ url::Origin::Create(GURL("https://a.example/")); const url::Origin conversion_origin = url::Origin::Create(GURL("https://sub.impression.example/")); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetExpiry(base::Days(30)) .SetImpressionOrigin(impression_origin) .SetReportingOrigin(reporting_origin) @@ -461,7 +461,7 @@ EXPECT_THAT(storage()->GetActiveSources(), IsEmpty()); task_environment_.FastForwardBy(base::Days(1)); - EXPECT_TRUE(storage()->DeleteReport(AttributionReport::Id(1))); + EXPECT_TRUE(storage()->DeleteReport(EventAttributionReport::Id(1))); storage()->ClearData( base::Time::Min(), base::Time::Max(), base::BindRepeating(std::equal_to<url::Origin>(), conversion_origin)); @@ -488,7 +488,7 @@ std::unique_ptr<AttributionStorage> storage = std::move(sql_storage); // These calls should be no-ops. - storage->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kNoMatchingImpressions, storage->MaybeCreateAndStoreReport(DefaultTrigger()).status()); } @@ -502,7 +502,7 @@ std::make_unique<ConfigurableStorageDelegate>()); // The directory should be created, and the database opened. - storage->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, storage->MaybeCreateAndStoreReport(DefaultTrigger()).status()); } @@ -511,7 +511,7 @@ base::HistogramTester histograms; OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); CloseDatabase(); histograms.ExpectUniqueSample("Conversions.Storage.Sql.InitStatus2", @@ -527,8 +527,7 @@ // `sql::Statement::ColumnInt64()` and `sql::Statement::BindInt64()` works // with the maximum value. - const auto impression = - SourceBuilder(base::Time::Now()).SetSourceEventId(kMaxUint64).Build(); + const auto impression = SourceBuilder().SetSourceEventId(kMaxUint64).Build(); storage()->StoreSource(impression); EXPECT_THAT(storage()->GetActiveSources(), ElementsAre(impression)); @@ -543,19 +542,17 @@ EXPECT_THAT( storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::trigger_data, kMaxUint64))); + ElementsAre(Property(&EventAttributionReport::trigger_data, kMaxUint64))); } TEST_F(AttributionStorageSqlTest, ImpressionNotExpired_NotDeleted) { OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(2u); @@ -564,14 +561,12 @@ TEST_F(AttributionStorageSqlTest, ImpressionExpired_Deleted) { OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); task_environment_.FastForwardBy(base::Milliseconds(3)); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(1u); @@ -582,14 +577,12 @@ delegate()->set_delete_expired_sources_frequency(base::Milliseconds(4)); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); task_environment_.FastForwardBy(base::Milliseconds(3)); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(2u); @@ -599,17 +592,15 @@ ExpiredImpressionWithPendingConversion_NotDeleted) { OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); task_environment_.FastForwardBy(base::Milliseconds(3)); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(2u); @@ -618,18 +609,15 @@ TEST_F(AttributionStorageSqlTest, TwoImpressionsOneExpired_OneDeleted) { OpenDatabase(); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(4)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(4)).Build()); task_environment_.FastForwardBy(base::Milliseconds(3)); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(2u); @@ -641,9 +629,8 @@ const int kReportTime = 5; delegate()->set_report_time_ms(kReportTime); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -651,14 +638,13 @@ // Advance past the default report time. task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> reports = + std::vector<EventAttributionReport> reports = storage()->GetAttributionsToReport(base::Time::Now()); EXPECT_THAT(reports, SizeIs(1)); EXPECT_TRUE(storage()->DeleteReport(*reports[0].report_id())); // Store another impression to trigger the expiry logic. - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(3)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(3)).Build()); CloseDatabase(); ExpectImpressionRows(1u);
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index 222fcd4..309ed01 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -21,9 +21,9 @@ #include "base/test/task_environment.h" #include "base/time/time.h" #include "build/build_config.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage_sql.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" #include "content/public/common/url_constants.h" @@ -79,8 +79,8 @@ // Given a |conversion|, returns the expected conversion report properties at // the current timestamp. - AttributionReport GetExpectedReport(const StorableSource& impression, - const StorableTrigger& conversion) { + EventAttributionReport GetExpectedReport(const StorableSource& impression, + const StorableTrigger& conversion) { return ReportBuilder(impression) .SetTriggerData(conversion.trigger_data()) .SetConversionTime(base::Time::Now()) @@ -95,7 +95,7 @@ return storage_->MaybeCreateAndStoreReport(conversion).status(); } - void DeleteReports(const std::vector<AttributionReport>& reports) { + void DeleteReports(const std::vector<EventAttributionReport>& reports) { for (const auto& report : reports) { EXPECT_TRUE(storage_->DeleteReport(*report.report_id())); } @@ -128,13 +128,12 @@ ->set_ignore_errors_for_testing(true); // Test all public methods on AttributionStorage. - EXPECT_NO_FATAL_FAILURE( - storage->StoreSource(SourceBuilder(base::Time::Now()).Build())); + EXPECT_NO_FATAL_FAILURE(storage->StoreSource(SourceBuilder().Build())); EXPECT_EQ(CreateReportStatus::kNoMatchingImpressions, storage->MaybeCreateAndStoreReport(DefaultTrigger()).status()); EXPECT_THAT(storage->GetAttributionsToReport(base::Time::Now()), IsEmpty()); EXPECT_THAT(storage->GetActiveSources(), IsEmpty()); - EXPECT_TRUE(storage->DeleteReport(AttributionReport::Id(0))); + EXPECT_TRUE(storage->DeleteReport(EventAttributionReport::Id(0))); EXPECT_NO_FATAL_FAILURE(storage->ClearData( base::Time::Min(), base::Time::Max(), base::NullCallback())); EXPECT_EQ( @@ -143,7 +142,7 @@ } TEST_F(AttributionStorageTest, ImpressionStoredAndRetrieved_ValuesIdentical) { - auto impression = SourceBuilder(base::Time::Now()).Build(); + auto impression = SourceBuilder().Build(); storage()->StoreSource(impression); EXPECT_THAT(storage()->GetActiveSources(), ElementsAre(impression)); } @@ -153,7 +152,7 @@ ImpressionStoredAndRetrieved_ValuesIdentical_AndroidApp) { url::ScopedSchemeRegistryForTests scoped_registry; url::AddStandardScheme(kAndroidAppScheme, url::SCHEME_WITH_HOST); - auto impression = SourceBuilder(base::Time::Now()) + auto impression = SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("android-app:com.any.app"))) .Build(); @@ -172,14 +171,14 @@ } TEST_F(AttributionStorageTest, GetWithMatchingImpression_ImpressionReturned) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); } TEST_F(AttributionStorageTest, MultipleImpressionsForConversion_OneConverts) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); } @@ -187,7 +186,7 @@ TEST_F(AttributionStorageTest, CrossOriginSameDomainConversion_ImpressionConverted) { auto impression = - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetConversionOrigin(url::Origin::Create(GURL("https://sub.a.test"))) .Build(); storage()->StoreSource(impression); @@ -201,7 +200,7 @@ } TEST_F(AttributionStorageTest, EventSourceImpressionsForConversion_Converts) { - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetSourceType(StorableSource::SourceType::kEvent) .Build()); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -210,14 +209,14 @@ task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::trigger_data, 456u))); + EXPECT_THAT( + storage()->GetAttributionsToReport(base::Time::Now()), + ElementsAre(Property(&EventAttributionReport::trigger_data, 456u))); } TEST_F(AttributionStorageTest, ImpressionExpired_NoConversionsStored) { - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(2)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(2)).Build()); task_environment_.FastForwardBy(base::Milliseconds(2)); EXPECT_EQ(CreateReportStatus::kNoMatchingImpressions, @@ -225,9 +224,8 @@ } TEST_F(AttributionStorageTest, ImpressionExpired_ConversionsStoredPrior) { - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetExpiry(base::Milliseconds(4)) - .Build()); + storage()->StoreSource( + SourceBuilder().SetExpiry(base::Milliseconds(4)).Build()); task_environment_.FastForwardBy(base::Milliseconds(3)); @@ -242,7 +240,7 @@ TEST_F(AttributionStorageTest, ImpressionWithMaxConversions_ConversionReportNotStored) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); for (int i = 0; i < kMaxConversions; i++) { EXPECT_EQ(CreateReportStatus::kSuccess, @@ -259,14 +257,15 @@ } TEST_F(AttributionStorageTest, OneConversion_OneReportScheduled) { - auto impression = SourceBuilder(base::Time::Now()).Build(); + auto impression = SourceBuilder().Build(); auto conversion = DefaultTrigger(); storage()->StoreSource(impression); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); - AttributionReport expected_report = GetExpectedReport(impression, conversion); + EventAttributionReport expected_report = + GetExpectedReport(impression, conversion); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); @@ -276,7 +275,7 @@ TEST_F(AttributionStorageTest, ConversionWithDifferentReportingOrigin_NoReportScheduled) { - auto impression = SourceBuilder(base::Time::Now()) + auto impression = SourceBuilder() .SetReportingOrigin( url::Origin::Create(GURL("https://different.test"))) .Build(); @@ -291,7 +290,7 @@ TEST_F(AttributionStorageTest, ConversionWithDifferentConversionOrigin_NoReportScheduled) { - auto impression = SourceBuilder(base::Time::Now()) + auto impression = SourceBuilder() .SetConversionOrigin( url::Origin::Create(GURL("https://different.test"))) .Build(); @@ -305,13 +304,13 @@ } TEST_F(AttributionStorageTest, ConversionReportDeleted_RemovedFromStorage) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> reports = + std::vector<EventAttributionReport> reports = storage()->GetAttributionsToReport(base::Time::Now()); EXPECT_THAT(reports, SizeIs(1)); DeleteReports(reports); @@ -325,7 +324,7 @@ // Store a large, arbitrary number of impressions. for (int i = 0; i < kNumMultiTouchImpressions; i++) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); } for (int i = 0; i < kMaxConversions; i++) { @@ -341,10 +340,10 @@ TEST_F(AttributionStorageTest, MultipleImpressionsForConversion_UnattributedImpressionsInactive) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); auto new_impression = - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(url::Origin::Create(GURL("https://other.test/"))) .Build(); storage()->StoreSource(new_impression); @@ -363,8 +362,7 @@ // multi-touch model. TEST_F(AttributionStorageTest, NewImpressionForConvertedImpression_MarkedInactive) { - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(0).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(0).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -374,15 +372,14 @@ DeleteReports(storage()->GetAttributionsToReport(base::Time::Now())); // Store a new impression that should mark the first inactive. - auto new_impression = - SourceBuilder(base::Time::Now()).SetSourceEventId(1000).Build(); + auto new_impression = SourceBuilder().SetSourceEventId(1000).Build(); storage()->StoreSource(new_impression); // Only the new impression should convert. auto conversion = DefaultTrigger(); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); - AttributionReport expected_report = + EventAttributionReport expected_report = GetExpectedReport(new_impression, conversion); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); @@ -394,7 +391,7 @@ TEST_F(AttributionStorageTest, NonMatchingImpressionForConvertedImpression_FirstRemainsActive) { - auto first_impression = SourceBuilder(base::Time::Now()).Build(); + auto first_impression = SourceBuilder().Build(); storage()->StoreSource(first_impression); auto conversion = DefaultTrigger(); @@ -407,7 +404,7 @@ DeleteReports(storage()->GetAttributionsToReport(base::Time::Now())); // Store a new impression with a different reporting origin. - auto new_impression = SourceBuilder(base::Time::Now()) + auto new_impression = SourceBuilder() .SetReportingOrigin(url::Origin::Create( GURL("https://different.test"))) .Build(); @@ -417,7 +414,7 @@ EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); - AttributionReport expected_report = + EventAttributionReport expected_report = GetExpectedReport(first_impression, conversion); // Verify it was the first impression that converted. @@ -428,10 +425,10 @@ TEST_F( AttributionStorageTest, MultipleImpressionsForConversionAtDifferentTimes_OneImpressionAttributed) { - auto first_impression = SourceBuilder(base::Time::Now()).Build(); + auto first_impression = SourceBuilder().Build(); storage()->StoreSource(first_impression); - auto second_impression = SourceBuilder(base::Time::Now()).Build(); + auto second_impression = SourceBuilder().Build(); storage()->StoreSource(second_impression); auto conversion = DefaultTrigger(); @@ -440,11 +437,10 @@ task_environment_.FastForwardBy(base::Milliseconds(3)); // Make a conversion with different impression data. - auto third_impression = - SourceBuilder(base::Time::Now()).SetSourceEventId(10).Build(); + auto third_impression = SourceBuilder().SetSourceEventId(10).Build(); storage()->StoreSource(third_impression); - AttributionReport third_expected_conversion = + EventAttributionReport third_expected_conversion = GetExpectedReport(third_impression, conversion); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); @@ -457,15 +453,15 @@ TEST_F(AttributionStorageTest, ImpressionsAtDifferentTimes_AttributedImpressionHasCorrectReportTime) { - auto first_impression = SourceBuilder(base::Time::Now()).Build(); + auto first_impression = SourceBuilder().Build(); storage()->StoreSource(first_impression); // Advance clock so the next impression is stored at a different timestamp. task_environment_.FastForwardBy(base::Milliseconds(2)); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); task_environment_.FastForwardBy(base::Milliseconds(2)); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -481,14 +477,14 @@ TEST_F(AttributionStorageTest, GetAttributionsToReportMultipleTimes_SameResult) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> first_call_reports = + std::vector<EventAttributionReport> first_call_reports = storage()->GetAttributionsToReport(base::Time::Now()); - std::vector<AttributionReport> second_call_reports = + std::vector<EventAttributionReport> second_call_reports = storage()->GetAttributionsToReport(base::Time::Now()); // Expect that |GetAttributionsToReport()| did not delete any conversions. @@ -497,12 +493,9 @@ TEST_F(AttributionStorageTest, MaxImpressionsPerOrigin_LimitsStorage) { delegate()->set_max_sources_per_origin(2); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(3).Build()); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(5).Build()); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(7).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(3).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(5).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(7).Build()); EXPECT_THAT(storage()->GetActiveSources(), ElementsAre(Property(&StorableSource::source_event_id, 3u), @@ -511,17 +504,17 @@ TEST_F(AttributionStorageTest, MaxImpressionsPerOrigin_PerOriginNotSite) { delegate()->set_max_sources_per_origin(2); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("https://foo.a.example"))) .SetSourceEventId(3) .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("https://foo.a.example"))) .SetSourceEventId(5) .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("https://bar.a.example"))) .SetSourceEventId(7) @@ -534,14 +527,14 @@ // This impression shouldn't be stored, because its origin has already hit the // limit of 2. - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("https://foo.a.example"))) .SetSourceEventId(9) .Build()); // This impression should be stored, because its origin hasn't hit the limit // of 2. - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetImpressionOrigin(url::Origin::Create( GURL("https://bar.a.example"))) .SetSourceEventId(11) @@ -556,8 +549,8 @@ TEST_F(AttributionStorageTest, MaxConversionsPerOrigin) { delegate()->set_max_attributions_per_origin(1); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); // Verify that MaxConversionsPerOrigin is enforced. @@ -683,7 +676,7 @@ task_environment_.FastForwardBy(base::Days(1)); - const AttributionReport expected_report = + const EventAttributionReport expected_report = GetExpectedReport(impression, conversion); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -703,10 +696,8 @@ storage()->StoreSource(impression1); task_environment_.FastForwardBy(base::Days(1)); - auto impression2 = - SourceBuilder(base::Time::Now()).SetExpiry(base::Days(30)).Build(); - auto impression3 = - SourceBuilder(base::Time::Now()).SetExpiry(base::Days(30)).Build(); + auto impression2 = SourceBuilder().SetExpiry(base::Days(30)).Build(); + auto impression3 = SourceBuilder().SetExpiry(base::Days(30)).Build(); storage()->StoreSource(impression2); storage()->StoreSource(impression3); @@ -772,10 +763,10 @@ .max_contributions_per_window = 2, }); - auto impression = SourceBuilder(base::Time::Now()).Build(); + auto impression = SourceBuilder().Build(); auto conversion = DefaultTrigger(); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -785,7 +776,7 @@ CreateReportStatus::kRateLimited), Property(&CreateReportResult::dropped_report, IsTrue()))); - const AttributionReport expected_report = + const EventAttributionReport expected_report = GetExpectedReport(impression, conversion); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), @@ -800,13 +791,13 @@ }); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceType(StorableSource::SourceType::kNavigation) .Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetSourceType(StorableSource::SourceType::kEvent) .Build()); // This would fail if the source types had a combined limit or the incorrect @@ -814,14 +805,14 @@ EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetSourceType(StorableSource::SourceType::kEvent) .Build()); EXPECT_EQ(CreateReportStatus::kRateLimited, MaybeCreateAndStoreReport(DefaultTrigger())); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceType(StorableSource::SourceType::kNavigation) .Build()); EXPECT_EQ(CreateReportStatus::kRateLimited, @@ -831,7 +822,7 @@ TEST_F(AttributionStorageTest, NeverAttributeImpression_ReportNotStored) { delegate()->set_max_attributions_per_source(1); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetAttributionLogic(StorableSource::AttributionLogic::kNever) .Build()); @@ -846,7 +837,7 @@ TEST_F(AttributionStorageTest, NeverAttributeImpression_Deactivates) { delegate()->set_max_attributions_per_source(1); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(3) .SetAttributionLogic(StorableSource::AttributionLogic::kNever) .Build()); @@ -854,8 +845,7 @@ EXPECT_EQ(CreateReportStatus::kDroppedForNoise, MaybeCreateAndStoreReport(DefaultTrigger())); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(5).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(5).Build()); EXPECT_EQ( CreateReportStatus::kSuccess, @@ -865,9 +855,9 @@ EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), ElementsAre(AllOf( - Property(&AttributionReport::source, + Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 5u)), - Property(&AttributionReport::trigger_data, 7u)))); + Property(&EventAttributionReport::trigger_data, 7u)))); } TEST_F(AttributionStorageTest, NeverAttributeImpression_RateLimitsNotChanged) { @@ -877,7 +867,7 @@ }); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(5) .SetAttributionLogic(StorableSource::AttributionLogic::kNever) .Build()); @@ -886,18 +876,16 @@ EXPECT_EQ(CreateReportStatus::kDroppedForNoise, MaybeCreateAndStoreReport(conversion)); - const auto impression = - SourceBuilder(base::Time::Now()).SetSourceEventId(7).Build(); + const auto impression = SourceBuilder().SetSourceEventId(7).Build(); storage()->StoreSource(impression); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(conversion)); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(9).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(9).Build()); EXPECT_EQ(CreateReportStatus::kRateLimited, MaybeCreateAndStoreReport(conversion)); - const AttributionReport expected_report = + const EventAttributionReport expected_report = GetExpectedReport(impression, conversion); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); @@ -908,12 +896,12 @@ TEST_F(AttributionStorageTest, NeverAndTruthfullyAttributeImpressions_ReportNotStored) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); task_environment_.FastForwardBy(base::Milliseconds(1)); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetAttributionLogic(StorableSource::AttributionLogic::kNever) .Build()); @@ -930,9 +918,8 @@ TEST_F(AttributionStorageTest, MaxAttributionDestinationsPerSource_AlreadyStored) { - const auto impression = SourceBuilder(base::Time::Now()) - .SetSourceType(StorableSource::SourceType::kEvent) - .Build(); + const auto impression = + SourceBuilder().SetSourceType(StorableSource::SourceType::kEvent).Build(); // Setting this doesn't affect the test behavior, but makes it clear that the // test passes without depending on the default value of |INT_MAX|. @@ -953,13 +940,13 @@ // test passes without depending on the default value of |INT_MAX|. delegate()->set_max_attribution_destinations_per_event_source(1); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(url::Origin::Create(GURL("https://a.example"))) .SetConversionOrigin(url::Origin::Create(GURL("https://c.example"))) .SetSourceType(StorableSource::SourceType::kEvent) .Build()); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(url::Origin::Create(GURL("https://b.example"))) .SetConversionOrigin(url::Origin::Create(GURL("https://d.example"))) .SetSourceType(StorableSource::SourceType::kEvent) @@ -977,11 +964,11 @@ // test passes without depending on the default value of |INT_MAX|. delegate()->set_max_attribution_destinations_per_event_source(1); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetConversionOrigin(url::Origin::Create(GURL("https://a.example/"))) .Build()); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetConversionOrigin(url::Origin::Create(GURL("https://b.example"))) .Build()); @@ -1012,7 +999,7 @@ delegate()->set_max_attribution_destinations_per_event_source( impression.max); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin( url::Origin::Create(GURL(impression.impression_origin))) .SetConversionOrigin( @@ -1036,7 +1023,7 @@ delegate()->set_max_attributions_per_source(1); delegate()->set_max_attribution_destinations_per_event_source(INT_MAX); - storage()->StoreSource(SourceBuilder(base::Time::Now()) + storage()->StoreSource(SourceBuilder() .SetSourceType(StorableSource::SourceType::kEvent) .Build()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(1)); @@ -1054,7 +1041,7 @@ task_environment_.FastForwardBy(base::Milliseconds(1)); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetConversionOrigin(url::Origin::Create(GURL("https://a.example"))) .SetSourceType(StorableSource::SourceType::kEvent) .Build()); @@ -1063,7 +1050,7 @@ delegate()->set_max_attribution_destinations_per_event_source(1); task_environment_.FastForwardBy(base::Milliseconds(1)); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetConversionOrigin(url::Origin::Create(GURL("https://b.example"))) .SetSourceType(StorableSource::SourceType::kEvent) .Build()); @@ -1085,16 +1072,13 @@ TEST_F(AttributionStorageTest, MultipleImpressionsPerConversion_MostRecentAttributesForSamePriority) { - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(3).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(3).Build()); task_environment_.FastForwardBy(base::Milliseconds(1)); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(7).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(7).Build()); task_environment_.FastForwardBy(base::Milliseconds(1)); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetSourceEventId(5).Build()); + storage()->StoreSource(SourceBuilder().SetSourceEventId(5).Build()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(3)); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -1104,28 +1088,22 @@ EXPECT_THAT( storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::source, + ElementsAre(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 5u)))); } TEST_F(AttributionStorageTest, MultipleImpressionsPerConversion_HighestPriorityAttributes) { - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetPriority(100) - .SetSourceEventId(3) - .Build()); + storage()->StoreSource( + SourceBuilder().SetPriority(100).SetSourceEventId(3).Build()); task_environment_.FastForwardBy(base::Milliseconds(1)); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetPriority(300) - .SetSourceEventId(5) - .Build()); + storage()->StoreSource( + SourceBuilder().SetPriority(300).SetSourceEventId(5).Build()); task_environment_.FastForwardBy(base::Milliseconds(1)); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetPriority(200) - .SetSourceEventId(7) - .Build()); + storage()->StoreSource( + SourceBuilder().SetPriority(200).SetSourceEventId(7).Build()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(3)); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -1135,19 +1113,15 @@ EXPECT_THAT( storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::source, + ElementsAre(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 5u)))); } TEST_F(AttributionStorageTest, MultipleImpressions_CorrectDeactivation) { - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(3) - .SetPriority(0) - .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(5) - .SetPriority(1) - .Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(3).SetPriority(0).Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(5).SetPriority(1).Build()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(2)); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -1165,7 +1139,7 @@ delegate()->set_max_attributions_per_source(1); const auto impression = - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(4) .SetSourceType(StorableSource::SourceType::kEvent) .SetPriority(100) @@ -1173,7 +1147,7 @@ .Build(); storage()->StoreSource(impression); - const AttributionReport expected_report = + const EventAttributionReport expected_report = ReportBuilder(impression) .SetTriggerData(7) .SetConversionTime(base::Time::Now()) @@ -1199,14 +1173,10 @@ TEST_F(AttributionStorageTest, TriggerPriority) { delegate()->set_max_attributions_per_source(1); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(3) - .SetPriority(0) - .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(5) - .SetPriority(1) - .Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(3).SetPriority(0).Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(5).SetPriority(1).Build()); EXPECT_THAT( storage()->MaybeCreateAndStoreReport( @@ -1219,16 +1189,14 @@ EXPECT_THAT( storage()->MaybeCreateAndStoreReport( TriggerBuilder().SetPriority(2).SetTriggerData(21).Build()), - AllOf( - Property(&CreateReportResult::status, - CreateReportStatus::kSuccessDroppedLowerPriority), - Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::trigger_data, 20u))))); + AllOf(Property(&CreateReportResult::status, + CreateReportStatus::kSuccessDroppedLowerPriority), + Property(&CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::trigger_data, + 20u))))); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(7) - .SetPriority(2) - .Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(7).SetPriority(2).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport( @@ -1238,29 +1206,29 @@ EXPECT_THAT( storage()->MaybeCreateAndStoreReport( TriggerBuilder().SetPriority(0).SetTriggerData(23).Build()), - AllOf( - Property(&CreateReportResult::status, - CreateReportStatus::kPriorityTooLow), - Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::trigger_data, 23u))))); + AllOf(Property(&CreateReportResult::status, + CreateReportStatus::kPriorityTooLow), + Property(&CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::trigger_data, + 23u))))); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); EXPECT_THAT( storage()->GetAttributionsToReport(base::Time::Now()), ElementsAre( - AllOf(Property(&AttributionReport::source, + AllOf(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 5u)), - Property(&AttributionReport::trigger_data, 21u)), - AllOf(Property(&AttributionReport::source, + Property(&EventAttributionReport::trigger_data, 21u)), + AllOf(Property(&EventAttributionReport::source, Property(&StorableSource::source_event_id, 7u)), - Property(&AttributionReport::trigger_data, 22u)))); + Property(&EventAttributionReport::trigger_data, 22u)))); } TEST_F(AttributionStorageTest, TriggerPriority_Simple) { delegate()->set_max_attributions_per_source(1); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); int i = 0; EXPECT_EQ(CreateReportStatus::kSuccess, @@ -1277,13 +1245,13 @@ task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::trigger_data, 9u))); + ElementsAre(Property(&EventAttributionReport::trigger_data, 9u))); } TEST_F(AttributionStorageTest, TriggerPriority_SamePriorityDeletesMostRecent) { delegate()->set_max_attributions_per_source(2); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport( @@ -1309,21 +1277,17 @@ TriggerBuilder().SetPriority(2).SetTriggerData(5).Build())); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::trigger_data, 3u), - Property(&AttributionReport::trigger_data, 5u))); + ElementsAre(Property(&EventAttributionReport::trigger_data, 3u), + Property(&EventAttributionReport::trigger_data, 5u))); } TEST_F(AttributionStorageTest, TriggerPriority_DeactivatesImpression) { delegate()->set_max_attributions_per_source(1); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(3) - .SetPriority(0) - .Build()); - storage()->StoreSource(SourceBuilder(base::Time::Now()) - .SetSourceEventId(5) - .SetPriority(1) - .Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(3).SetPriority(0).Build()); + storage()->StoreSource( + SourceBuilder().SetSourceEventId(5).SetPriority(1).Build()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(2)); EXPECT_EQ(CreateReportStatus::kSuccess, @@ -1349,12 +1313,12 @@ TEST_F(AttributionStorageTest, DedupKey_Dedups) { storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(1) .SetConversionOrigin(url::Origin::Create(GURL("https://a.example"))) .Build()); storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(2) .SetConversionOrigin(url::Origin::Create(GURL("https://b.example"))) .Build()); @@ -1414,10 +1378,11 @@ .Build())); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::trigger_data, 71u), - Property(&AttributionReport::trigger_data, 72u), - Property(&AttributionReport::trigger_data, 73u))); + EXPECT_THAT( + storage()->GetAttributionsToReport(base::Time::Now()), + ElementsAre(Property(&EventAttributionReport::trigger_data, 71u), + Property(&EventAttributionReport::trigger_data, 72u), + Property(&EventAttributionReport::trigger_data, 73u))); EXPECT_THAT( storage()->GetActiveSources(), @@ -1427,7 +1392,7 @@ TEST_F(AttributionStorageTest, DedupKey_DedupsAfterConversionDeletion) { storage()->StoreSource( - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetSourceEventId(1) .SetConversionOrigin(url::Origin::Create(GURL("https://a.example"))) .Build()); @@ -1446,10 +1411,10 @@ task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> actual_reports = + std::vector<EventAttributionReport> actual_reports = storage()->GetAttributionsToReport(base::Time::Now()); EXPECT_THAT(actual_reports, - ElementsAre(Property(&AttributionReport::trigger_data, 3u))); + ElementsAre(Property(&EventAttributionReport::trigger_data, 3u))); // Simulate the report being sent and deleted from storage. DeleteReports(actual_reports); @@ -1472,7 +1437,7 @@ } TEST_F(AttributionStorageTest, GetAttributionsToReport_SetsPriority) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ( CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(TriggerBuilder().SetPriority(13).Build())); @@ -1480,11 +1445,11 @@ task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(Property(&AttributionReport::priority, 13))); + ElementsAre(Property(&EventAttributionReport::priority, 13))); } TEST_F(AttributionStorageTest, NoIDReuse_Impression) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); auto sources = storage()->GetActiveSources(); EXPECT_THAT(sources, ElementsAre(Property(&StorableSource::impression_id, IsTrue()))); @@ -1494,7 +1459,7 @@ base::NullCallback()); EXPECT_THAT(storage()->GetActiveSources(), IsEmpty()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); sources = storage()->GetActiveSources(); EXPECT_THAT(sources, ElementsAre(Property(&StorableSource::impression_id, IsTrue()))); @@ -1504,41 +1469,41 @@ } TEST_F(AttributionStorageTest, NoIDReuse_Conversion) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); auto reports = storage()->GetAttributionsToReport(base::Time::Max()); - EXPECT_THAT(reports, - ElementsAre(Property(&AttributionReport::report_id, IsTrue()))); - const AttributionReport::Id id1 = *reports.front().report_id(); + EXPECT_THAT(reports, ElementsAre(Property(&EventAttributionReport::report_id, + IsTrue()))); + const EventAttributionReport::Id id1 = *reports.front().report_id(); storage()->ClearData(base::Time::Min(), base::Time::Max(), base::NullCallback()); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty()); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); reports = storage()->GetAttributionsToReport(base::Time::Max()); - EXPECT_THAT(reports, - ElementsAre(Property(&AttributionReport::report_id, IsTrue()))); - const AttributionReport::Id id2 = *reports.front().report_id(); + EXPECT_THAT(reports, ElementsAre(Property(&EventAttributionReport::report_id, + IsTrue()))); + const EventAttributionReport::Id id2 = *reports.front().report_id(); EXPECT_NE(id1, id2); } TEST_F(AttributionStorageTest, UpdateReportForSendFailure) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> actual_reports = + std::vector<EventAttributionReport> actual_reports = storage()->GetAttributionsToReport(base::Time::Now()); EXPECT_THAT( actual_reports, - ElementsAre(Property(&AttributionReport::failed_send_attempts, 0))); + ElementsAre(Property(&EventAttributionReport::failed_send_attempts, 0))); const base::TimeDelta delay = base::Days(2); const base::Time new_report_time = actual_reports[0].report_time() + delay; @@ -1547,14 +1512,15 @@ task_environment_.FastForwardBy(delay); - EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), - ElementsAre(AllOf( - Property(&AttributionReport::failed_send_attempts, 1), - Property(&AttributionReport::report_time, new_report_time)))); + EXPECT_THAT( + storage()->GetAttributionsToReport(base::Time::Now()), + ElementsAre(AllOf( + Property(&EventAttributionReport::failed_send_attempts, 1), + Property(&EventAttributionReport::report_time, new_report_time)))); } TEST_F(AttributionStorageTest, StoreSource_ReturnsDeactivatedSources) { - auto source1 = SourceBuilder(base::Time::Now()).SetSourceEventId(7).Build(); + auto source1 = SourceBuilder().SetSourceEventId(7).Build(); EXPECT_THAT(storage()->StoreSource(source1), IsEmpty()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(1)); @@ -1566,7 +1532,7 @@ MaybeCreateAndStoreReport(TriggerBuilder().SetDedupKey(13).Build())); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1)); - auto source2 = SourceBuilder(base::Time::Now()).SetSourceEventId(9).Build(); + auto source2 = SourceBuilder().SetSourceEventId(9).Build(); source1.SetDedupKeys({13}); EXPECT_THAT(storage()->StoreSource(source2), @@ -1577,10 +1543,10 @@ } TEST_F(AttributionStorageTest, StoreSource_ReturnsDeactivatedSources_Limited) { - auto source1 = SourceBuilder(base::Time::Now()).SetSourceEventId(1).Build(); + auto source1 = SourceBuilder().SetSourceEventId(1).Build(); EXPECT_THAT(storage()->StoreSource(source1), IsEmpty()); - auto source2 = SourceBuilder(base::Time::Now()).SetSourceEventId(2).Build(); + auto source2 = SourceBuilder().SetSourceEventId(2).Build(); EXPECT_THAT(storage()->StoreSource(source1), IsEmpty()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(2)); @@ -1594,7 +1560,7 @@ EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(2)); // 2 sources are deactivated, but only 1 should be returned. - auto source3 = SourceBuilder(base::Time::Now()).SetSourceEventId(3).Build(); + auto source3 = SourceBuilder().SetSourceEventId(3).Build(); EXPECT_THAT( storage()->StoreSource(source3, /*deactivated_source_return_limit=*/1), ElementsAre(DeactivatedSource( @@ -1604,7 +1570,7 @@ TEST_F(AttributionStorageTest, MaybeCreateAndStoreReport_ReturnsDeactivatedSources) { - auto source1 = SourceBuilder(base::Time::Now()).SetSourceEventId(7).Build(); + auto source1 = SourceBuilder().SetSourceEventId(7).Build(); EXPECT_THAT(storage()->StoreSource(source1), IsEmpty()); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(1)); @@ -1629,8 +1595,9 @@ AllOf( Property(&CreateReportResult::status, CreateReportStatus::kPriorityTooLow), - Property(&CreateReportResult::dropped_report, - Optional(Property(&AttributionReport::source, source1))), + Property( + &CreateReportResult::dropped_report, + Optional(Property(&EventAttributionReport::source, source1))), Property(&CreateReportResult::GetDeactivatedSource, DeactivatedSource( source1, @@ -1638,13 +1605,13 @@ } TEST_F(AttributionStorageTest, ReportID_RoundTrips) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); - std::vector<AttributionReport> actual_reports = + std::vector<EventAttributionReport> actual_reports = storage()->GetAttributionsToReport(base::Time::Now()); EXPECT_EQ(1u, actual_reports.size()); EXPECT_EQ(DefaultExternalReportID(), actual_reports[0].external_report_id()); @@ -1655,7 +1622,7 @@ storage()->AdjustOfflineReportTimes(base::TimeDelta(), base::TimeDelta()), absl::nullopt); - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -1663,7 +1630,7 @@ base::Time::Now() + base::Milliseconds(kReportTime); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, original_report_time))); task_environment_.FastForwardBy(base::Milliseconds(kReportTime)); @@ -1675,7 +1642,7 @@ // The report time should not be changed as it is equal to now, not strictly // less than it. EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, original_report_time))); task_environment_.FastForwardBy(base::Milliseconds(1)); @@ -1687,13 +1654,13 @@ new_report_time); // The report time should be changed as it is strictly less than now. - EXPECT_THAT( - storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::report_time, new_report_time))); + EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), + ElementsAre(Property(&EventAttributionReport::report_time, + new_report_time))); } TEST_F(AttributionStorageTest, AdjustOfflineReportTimes_Range) { - storage()->StoreSource(SourceBuilder(base::Time::Now()).Build()); + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport(DefaultTrigger())); @@ -1701,7 +1668,7 @@ base::Time::Now() + base::Milliseconds(kReportTime); EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, original_report_time))); task_environment_.FastForwardBy(base::Milliseconds(kReportTime + 1)); @@ -1711,7 +1678,7 @@ EXPECT_THAT( storage()->GetAttributionsToReport(base::Time::Max()), - ElementsAre(Property(&AttributionReport::report_time, + ElementsAre(Property(&EventAttributionReport::report_time, AllOf(Ge(base::Time::Now() + base::Hours(1)), Le(base::Time::Now() + base::Hours(3)))))); } @@ -1722,8 +1689,7 @@ EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), absl::nullopt); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetReportingOrigin(origin_a).Build()); + storage()->StoreSource(SourceBuilder().SetReportingOrigin(origin_a).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport( TriggerBuilder().SetReportingOrigin(origin_a).Build())); @@ -1735,8 +1701,7 @@ EXPECT_EQ(storage()->GetNextReportTime(report_time_a), absl::nullopt); task_environment_.FastForwardBy(base::Milliseconds(1)); - storage()->StoreSource( - SourceBuilder(base::Time::Now()).SetReportingOrigin(origin_b).Build()); + storage()->StoreSource(SourceBuilder().SetReportingOrigin(origin_b).Build()); EXPECT_EQ(CreateReportStatus::kSuccess, MaybeCreateAndStoreReport( TriggerBuilder().SetReportingOrigin(origin_b).Build()));
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index 930a748..747684c 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -145,8 +145,9 @@ observer.OnSourceDeactivated(source); } -void MockAttributionManager::NotifyReportSent(const AttributionReport& report, - const SendResult& info) { +void MockAttributionManager::NotifyReportSent( + const EventAttributionReport& report, + const SendResult& info) { for (Observer& observer : observers_) observer.OnReportSent(report, info); } @@ -314,15 +315,15 @@ } ReportBuilder& ReportBuilder::SetReportId( - absl::optional<AttributionReport::Id> id) { + absl::optional<EventAttributionReport::Id> id) { report_id_ = id; return *this; } -AttributionReport ReportBuilder::Build() const { - return AttributionReport(source_, trigger_data_, conversion_time_, - report_time_, priority_, external_report_id_, - report_id_); +EventAttributionReport ReportBuilder::Build() const { + return EventAttributionReport(source_, trigger_data_, conversion_time_, + report_time_, priority_, external_report_id_, + report_id_); } // Custom comparator for `StorableSource` that does not take impression IDs @@ -342,8 +343,9 @@ // Custom comparator for comparing two vectors of conversion reports. Does not // compare impression and conversion IDs as they are set by the underlying // sqlite db and should not be tested. -bool operator==(const AttributionReport& a, const AttributionReport& b) { - const auto tie = [](const AttributionReport& conversion) { +bool operator==(const EventAttributionReport& a, + const EventAttributionReport& b) { + const auto tie = [](const EventAttributionReport& conversion) { return std::make_tuple(conversion.source(), conversion.trigger_data(), conversion.conversion_time(), conversion.report_time(), conversion.priority(), @@ -496,7 +498,8 @@ return out << "]}"; } -std::ostream& operator<<(std::ostream& out, const AttributionReport& report) { +std::ostream& operator<<(std::ostream& out, + const EventAttributionReport& report) { return out << "{source=" << report.source() << ",trigger_data=" << report.trigger_data() << ",conversion_time=" << report.conversion_time() @@ -539,16 +542,16 @@ << ",reason=" << deactivated_source.reason << "}"; } -std::vector<AttributionReport> GetAttributionsToReportForTesting( +std::vector<EventAttributionReport> GetAttributionsToReportForTesting( AttributionManagerImpl* manager, base::Time max_report_time) { base::RunLoop run_loop; - std::vector<AttributionReport> attribution_reports; + std::vector<EventAttributionReport> attribution_reports; manager->attribution_storage_ .AsyncCall(&AttributionStorage::GetAttributionsToReport) .WithArgs(max_report_time, /*limit=*/-1) .Then(base::BindOnce(base::BindLambdaForTesting( - [&](std::vector<AttributionReport> reports) { + [&](std::vector<EventAttributionReport> reports) { attribution_reports = std::move(reports); run_loop.Quit(); })));
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index b927d70..1352101 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -21,8 +21,8 @@ #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/attribution_manager_impl.h" #include "content/browser/attribution_reporting/attribution_policy.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/rate_limit_table.h" #include "content/browser/attribution_reporting/send_result.h" #include "content/browser/attribution_reporting/storable_source.h" @@ -175,7 +175,7 @@ MOCK_METHOD( void, GetPendingReportsForWebUI, - (base::OnceCallback<void(std::vector<AttributionReport>)> callback), + (base::OnceCallback<void(std::vector<EventAttributionReport>)> callback), (override)); MOCK_METHOD(void, SendReportsForWebUI, (base::OnceClosure done), (override)); @@ -196,7 +196,7 @@ void NotifyReportsChanged(); void NotifySourceDeactivated( const AttributionStorage::DeactivatedSource& source); - void NotifyReportSent(const AttributionReport& report, + void NotifyReportSent(const EventAttributionReport& report, const SendResult& info); void NotifyReportDropped( const AttributionStorage::CreateReportResult& result); @@ -211,7 +211,7 @@ // builder pattern. class SourceBuilder { public: - explicit SourceBuilder(base::Time time); + explicit SourceBuilder(base::Time time = base::Time::Now()); ~SourceBuilder(); SourceBuilder& SetExpiry(base::TimeDelta delta) WARN_UNUSED_RESULT; @@ -295,7 +295,7 @@ absl::optional<int64_t> dedup_key_ = absl::nullopt; }; -// Helper class to construct an `AttributionReport` for tests using default +// Helper class to construct an `EventAttributionReport` for tests using default // data. class ReportBuilder { public: @@ -313,10 +313,10 @@ ReportBuilder& SetExternalReportId(base::GUID external_report_id) WARN_UNUSED_RESULT; - ReportBuilder& SetReportId(absl::optional<AttributionReport::Id> id) + ReportBuilder& SetReportId(absl::optional<EventAttributionReport::Id> id) WARN_UNUSED_RESULT; - AttributionReport Build() const WARN_UNUSED_RESULT; + EventAttributionReport Build() const WARN_UNUSED_RESULT; private: StorableSource source_; @@ -325,12 +325,13 @@ base::Time report_time_; int64_t priority_ = 0; base::GUID external_report_id_; - absl::optional<AttributionReport::Id> report_id_; + absl::optional<EventAttributionReport::Id> report_id_; }; bool operator==(const StorableSource& a, const StorableSource& b); -bool operator==(const AttributionReport& a, const AttributionReport& b); +bool operator==(const EventAttributionReport& a, + const EventAttributionReport& b); bool operator==(const SendResult& a, const SendResult& b); @@ -353,7 +354,8 @@ std::ostream& operator<<(std::ostream& out, const StorableSource& impression); -std::ostream& operator<<(std::ostream& out, const AttributionReport& report); +std::ostream& operator<<(std::ostream& out, + const EventAttributionReport& report); std::ostream& operator<<(std::ostream& out, SendResult::Status status); @@ -366,7 +368,7 @@ std::ostream& out, const AttributionStorage::DeactivatedSource& deactivated_source); -std::vector<AttributionReport> GetAttributionsToReportForTesting( +std::vector<EventAttributionReport> GetAttributionsToReportForTesting( AttributionManagerImpl* manager, base::Time max_report_time) WARN_UNUSED_RESULT;
diff --git a/content/browser/attribution_reporting/attribution_report.cc b/content/browser/attribution_reporting/event_attribution_report.cc similarity index 64% rename from content/browser/attribution_reporting/attribution_report.cc rename to content/browser/attribution_reporting/event_attribution_report.cc index b0830796..49ec269 100644 --- a/content/browser/attribution_reporting/attribution_report.cc +++ b/content/browser/attribution_reporting/event_attribution_report.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/attribution_reporting/attribution_report.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include <utility> @@ -16,13 +16,13 @@ namespace content { -AttributionReport::AttributionReport(StorableSource source, - uint64_t trigger_data, - base::Time conversion_time, - base::Time report_time, - int64_t priority, - base::GUID external_report_id, - absl::optional<Id> report_id) +EventAttributionReport::EventAttributionReport(StorableSource source, + uint64_t trigger_data, + base::Time conversion_time, + base::Time report_time, + int64_t priority, + base::GUID external_report_id, + absl::optional<Id> report_id) : source_(std::move(source)), trigger_data_(trigger_data), conversion_time_(conversion_time), @@ -33,19 +33,21 @@ DCHECK(external_report_id_.is_valid()); } -AttributionReport::AttributionReport(const AttributionReport& other) = default; +EventAttributionReport::EventAttributionReport( + const EventAttributionReport& other) = default; -AttributionReport& AttributionReport::operator=( - const AttributionReport& other) = default; +EventAttributionReport& EventAttributionReport::operator=( + const EventAttributionReport& other) = default; -AttributionReport::AttributionReport(AttributionReport&& other) = default; - -AttributionReport& AttributionReport::operator=(AttributionReport&& other) = +EventAttributionReport::EventAttributionReport(EventAttributionReport&& other) = default; -AttributionReport::~AttributionReport() = default; +EventAttributionReport& EventAttributionReport::operator=( + EventAttributionReport&& other) = default; -GURL AttributionReport::ReportURL() const { +EventAttributionReport::~EventAttributionReport() = default; + +GURL EventAttributionReport::ReportURL() const { url::Replacements<char> replacements; static constexpr char kEndpointPath[] = "/.well-known/attribution-reporting/report-attribution"; @@ -53,7 +55,7 @@ return source_.reporting_origin().GetURL().ReplaceComponents(replacements); } -std::string AttributionReport::ReportBody(bool pretty_print) const { +std::string EventAttributionReport::ReportBody(bool pretty_print) const { base::Value dict(base::Value::Type::DICTIONARY); dict.SetStringKey("attribution_destination", @@ -88,16 +90,17 @@ return output_json; } -void AttributionReport::set_report_time(base::Time report_time) { +void EventAttributionReport::set_report_time(base::Time report_time) { report_time_ = report_time; } -void AttributionReport::set_failed_send_attempts(int failed_send_attempts) { +void EventAttributionReport::set_failed_send_attempts( + int failed_send_attempts) { DCHECK_GE(failed_send_attempts, 0); failed_send_attempts_ = failed_send_attempts; } -void AttributionReport::SetExternalReportIdForTesting( +void EventAttributionReport::SetExternalReportIdForTesting( base::GUID external_report_id) { DCHECK(external_report_id.is_valid()); external_report_id_ = std::move(external_report_id);
diff --git a/content/browser/attribution_reporting/attribution_report.h b/content/browser/attribution_reporting/event_attribution_report.h similarity index 73% rename from content/browser/attribution_reporting/attribution_report.h rename to content/browser/attribution_reporting/event_attribution_report.h index 19a6431..4e86eb5 100644 --- a/content/browser/attribution_reporting/attribution_report.h +++ b/content/browser/attribution_reporting/event_attribution_report.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_REPORT_H_ -#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_REPORT_H_ +#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_EVENT_ATTRIBUTION_REPORT_H_ +#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_EVENT_ATTRIBUTION_REPORT_H_ #include <stdint.h> @@ -24,23 +24,23 @@ // Class that contains all the data needed to serialize and send a conversion // report. This represents the report for a conversion event and its associated // source. -class CONTENT_EXPORT AttributionReport { +class CONTENT_EXPORT EventAttributionReport { public: - using Id = base::StrongAlias<AttributionReport, int64_t>; + using Id = base::StrongAlias<EventAttributionReport, int64_t>; // The conversion_id may not be set for a conversion report. - AttributionReport(StorableSource source, - uint64_t trigger_data, - base::Time conversion_time, - base::Time report_time, - int64_t priority, - base::GUID external_report_id, - absl::optional<Id> report_id); - AttributionReport(const AttributionReport& other); - AttributionReport& operator=(const AttributionReport& other); - AttributionReport(AttributionReport&& other); - AttributionReport& operator=(AttributionReport&& other); - ~AttributionReport(); + EventAttributionReport(StorableSource source, + uint64_t trigger_data, + base::Time conversion_time, + base::Time report_time, + int64_t priority, + base::GUID external_report_id, + absl::optional<Id> report_id); + EventAttributionReport(const EventAttributionReport& other); + EventAttributionReport& operator=(const EventAttributionReport& other); + EventAttributionReport(EventAttributionReport&& other); + EventAttributionReport& operator=(EventAttributionReport&& other); + ~EventAttributionReport(); // Returns the URL to which the report will be sent. GURL ReportURL() const WARN_UNUSED_RESULT; @@ -104,4 +104,4 @@ } // namespace content -#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_REPORT_H_ +#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_EVENT_ATTRIBUTION_REPORT_H_
diff --git a/content/browser/attribution_reporting/rate_limit_table.cc b/content/browser/attribution_reporting/rate_limit_table.cc index f5f8bab..4aa47108 100644 --- a/content/browser/attribution_reporting/rate_limit_table.cc +++ b/content/browser/attribution_reporting/rate_limit_table.cc
@@ -6,7 +6,7 @@ #include "base/check.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_report.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/sql_utils.h" #include "net/base/schemeful_site.h" #include "sql/database.h" @@ -114,7 +114,7 @@ } bool RateLimitTable::AddRateLimit(sql::Database* db, - const AttributionReport& report) { + const EventAttributionReport& report) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(report.source().impression_id().has_value()); @@ -177,7 +177,7 @@ AttributionAllowedStatus RateLimitTable::AttributionAllowed( sql::Database* db, - const AttributionReport& report, + const EventAttributionReport& report, base::Time now) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/browser/attribution_reporting/rate_limit_table.h b/content/browser/attribution_reporting/rate_limit_table.h index 5d8476d..ac315cb 100644 --- a/content/browser/attribution_reporting/rate_limit_table.h +++ b/content/browser/attribution_reporting/rate_limit_table.h
@@ -28,7 +28,7 @@ namespace content { -class AttributionReport; +class EventAttributionReport; struct AggregateHistogramContribution { std::string bucket; @@ -60,14 +60,14 @@ // Adds a rate limit to the table for an event-level report. // Returns false on failure. bool AddRateLimit(sql::Database* db, - const AttributionReport& report) WARN_UNUSED_RESULT; + const EventAttributionReport& report) WARN_UNUSED_RESULT; // Checks if the given attribution is allowed according to the data in the // table and policy as specified by the delegate. - AttributionAllowedStatus AttributionAllowed(sql::Database* db, - const AttributionReport& report, - base::Time now) - WARN_UNUSED_RESULT; + AttributionAllowedStatus AttributionAllowed( + sql::Database* db, + const EventAttributionReport& report, + base::Time now) WARN_UNUSED_RESULT; // Attempts to add a set of histogram contributions to the rate limit. Returns // `kAllowed` if the contributions were added, `kNotAllowed` if the reports
diff --git a/content/browser/attribution_reporting/rate_limit_table_unittest.cc b/content/browser/attribution_reporting/rate_limit_table_unittest.cc index 08fb5428..7611996 100644 --- a/content/browser/attribution_reporting/rate_limit_table_unittest.cc +++ b/content/browser/attribution_reporting/rate_limit_table_unittest.cc
@@ -11,8 +11,8 @@ #include "base/files/scoped_temp_dir.h" #include "base/test/task_environment.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" +#include "content/browser/attribution_reporting/event_attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" #include "sql/database.h" #include "sql/statement.h" @@ -38,13 +38,13 @@ table_ = std::make_unique<RateLimitTable>(delegate_.get()); } - AttributionReport NewConversionReport( + EventAttributionReport NewConversionReport( url::Origin impression_origin, url::Origin conversion_origin, StorableSource::Id impression_id = StorableSource::Id(0), StorableSource::SourceType source_type = StorableSource::SourceType::kNavigation) { - return ReportBuilder(SourceBuilder(base::Time::Now()) + return ReportBuilder(SourceBuilder() .SetImpressionOrigin(std::move(impression_origin)) .SetConversionOrigin(std::move(conversion_origin)) .SetImpressionId(impression_id) @@ -466,7 +466,7 @@ EXPECT_EQ(AttributionAllowedStatus::kAllowed, table()->AddAggregateHistogramContributionsForTesting( &db, - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(example_a) .SetConversionOrigin(example_b) .SetImpressionId(StorableSource::Id(1)) @@ -586,7 +586,7 @@ }); const auto impression = - SourceBuilder(base::Time::Now()) + SourceBuilder() .SetImpressionOrigin(url::Origin::Create(GURL("https://a.example/"))) .SetConversionOrigin(url::Origin::Create(GURL("https://b.example/"))) .SetImpressionId(StorableSource::Id(1))
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.cc b/content/browser/background_fetch/background_fetch_delegate_proxy.cc index 3e42823..e50cda8 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.cc +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -18,6 +18,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/download_manager.h" +#include "content/public/browser/download_manager_delegate.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/blob/serialized_blob.mojom.h" @@ -60,28 +61,32 @@ GetPermissionForOriginCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Permissions need to go through the DownloadRequestLimiter for top level + // frames. (This may be missing in unit tests.) + if (rfh && !rfh->GetParent() && + rfh->GetBrowserContext()->GetDownloadManager()->GetDelegate()) { + rfh->GetBrowserContext() + ->GetDownloadManager() + ->GetDelegate() + ->CheckDownloadAllowed( + base::BindRepeating(&WebContents::FromRenderFrameHost, rfh), + origin.GetURL(), "GET", absl::nullopt, + false /* from_download_cross_origin_redirect */, + true /* content_initiated */, + base::BindOnce(&BackgroundFetchDelegateProxy:: + DidGetPermissionFromDownloadRequestLimiter, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))); + return; + } + BackgroundFetchPermission result = BackgroundFetchPermission::BLOCKED; if (auto* controller = GetPermissionController()) { - // Use GetPermissionStatusForFrame() only if the fetch is started from - // a top-level document. Permissions need to go through the - // DownloadRequestLimiter in that case. - // TODO(falken): Consider using GetPermissionStatusForFrame() for any `rfh`. - // The code may currently not be doing that just for historical reasons. - // Previously a WebContents was plumbed here instead of a - // RenderFrameHostImpl, and it was only set for the top-level document, so - // there was no way to get the RenderFrameHostImpl for subframes. - if (rfh && rfh->GetParent()) - rfh = nullptr; - blink::mojom::PermissionStatus permission_status = - rfh ? controller->GetPermissionStatusForFrame( - PermissionType::BACKGROUND_FETCH, rfh, - /*requesting_origin=*/origin.GetURL()) - : controller->GetPermissionStatus( - PermissionType::BACKGROUND_FETCH, - /*requesting_origin=*/origin.GetURL(), - /*embedding_origin=*/origin.GetURL()); + controller->GetPermissionStatus(PermissionType::BACKGROUND_FETCH, + /*requesting_origin=*/origin.GetURL(), + /*embedding_origin=*/origin.GetURL()); switch (permission_status) { case blink::mojom::PermissionStatus::GRANTED: result = BackgroundFetchPermission::ALLOWED; @@ -332,4 +337,13 @@ return PermissionControllerImpl::FromBrowserContext(browser_context); } +void BackgroundFetchDelegateProxy::DidGetPermissionFromDownloadRequestLimiter( + GetPermissionForOriginCallback callback, + bool has_permission) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + std::move(callback).Run(has_permission + ? content::BackgroundFetchPermission::ALLOWED + : content::BackgroundFetchPermission::BLOCKED); +} + } // namespace content
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.h b/content/browser/background_fetch/background_fetch_delegate_proxy.h index 75101ab..ad821c2e 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.h +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -162,6 +162,10 @@ const std::string& download_guid, BackgroundFetchDelegate::GetUploadDataCallback callback) override; + void DidGetPermissionFromDownloadRequestLimiter( + GetPermissionForOriginCallback callback, + bool has_permission); + BrowserContext* GetBrowserContext(); BackgroundFetchDelegate* GetDelegate();
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 7728866..fe037f2 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -93,6 +93,7 @@ #include "storage/browser/quota/quota_manager.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/storage_key/storage_key.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" @@ -1196,6 +1197,8 @@ &RenderProcessHostImpl::BindIndexedDB, host)); map->Add<blink::mojom::NativeIOHost>(BindWorkerReceiverForStorageKey( &RenderProcessHostImpl::BindNativeIOHost, host)); + map->Add<blink::mojom::LockManager>(BindWorkerReceiverForStorageKey( + &RenderProcessHostImpl::CreateLockManager, host)); } void PopulateBinderMapWithContext( @@ -1210,8 +1213,6 @@ &RenderProcessHostImpl::BindBucketManagerHost, host)); // RenderProcessHost binders taking a frame id and an origin - map->Add<blink::mojom::LockManager>(BindWorkerReceiverForOriginAndFrameId( - &RenderProcessHostImpl::CreateLockManager, host)); map->Add<blink::mojom::NotificationService>( BindWorkerReceiverForOriginAndFrameId( &RenderProcessHostImpl::CreateNotificationService, host)); @@ -1289,6 +1290,8 @@ &RenderProcessHostImpl::BindNativeIOHost, host)); map->Add<blink::mojom::WebSocketConnector>(BindWorkerReceiverForStorageKey( &RenderProcessHostImpl::CreateWebSocketConnector, host)); + map->Add<blink::mojom::LockManager>(BindWorkerReceiverForStorageKey( + &RenderProcessHostImpl::CreateLockManager, host)); } void PopulateBinderMapWithContext( @@ -1303,8 +1306,6 @@ &RenderProcessHostImpl::BindBucketManagerHost, host)); // RenderProcessHost binders taking a frame id and an origin - map->Add<blink::mojom::LockManager>(BindWorkerReceiverForOriginAndFrameId( - &RenderProcessHostImpl::CreateLockManager, host)); map->Add<blink::mojom::NotificationService>( BindWorkerReceiverForOriginAndFrameId( &RenderProcessHostImpl::CreateNotificationService, host)); @@ -1416,11 +1417,10 @@ map->Add<blink::mojom::WebSocketConnector>( BindServiceWorkerReceiverForStorageKey( &RenderProcessHostImpl::CreateWebSocketConnector, host)); + map->Add<blink::mojom::LockManager>(BindServiceWorkerReceiverForStorageKey( + &RenderProcessHostImpl::CreateLockManager, host)); // RenderProcessHost binders taking a frame id and an origin - map->Add<blink::mojom::LockManager>( - BindServiceWorkerReceiverForOriginAndFrameId( - &RenderProcessHostImpl::CreateLockManager, host)); map->Add<blink::mojom::NotificationService>( BindServiceWorkerReceiverForOriginAndFrameId( &RenderProcessHostImpl::CreateNotificationService, host));
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl.cc b/content/browser/browsing_data/browsing_data_filter_builder_impl.cc index 9f32553..340852a1 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl.cc +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl.cc
@@ -59,7 +59,9 @@ bool MatchesURL(const std::set<url::Origin>& origins, const std::set<std::string>& registerable_domains, BrowsingDataFilterBuilder::Mode mode, + bool is_cross_site_clear_site_data, const GURL& url) { + DCHECK(!is_cross_site_clear_site_data); return MatchesOrigin(origins, registerable_domains, mode, url::Origin::Create(url)); } @@ -81,6 +83,14 @@ (domains_and_ips.find(domain_or_ip) != domains_and_ips.end())); } +template <typename T> +base::RepeatingCallback<bool(const T&)> NotReachedFilter() { + return base::BindRepeating([](const T&) { + NOTREACHED(); + return false; + }); +} + } // namespace // static @@ -123,6 +133,32 @@ domains_.insert(domain); } +void BrowsingDataFilterBuilderImpl::SetCookiePartitionKeyCollection( + const net::CookiePartitionKeyCollection& cookie_partition_key_collection) { + // This method should only be called when the current + // `cookie_partition_key_collection_` is the default value. + DCHECK(cookie_partition_key_collection_.ContainsAllKeys()); + cookie_partition_key_collection_ = cookie_partition_key_collection; +} + +bool BrowsingDataFilterBuilderImpl::IsCrossSiteClearSiteData() const { + if (cookie_partition_key_collection_.IsEmpty() || + cookie_partition_key_collection_.ContainsAllKeys()) { + return false; + } + for (const auto& domain : domains_) { + auto secure_site = + net::SchemefulSite(url::Origin::Create(GURL("https://" + domain))); + auto insecure_site = + net::SchemefulSite(url::Origin::Create(GURL("http://" + domain))); + for (const auto& key : cookie_partition_key_collection_.PartitionKeys()) { + if (key.site() == secure_site || key.site() == insecure_site) + return false; + } + } + return true; +} + bool BrowsingDataFilterBuilderImpl::MatchesAllOriginsAndDomains() { return mode_ == Mode::kPreserve && origins_.empty() && domains_.empty(); } @@ -131,11 +167,14 @@ BrowsingDataFilterBuilderImpl::BuildUrlFilter() { if (MatchesAllOriginsAndDomains()) return base::BindRepeating([](const GURL&) { return true; }); - return base::BindRepeating(&MatchesURL, origins_, domains_, mode_); + return base::BindRepeating(&MatchesURL, origins_, domains_, mode_, + IsCrossSiteClearSiteData()); } base::RepeatingCallback<bool(const url::Origin&)> BrowsingDataFilterBuilderImpl::BuildOriginFilter() { + if (!cookie_partition_key_collection_.ContainsAllKeys()) + return NotReachedFilter<url::Origin>(); if (MatchesAllOriginsAndDomains()) return base::BindRepeating([](const url::Origin&) { return true; }); return base::BindRepeating(&MatchesOrigin, origins_, domains_, mode_); @@ -151,6 +190,10 @@ if (MatchesAllOriginsAndDomains()) return nullptr; + + if (!cookie_partition_key_collection_.ContainsAllKeys()) + return nullptr; + network::mojom::ClearDataFilterPtr filter = network::mojom::ClearDataFilter::New(); filter->type = (mode_ == Mode::kDelete) @@ -170,6 +213,9 @@ "different scoping, such as RegistrableDomainFilterBuilder."; auto deletion_filter = network::mojom::CookieDeletionFilter::New(); + deletion_filter->cookie_partition_key_collection = + cookie_partition_key_collection_; + switch (mode_) { case Mode::kDelete: deletion_filter->including_domains.emplace(domains_.begin(), @@ -185,6 +231,8 @@ base::RepeatingCallback<bool(const std::string& site)> BrowsingDataFilterBuilderImpl::BuildPluginFilter() { + if (!cookie_partition_key_collection_.ContainsAllKeys()) + return NotReachedFilter<std::string>(); DCHECK(origins_.empty()) << "Origin-based deletion is not suitable for plugins. Please use " "different scoping, such as RegistrableDomainFilterBuilder.";
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl.h b/content/browser/browsing_data/browsing_data_filter_builder_impl.h index 2d6da15..e22ea00 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl.h +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl.h
@@ -27,6 +27,10 @@ // BrowsingDataFilterBuilder implementation: void AddOrigin(const url::Origin& origin) override; void AddRegisterableDomain(const std::string& registrable_domain) override; + void SetCookiePartitionKeyCollection( + const net::CookiePartitionKeyCollection& cookie_partition_key_collection) + override; + bool IsCrossSiteClearSiteData() const override; bool MatchesAllOriginsAndDomains() override; base::RepeatingCallback<bool(const GURL&)> BuildUrlFilter() override; base::RepeatingCallback<bool(const url::Origin&)> BuildOriginFilter() @@ -44,6 +48,8 @@ std::set<url::Origin> origins_; std::set<std::string> domains_; + net::CookiePartitionKeyCollection cookie_partition_key_collection_ = + net::CookiePartitionKeyCollection::ContainsAll(); }; } // content
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc index ad29c56..9f555e6 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
@@ -335,6 +335,125 @@ RunTestCase(test_case, builder.BuildCookieDeletionFilter()); } +TEST(BrowsingDataFilterBuilderImplTest, PartitionedCookies) { + struct PartitionedCookiesTestCase { + net::CookiePartitionKeyCollection filter_cookie_partition_key_collection; + absl::optional<net::CookiePartitionKey> cookie_partition_key; + bool should_match; + } test_cases[] = { + // Unpartitioned cookies should remain unaffected by the filter's + // keychain. + {net::CookiePartitionKeyCollection(), absl::nullopt, true}, + {net::CookiePartitionKeyCollection::ContainsAll(), absl::nullopt, true}, + {net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://www.foo.com"))), + absl::nullopt, true}, + // Partitioned cookies should not match with an empty keychain. + {net::CookiePartitionKeyCollection(), + net::CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")), + false}, + // Partitioned cookies should match a keychain with their partition key. + {net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://www.foo.com"))), + net::CookiePartitionKey::FromURLForTesting( + GURL("https://subdomain.foo.com")), + true}, + // Partitioned cookies should match a keychain that contains all keys. + {net::CookiePartitionKeyCollection::ContainsAll(), + net::CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")), + true}, + // Partitioned cookies should not match a keychain with a different + // partition key. + {net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://www.foo.com"))), + net::CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")), + false}, + }; + + for (const auto& test_case : test_cases) { + BrowsingDataFilterBuilderImpl builder( + BrowsingDataFilterBuilderImpl::Mode::kDelete); + builder.AddRegisterableDomain("cookie.com"); + builder.SetCookiePartitionKeyCollection( + test_case.filter_cookie_partition_key_collection); + + CookieDeletionInfo delete_info = + network::DeletionFilterToInfo(builder.BuildCookieDeletionFilter()); + std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create( + GURL("https://www.cookie.com/"), + "__Host-A=B; Secure; SameSite=None; Path=/; Partitioned;", + base::Time::Now(), absl::nullopt, test_case.cookie_partition_key); + EXPECT_TRUE(cookie); + EXPECT_EQ( + test_case.should_match, + delete_info.Matches( + *cookie, net::CookieAccessParams{ + net::CookieAccessSemantics::NONLEGACY, false, + net::CookieSamePartyStatus::kNoSamePartyEnforcement})); + } +} + +TEST(BrowserDataFilterBuilderImplTest, IsCrossSiteClearSiteData) { + struct TestCase { + const std::string desc; + const net::CookiePartitionKeyCollection cookie_partition_key_collection; + bool expected; + } test_cases[] = { + {"Empty keychain", net::CookiePartitionKeyCollection(), false}, + {"Keychain contains all keys", + net::CookiePartitionKeyCollection::ContainsAll(), false}, + {"Contains secure cookie domain", + net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("http://cookie.com"))), + false}, + {"Contains insecure cookie domain", + net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://cookie.com"))), + false}, + {"Does not include cookie domain (secure)", + net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://notcookie.com"))), + true}, + {"Does not include cookie domain (insecure)", + net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("http://notcookie.com"))), + true}, + {"Multiple keys, contains cookie domain", + net::CookiePartitionKeyCollection({ + net::CookiePartitionKey::FromURLForTesting( + GURL("https://cookie.com")), + net::CookiePartitionKey::FromURLForTesting( + GURL("https://notcookie.com")), + }), + false}, + {"Multiple keys, does not contain cookie domain", + net::CookiePartitionKeyCollection({ + net::CookiePartitionKey::FromURLForTesting( + GURL("https://notcookie.com")), + net::CookiePartitionKey::FromURLForTesting( + GURL("https://alsonotcookie.com")), + }), + true}, + }; + + for (const auto& test_case : test_cases) { + SCOPED_TRACE(test_case.desc); + BrowsingDataFilterBuilderImpl builder( + BrowsingDataFilterBuilderImpl::Mode::kDelete); + builder.AddRegisterableDomain("cookie.com"); + builder.SetCookiePartitionKeyCollection( + test_case.cookie_partition_key_collection); + EXPECT_EQ(test_case.expected, builder.IsCrossSiteClearSiteData()); + } +} + TEST(BrowsingDataFilterBuilderImplTest, NetworkServiceFilterDeleteList) { BrowsingDataFilterBuilderImpl builder( BrowsingDataFilterBuilderImpl::Mode::kDelete);
diff --git a/content/browser/browsing_data/clear_site_data_handler.cc b/content/browser/browsing_data/clear_site_data_handler.cc index 9f3b6b0b..fd9738d 100644 --- a/content/browser/browsing_data/clear_site_data_handler.cc +++ b/content/browser/browsing_data/clear_site_data_handler.cc
@@ -108,9 +108,11 @@ const GURL& url, const std::string& header_value, int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback) { ClearSiteDataHandler handler(browser_context_getter, web_contents_getter, url, - header_value, load_flags, std::move(callback), + header_value, load_flags, cookie_partition_key, + std::move(callback), std::make_unique<ConsoleMessagesDelegate>()); handler.HandleHeaderAndOutputConsoleMessages(); } @@ -133,6 +135,7 @@ const GURL& url, const std::string& header_value, int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback, std::unique_ptr<ConsoleMessagesDelegate> delegate) : browser_context_getter_(browser_context_getter), @@ -140,6 +143,7 @@ url_(url), header_value_(header_value), load_flags_(load_flags), + cookie_partition_key_(cookie_partition_key), callback_(std::move(callback)), delegate_(std::move(delegate)) { DCHECK(browser_context_getter_); @@ -299,7 +303,7 @@ base::OnceClosure callback) { ClearSiteData(browser_context_getter_, origin, clear_cookies, clear_storage, clear_cache, true /*avoid_closing_connections*/, - std::move(callback)); + cookie_partition_key_, std::move(callback)); } // static
diff --git a/content/browser/browsing_data/clear_site_data_handler.h b/content/browser/browsing_data/clear_site_data_handler.h index 4a7bca6..9d258960 100644 --- a/content/browser/browsing_data/clear_site_data_handler.h +++ b/content/browser/browsing_data/clear_site_data_handler.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/time/time.h" #include "content/common/content_export.h" +#include "net/cookies/cookie_partition_key.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -79,6 +80,7 @@ const GURL& url, const std::string& header_value, int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback); // Exposes ParseHeader() publicly for testing. @@ -96,6 +98,7 @@ const GURL& url, const std::string& header_value, int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback, std::unique_ptr<ConsoleMessagesDelegate> delegate); virtual ~ClearSiteDataHandler(); @@ -143,6 +146,11 @@ const GURL& GetURLForTesting(); + const absl::optional<net::CookiePartitionKey> CookiePartitionKeyForTesting() + const { + return cookie_partition_key_; + } + private: // Required to clear the data. base::RepeatingCallback<BrowserContext*()> browser_context_getter_; @@ -157,6 +165,10 @@ // Load flags of the current request, used to check cookie policies. int load_flags_; + // The cookie partition key for which we need to clear partitioned cookies + // when we receive the Clear-Site-Data header. + absl::optional<net::CookiePartitionKey> cookie_partition_key_; + // Used to notify that the clearing has completed. Callers could resuming // loading after this point. base::OnceClosure callback_;
diff --git a/content/browser/browsing_data/clear_site_data_handler_unittest.cc b/content/browser/browsing_data/clear_site_data_handler_unittest.cc index f522930..7e2e3b4 100644 --- a/content/browser/browsing_data/clear_site_data_handler_unittest.cc +++ b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
@@ -46,18 +46,21 @@ // functionality. class TestHandler : public ClearSiteDataHandler { public: - TestHandler(base::RepeatingCallback<BrowserContext*()> browser_context_getter, - base::RepeatingCallback<WebContents*()> web_contents_getter, - const GURL& url, - const std::string& header_value, - int load_flags, - base::OnceClosure callback, - std::unique_ptr<ConsoleMessagesDelegate> delegate) + TestHandler( + base::RepeatingCallback<BrowserContext*()> browser_context_getter, + base::RepeatingCallback<WebContents*()> web_contents_getter, + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + base::OnceClosure callback, + std::unique_ptr<ConsoleMessagesDelegate> delegate) : ClearSiteDataHandler(browser_context_getter, web_contents_getter, url, header_value, load_flags, + cookie_partition_key, std::move(callback), std::move(delegate)) {} ~TestHandler() override = default; @@ -66,11 +69,14 @@ // test cases. bool DoHandleHeader() { return HandleHeaderAndOutputConsoleMessages(); } - MOCK_METHOD4(ClearSiteData, + MOCK_METHOD6(ClearSiteData, void(const url::Origin& origin, bool clear_cookies, bool clear_storage, - bool clear_cache)); + bool clear_cache, + bool avoid_closing_connections, + const absl::optional<net::CookiePartitionKey>& + cookie_partition_key)); protected: void ExecuteClearingTask(const url::Origin& origin, @@ -78,7 +84,8 @@ bool clear_storage, bool clear_cache, base::OnceClosure callback) override { - ClearSiteData(origin, clear_cookies, clear_storage, clear_cache); + ClearSiteData(origin, clear_cookies, clear_storage, clear_cache, false, + CookiePartitionKeyForTesting()); // NOTE: ResourceThrottle expects Resume() to be called asynchronously. // For the purposes of this test, synchronous call works correctly, and @@ -227,15 +234,16 @@ net::TestURLRequestContext context; std::unique_ptr<net::URLRequest> request(context.CreateRequest( url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS)); - TestHandler handler(base::BindRepeating(&FakeBrowserContextGetter), - base::BindRepeating(&FakeWebContentsGetter), - request->url(), test_case.header, - request->load_flags(), base::DoNothing(), - std::make_unique<ConsoleMessagesDelegate>()); + TestHandler handler( + base::BindRepeating(&FakeBrowserContextGetter), + base::BindRepeating(&FakeWebContentsGetter), request->url(), + test_case.header, request->load_flags(), + /*cookie_partition_key=*/absl::nullopt, base::DoNothing(), + std::make_unique<ConsoleMessagesDelegate>()); EXPECT_CALL(handler, ClearSiteData(url::Origin::Create(url), test_case.cookies, - test_case.storage, test_case.cache)); + test_case.storage, test_case.cache, _, _)); bool defer = handler.DoHandleHeader(); EXPECT_TRUE(defer); @@ -300,10 +308,11 @@ TestHandler handler( base::BindRepeating(&FakeBrowserContextGetter), base::BindRepeating(&FakeWebContentsGetter), request->url(), - kClearCookiesHeader, request->load_flags(), base::DoNothing(), + kClearCookiesHeader, request->load_flags(), + /*cookie_partition_key*/ absl::nullopt, base::DoNothing(), std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer)); - EXPECT_CALL(handler, ClearSiteData(_, _, _, _)); + EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _)); bool defer = handler.DoHandleHeader(); EXPECT_TRUE(defer); EXPECT_EQ(1u, message_buffer.size()); @@ -327,10 +336,11 @@ TestHandler handler( base::BindRepeating(&FakeBrowserContextGetter), base::BindRepeating(&FakeWebContentsGetter), request->url(), - kClearCookiesHeader, request->load_flags(), base::DoNothing(), + kClearCookiesHeader, request->load_flags(), + /*cookie_partition_key=*/absl::nullopt, base::DoNothing(), std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer)); - EXPECT_CALL(handler, ClearSiteData(_, _, _, _)).Times(0); + EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _)).Times(0); bool defer = handler.DoHandleHeader(); EXPECT_FALSE(defer); EXPECT_EQ(1u, message_buffer.size()); @@ -376,10 +386,11 @@ TestHandler handler( base::BindRepeating(&FakeBrowserContextGetter), base::BindRepeating(&FakeWebContentsGetter), request->url(), - kClearCookiesHeader, request->load_flags(), base::DoNothing(), + kClearCookiesHeader, request->load_flags(), + /*cookie_partition_key=*/absl::nullopt, base::DoNothing(), std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer)); - EXPECT_CALL(handler, ClearSiteData(_, _, _, _)) + EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _)) .Times(test_case.expect_success ? 1 : 0); bool defer = handler.DoHandleHeader(); @@ -470,7 +481,8 @@ TestHandler handler( base::BindRepeating(&FakeBrowserContextGetter), base::BindRepeating(&FakeWebContentsGetter), GURL(kTestCases[i].url), - kTestCases[i].header, request->load_flags(), base::DoNothing(), + kTestCases[i].header, request->load_flags(), + /*cookie_partition_key=*/absl::nullopt, base::DoNothing(), std::make_unique<StringConsoleMessagesDelegate>(&output_buffer)); handler.DoHandleHeader(); @@ -495,4 +507,27 @@ } } +TEST_F(ClearSiteDataHandlerTest, CookiePartitionKey) { + absl::optional<net::CookiePartitionKey> cookie_partition_keys[] = { + absl::nullopt, + net::CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")), + }; + const GURL kTestURL("https://www.bar.com"); + + for (const auto& cookie_partition_key : cookie_partition_keys) { + net::TestURLRequestContext context; + std::unique_ptr<net::URLRequest> request( + context.CreateRequest(kTestURL, net::DEFAULT_PRIORITY, nullptr, + TRAFFIC_ANNOTATION_FOR_TESTS)); + std::string output_buffer; + TestHandler handler( + base::BindRepeating(&FakeBrowserContextGetter), + base::BindRepeating(&FakeWebContentsGetter), kTestURL, "\"cookies\"", + request->load_flags(), cookie_partition_key, base::DoNothing(), + std::make_unique<StringConsoleMessagesDelegate>(&output_buffer)); + EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, cookie_partition_key)); + EXPECT_TRUE(handler.DoHandleHeader()); + } +} + } // namespace content
diff --git a/content/browser/browsing_data/clear_site_data_utils.cc b/content/browser/browsing_data/clear_site_data_utils.cc index 05add964..78c9186 100644 --- a/content/browser/browsing_data/clear_site_data_utils.cc +++ b/content/browser/browsing_data/clear_site_data_utils.cc
@@ -25,18 +25,21 @@ // on the IO thread. class SiteDataClearer : public BrowsingDataRemover::Observer { public: - SiteDataClearer(BrowserContext* browser_context, - const url::Origin& origin, - bool clear_cookies, - bool clear_storage, - bool clear_cache, - bool avoid_closing_connections, - base::OnceClosure callback) + SiteDataClearer( + BrowserContext* browser_context, + const url::Origin& origin, + bool clear_cookies, + bool clear_storage, + bool clear_cache, + bool avoid_closing_connections, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + base::OnceClosure callback) : origin_(origin), clear_cookies_(clear_cookies), clear_storage_(clear_storage), clear_cache_(clear_cache), avoid_closing_connections_(avoid_closing_connections), + cookie_partition_key_(cookie_partition_key), callback_(std::move(callback)), pending_task_count_(0), remover_(nullptr) { @@ -69,10 +72,13 @@ if (domain.empty()) domain = origin_.host(); // IP address or internal hostname. - std::unique_ptr<BrowsingDataFilterBuilder> domain_filter_builder( + std::unique_ptr<BrowsingDataFilterBuilder> cookie_filter_builder( BrowsingDataFilterBuilder::Create( BrowsingDataFilterBuilder::Mode::kDelete)); - domain_filter_builder->AddRegisterableDomain(domain); + cookie_filter_builder->AddRegisterableDomain(domain); + cookie_filter_builder->SetCookiePartitionKeyCollection( + net::CookiePartitionKeyCollection::FromOptional( + cookie_partition_key_)); pending_task_count_++; uint64_t remove_mask = BrowsingDataRemover::DATA_TYPE_COOKIES; @@ -83,7 +89,7 @@ base::Time(), base::Time::Max(), remove_mask, BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB, - std::move(domain_filter_builder), this); + std::move(cookie_filter_builder), this); } // Delete origin-scoped data. @@ -126,6 +132,7 @@ bool clear_storage_; bool clear_cache_; bool avoid_closing_connections_; + absl::optional<net::CookiePartitionKey> cookie_partition_key_; base::OnceClosure callback_; int pending_task_count_; raw_ptr<BrowsingDataRemover> remover_; @@ -142,6 +149,7 @@ bool clear_storage, bool clear_cache, bool avoid_closing_connections, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); BrowserContext* browser_context = browser_context_getter.Run(); @@ -151,7 +159,7 @@ } (new SiteDataClearer(browser_context, origin, clear_cookies, clear_storage, clear_cache, avoid_closing_connections, - std::move(callback))) + cookie_partition_key, std::move(callback))) ->RunAndDestroySelfWhenDone(); }
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 3c2d16c..0983278 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -330,6 +330,8 @@ agent_host_->DetachClient(this); } + std::string GetTypeForMetrics() override { return "RemoteDebugger"; } + void AgentHostClosed(DevToolsAgentHost* agent_host) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(agent_host == agent_host_.get());
diff --git a/content/browser/devtools/devtools_pipe_handler.cc b/content/browser/devtools/devtools_pipe_handler.cc index e39b4c1..ca03e0b8 100644 --- a/content/browser/devtools/devtools_pipe_handler.cc +++ b/content/browser/devtools/devtools_pipe_handler.cc
@@ -422,4 +422,8 @@ return true; } +std::string DevToolsPipeHandler::GetTypeForMetrics() { + return "RemoteDebugger"; +} + } // namespace content
diff --git a/content/browser/devtools/devtools_pipe_handler.h b/content/browser/devtools/devtools_pipe_handler.h index 626a505e..14e784d 100644 --- a/content/browser/devtools/devtools_pipe_handler.h +++ b/content/browser/devtools/devtools_pipe_handler.h
@@ -33,6 +33,7 @@ void AgentHostClosed(DevToolsAgentHost* agent_host) override; bool UsesBinaryProtocol() override; bool AllowUnsafeOperations() override; + std::string GetTypeForMetrics() override; void Shutdown();
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index b0d8b48..2e574d5f 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -2891,6 +2891,7 @@ base::StringPiece scheme, RenderProcessHost* host, int routing_id, + const url::Origin& origin, network::mojom::URLLoaderFactoryParamsPtr params) { if (!host || !params) { // Return an invalid remote by default. @@ -2917,7 +2918,7 @@ GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( - host->GetID(), routing_id, &factories); + host->GetID(), routing_id, origin, &factories); auto i = factories.find(std::string(scheme)); if (i == factories.end()) { return {}; @@ -2990,7 +2991,7 @@ auto factory = CreateNetworkFactoryForDevTools( gurl.scheme(), frame->GetProcess(), frame->GetRoutingID(), - std::move(params)); + frame->GetLastCommittedOrigin(), std::move(params)); url_loader_factory.Bind(std::move(factory)); auto loader = DevToolsNetworkResourceLoader::Create( @@ -3006,7 +3007,7 @@ // TODO(sigurds): Support dedicated workers. auto info = host->CreateNetworkFactoryParamsForDevTools(); auto factory = CreateNetworkFactoryForDevTools( - gurl.scheme(), host->GetProcessHost(), MSG_ROUTING_NONE, + gurl.scheme(), host->GetProcessHost(), MSG_ROUTING_NONE, info.origin, std::move(info.factory_params)); if (factory.is_valid()) { url_loader_factory.Bind(std::move(factory));
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index 66400f9..a6ff921 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -418,6 +418,8 @@ agent_host_->DetachClient(this); } + std::string GetTypeForMetrics() override { return "DevTools"; } + void Detach(bool host_closed) { handler_->frontend_->DetachedFromTarget(id_, agent_host_->GetId()); if (flatten_protocol_)
diff --git a/content/browser/direct_sockets/direct_sockets_open_browsertest.cc b/content/browser/direct_sockets/direct_sockets_open_browsertest.cc index b42f659..78de610 100644 --- a/content/browser/direct_sockets/direct_sockets_open_browsertest.cc +++ b/content/browser/direct_sockets/direct_sockets_open_browsertest.cc
@@ -6,10 +6,12 @@ #include <vector> #include "base/memory/raw_ptr.h" +#include "base/metrics/histogram.h" #include "base/run_loop.h" #include "base/strings/strcat.h" #include "base/strings/stringprintf.h" #include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "content/browser/direct_sockets/direct_sockets_service_impl.h" #include "content/browser/renderer_host/frame_tree_node.h" @@ -65,6 +67,12 @@ constexpr char kPermissionDeniedHistogramName[] = "DirectSockets.PermissionDeniedFailures"; +constexpr char kTCPNetworkFailuresHistogramName[] = + "DirectSockets.TCPNetworkFailures"; + +constexpr char kUDPNetworkFailuresHistogramName[] = + "DirectSockets.UDPNetworkFailures"; + const std::string kIPv4_tests[] = { // 0.0.0.0/8 "0.0.0.0", "0.255.255.255", @@ -612,6 +620,11 @@ DirectSocketsServiceImpl::SetPermissionCallbackForTesting( base::BindRepeating(&UnconditionallyPermitConnection)); + base::HistogramTester histogram_tester; + histogram_tester.ExpectUniqueSample(kTCPNetworkFailuresHistogramName, + -net::Error::ERR_PROXY_CONNECTION_FAILED, + 0); + MockNetworkContext mock_network_context(net::ERR_PROXY_CONNECTION_FAILED); DirectSocketsServiceImpl::SetNetworkContextForTesting(&mock_network_context); const std::string expected_result = @@ -637,6 +650,12 @@ EXPECT_EQ(3456, call.send_buffer_size); EXPECT_EQ(7890, call.receive_buffer_size); EXPECT_EQ(false, call.no_delay); + + // To sync histograms from renderer. + FetchHistogramsFromChildProcesses(); + histogram_tester.ExpectUniqueSample(kTCPNetworkFailuresHistogramName, + -net::Error::ERR_PROXY_CONNECTION_FAILED, + 1); } IN_PROC_BROWSER_TEST_F(DirectSocketsOpenBrowserTest, OpenTcp_OptionsTwo) { @@ -840,6 +859,11 @@ DirectSocketsServiceImpl::SetPermissionCallbackForTesting( base::BindRepeating(&UnconditionallyPermitConnection)); + base::HistogramTester histogram_tester; + histogram_tester.ExpectUniqueSample(kUDPNetworkFailuresHistogramName, + -net::Error::ERR_PROXY_CONNECTION_FAILED, + 0); + MockNetworkContext mock_network_context(net::ERR_PROXY_CONNECTION_FAILED); DirectSocketsServiceImpl::SetNetworkContextForTesting(&mock_network_context); const std::string expected_result = @@ -863,6 +887,12 @@ EXPECT_EQ(9012, call.remote_port); EXPECT_EQ(3456, call.send_buffer_size); EXPECT_EQ(7890, call.receive_buffer_size); + + // To sync histograms from renderer. + FetchHistogramsFromChildProcesses(); + histogram_tester.ExpectUniqueSample(kUDPNetworkFailuresHistogramName, + -net::Error::ERR_PROXY_CONNECTION_FAILED, + 1); } IN_PROC_BROWSER_TEST_F(DirectSocketsOpenBrowserTest, OpenUdp_OptionsTwo) {
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 23b2347..c99bae3 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -1361,7 +1361,7 @@ ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( params->render_process_host_id(), - params->render_frame_host_routing_id(), + params->render_frame_host_routing_id(), params->initiator(), &non_network_url_loader_factories); auto it = non_network_url_loader_factories.find(params->url().scheme()); if (it != non_network_url_loader_factories.end()) {
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc index 205d001..0bc9c70 100644 --- a/content/browser/fenced_frame/fenced_frame_browsertest.cc +++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -230,10 +230,10 @@ } // Test that when the documents inside fenced frame tree are loading, -// WebContentsObserver::DocumentOnLoadCompletedInMainFrame is not invoked for -// fenced frames as it is only invoked for primary main frames. +// WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame is not invoked +// for fenced frames as it is only invoked for primary main frames. IN_PROC_BROWSER_TEST_F(FencedFrameBrowserTest, - DocumentOnLoadCompletedInMainFrame) { + DocumentOnLoadCompletedInPrimaryMainFrame) { // Initialize a MockWebContentsObserver to ensure that // DocumentAvailableInMainFrame is only invoked for primary main // RenderFrameHosts. @@ -241,18 +241,18 @@ web_contents()); // Navigate to an initial primary page. This should result in invoking - // DocumentOnLoadCompletedInMainFrame once. + // DocumentOnLoadCompletedInPrimaryMainFrame once. EXPECT_CALL(web_contents_observer, - DocumentOnLoadCompletedInMainFrame(primary_main_frame_host())) + DocumentOnLoadCompletedInPrimaryMainFrame()) .Times(1); EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL( "fencedframe.test", "/title1.html"))); RenderFrameHostImplWrapper primary_rfh(primary_main_frame_host()); // Once the fenced frame complets loading, it shouldn't result in - // invoking DocumentOnLoadCompletedInMainFrame. + // invoking DocumentOnLoadCompletedInPrimaryMainFrame. EXPECT_CALL(web_contents_observer, - DocumentOnLoadCompletedInMainFrame(testing::_)) + DocumentOnLoadCompletedInPrimaryMainFrame()) .Times(0); const GURL fenced_frame_url = embedded_test_server()->GetURL( "fencedframe.test", "/fenced_frames/title1.html");
diff --git a/content/browser/fenced_frame/fenced_frame_url_mapping.cc b/content/browser/fenced_frame/fenced_frame_url_mapping.cc index 1e93bff00..4a52b79 100644 --- a/content/browser/fenced_frame/fenced_frame_url_mapping.cc +++ b/content/browser/fenced_frame/fenced_frame_url_mapping.cc
@@ -64,7 +64,7 @@ void FencedFrameURLMapping::PendingAdComponentsMap::ExportToMapping( FencedFrameURLMapping& mapping) const { for (const auto& component_ad : component_ads_) { - CHECK(!mapping.IsPresent(component_ad.urn)); + DCHECK(!mapping.IsMapped(component_ad.urn)); UrnUuidToUrlMap::iterator it = mapping.urn_uuid_to_url_map_ @@ -108,22 +108,6 @@ FencedFrameURLMapping::FencedFrameURLMapping() = default; FencedFrameURLMapping::~FencedFrameURLMapping() = default; -absl::optional<GURL> FencedFrameURLMapping::ConvertFencedFrameURNToURL( - const GURL& urn_uuid, - absl::optional<PendingAdComponentsMap>& out_ad_components) const { - CHECK(IsValidUrnUuidURL(urn_uuid)); - - auto it = urn_uuid_to_url_map_.find(urn_uuid); - if (it == urn_uuid_to_url_map_.end()) - return absl::nullopt; - - if (it->second.ad_component_urls) { - out_ad_components.emplace( - PendingAdComponentsMap(*it->second.ad_component_urls)); - } - return it->second.mapped_url; -} - GURL FencedFrameURLMapping::AddFencedFrameURL(const GURL& url) { DCHECK(url.is_valid()); DCHECK(network::IsUrlPotentiallyTrustworthy(url)); @@ -143,13 +127,95 @@ FencedFrameURLMapping::AddMappingForUrl(const GURL& url) { // Create a urn::uuid. GURL urn_uuid = GenerateURN(); - CHECK(!IsPresent(urn_uuid)); + DCHECK(!IsMapped(urn_uuid)); return urn_uuid_to_url_map_.emplace(urn_uuid, MapInfo(url)).first; } -bool FencedFrameURLMapping::IsPresent(const GURL& urn_uuid) { +GURL FencedFrameURLMapping::GeneratePendingMappedURN() { + GURL urn_uuid = GenerateURN(); + DCHECK(!IsMapped(urn_uuid)); + DCHECK(!IsPendingMapped(urn_uuid)); + pending_urn_uuid_to_url_map_.emplace( + urn_uuid, std::set<raw_ptr<MappingResultObserver>>()); + return urn_uuid; +} + +void FencedFrameURLMapping::ConvertFencedFrameURNToURL( + const GURL& urn_uuid, + MappingResultObserver* observer) { + DCHECK(IsValidUrnUuidURL(urn_uuid)); + + if (IsPendingMapped(urn_uuid)) { + DCHECK(!pending_urn_uuid_to_url_map_.at(urn_uuid).count(observer)); + pending_urn_uuid_to_url_map_.at(urn_uuid).emplace(observer); + return; + } + + absl::optional<GURL> result_url; + absl::optional<PendingAdComponentsMap> result_ad_components; + + auto it = urn_uuid_to_url_map_.find(urn_uuid); + if (it != urn_uuid_to_url_map_.end()) { + if (it->second.ad_component_urls) { + result_ad_components.emplace( + PendingAdComponentsMap(*it->second.ad_component_urls)); + } + result_url = it->second.mapped_url; + } + + observer->OnFencedFrameURLMappingComplete(std::move(result_url), + std::move(result_ad_components)); +} + +void FencedFrameURLMapping::RemoveObserverForURN( + const GURL& urn_uuid, + MappingResultObserver* observer) { + auto it = pending_urn_uuid_to_url_map_.find(urn_uuid); + DCHECK(it != pending_urn_uuid_to_url_map_.end()); + + auto observer_it = it->second.find(observer); + DCHECK(observer_it != it->second.end()); + + it->second.erase(observer_it); +} + +void FencedFrameURLMapping::OnURNMappingResultDetermined( + const GURL& urn_uuid, + const absl::optional<GURL>& mapped_url) { + auto it = pending_urn_uuid_to_url_map_.find(urn_uuid); + DCHECK(it != pending_urn_uuid_to_url_map_.end()); + + DCHECK(!IsMapped(urn_uuid)); + + if (mapped_url) + urn_uuid_to_url_map_.emplace(urn_uuid, mapped_url.value()); + + std::set<raw_ptr<MappingResultObserver>>& observers = it->second; + + for (raw_ptr<MappingResultObserver> observer : observers) { + observer->OnFencedFrameURLMappingComplete( + mapped_url, + /*pending_ad_components_map=*/absl::nullopt); + } + + pending_urn_uuid_to_url_map_.erase(it); +} + +bool FencedFrameURLMapping::HasObserverForTesting( + const GURL& urn_uuid, + MappingResultObserver* observer) { + return IsPendingMapped(urn_uuid) && + pending_urn_uuid_to_url_map_.at(urn_uuid).count(observer); +} + +bool FencedFrameURLMapping::IsMapped(const GURL& urn_uuid) const { return urn_uuid_to_url_map_.find(urn_uuid) != urn_uuid_to_url_map_.end(); } +bool FencedFrameURLMapping::IsPendingMapped(const GURL& urn_uuid) const { + return pending_urn_uuid_to_url_map_.find(urn_uuid) != + pending_urn_uuid_to_url_map_.end(); +} + } // namespace content
diff --git a/content/browser/fenced_frame/fenced_frame_url_mapping.h b/content/browser/fenced_frame/fenced_frame_url_mapping.h index 5ab4584..f8578ac6 100644 --- a/content/browser/fenced_frame/fenced_frame_url_mapping.h +++ b/content/browser/fenced_frame/fenced_frame_url_mapping.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_FENCED_FRAME_FENCED_FRAME_URL_MAPPING_H_ #include <map> +#include <set> #include <string> #include <vector> @@ -17,10 +18,9 @@ extern const char kURNUUIDprefix[]; -// Keeps a mapping of fenced frames URN:UUID and URL. See +// Keeps a mapping of fenced frames URN:UUID and URL. Also keeps a set of +// pending mapped URN:UUIDs to support asynchronous mapping. See // https://github.com/shivanigithub/fenced-frame/blob/master/OpaqueSrc.md -// TODO(crbug.com/1216088) Also support asynchronous mapping of urn:uuid to -// url. class CONTENT_EXPORT FencedFrameURLMapping { public: // When the result of an ad auction is a main ad URL with a set of ad @@ -75,24 +75,34 @@ std::vector<AdComponent> component_ads_; }; + class MappingResultObserver { + public: + virtual ~MappingResultObserver() = default; + + // Called as soon as the URN mapping decision is made. + // + // On success, `mapped_url` will be populated with the result URL. If the + // original URN is the result of an InterestGroup auction (which is only + // possible when the initial URN is already mapped, and the + // `OnFencedFrameURLMappingComplete` is invoked synchronously), + // `pending_ad_components_map` will be populated with a + // `PendingAdComponentsMap`. In that case, the observer needs to use the + // `PendingAdComponentsMap` to provide ad component URNs to the fenced frame + // via its commit parameters, and to add those URNs to the + // `FencedFrameURLMapping` of the committed frame. + // + // On failure, both `mapped_url` and `pending_ad_components_map` will be + // absl::nullopt. + virtual void OnFencedFrameURLMappingComplete( + absl::optional<GURL> mapped_url, + absl::optional<PendingAdComponentsMap> pending_ad_components_map) = 0; + }; + FencedFrameURLMapping(); ~FencedFrameURLMapping(); FencedFrameURLMapping(FencedFrameURLMapping&) = delete; FencedFrameURLMapping& operator=(FencedFrameURLMapping&) = delete; - // Converts given |urn_uuid| to the mapped URL. Only returns a GURL if a - // mapping exists for |urn_uuid|. Should only be invoked with a valid url - // with the urn scheme. - // - // If the passed in URN is the result of an InterestGroup auction, - // `out_ad_components` will be populated with a PendingAdComponentsMap. - // In that case, the caller needs to use the PendingAdComponentsMap to provide - // ad component URNs to the fenced frame via its commit parameters, and to add - // those URNs the FencedFrameURLMapping of the committed frame. - absl::optional<GURL> ConvertFencedFrameURNToURL( - const GURL& urn_uuid, - absl::optional<PendingAdComponentsMap>& out_ad_components) const; - // Adds a mapping for |url| to a URN:UUID that will be generated by this // function. Should only be invoked with a valid URL which is one of the // "potentially trustworthy URLs". @@ -110,6 +120,39 @@ static bool IsValidUrnUuidURL(const GURL& url); + // Generate a URN that is not yet mapped to a URL. Used by the Shared Storage + // API to return the URN for `sharedStorage.runURLSelectionOperation` before + // the URL selection decision is made. + GURL GeneratePendingMappedURN(); + + // Register an observer for `urn_uuid`. The observer will be notified with the + // mapping result and will be auto unregistered. If `urn_uuid` already exists + // in `urn_uuid_to_url_map_`, or if it is not recognized at all, the observer + // will be notified synchronously; if the mapping is pending (i.e. `urn_uuid` + // exists in `pending_urn_uuid_to_url_map_`), the observer will be notified + // asynchronously as soon as when the mapping decision is made. + void ConvertFencedFrameURNToURL(const GURL& urn_uuid, + MappingResultObserver* observer); + + // Explicitly unregister the observer for `urn_uuid`. This is only needed if + // the observer is going to become invalid and the mapping is still pending. + void RemoveObserverForURN(const GURL& urn_uuid, + MappingResultObserver* observer); + + // Called when the mapping decision is made for `urn_uuid`. On success, + // `mapped_url` will be the result url; on failure,`mapped_url` will be + // absl::nullopt. Should only be invoked with a `urn_uuid` pending to be + // mapped. This method will trigger the observers' + // OnFencedFrameURLMappingComplete() method associated with the `urn_uuid`, + // unregister those observers, and remove `urn_uuid` from + // `pending_urn_uuid_to_url_map_`. If the mapping succeeded, the `urn_uuid` + // will be added to `urn_uuid_to_url_map_`. + void OnURNMappingResultDetermined(const GURL& urn_uuid, + const absl::optional<GURL>& mapped_url); + + bool HasObserverForTesting(const GURL& urn_uuid, + MappingResultObserver* observer); + private: // Contains the URL a particular URN is mapped to, along with any extra data // associated with the URL that needs to be used on commit. @@ -140,9 +183,16 @@ // as the key. UrnUuidToUrlMap::iterator AddMappingForUrl(const GURL& url); - bool IsPresent(const GURL& urn_uuid); + bool IsMapped(const GURL& urn_uuid) const; + bool IsPendingMapped(const GURL& urn_uuid) const; + // The URNs that are already mapped to URLs, along with their mapping info. UrnUuidToUrlMap urn_uuid_to_url_map_; + + // The URNs that are not yet mapped to URLs, along with the associated + // observers to be notified when the mapping decision is made. + std::map<GURL, std::set<raw_ptr<MappingResultObserver>>> + pending_urn_uuid_to_url_map_; }; } // namespace content
diff --git a/content/browser/fenced_frame/fenced_frame_url_mapping_unittest.cc b/content/browser/fenced_frame/fenced_frame_url_mapping_unittest.cc index 0b7b77a42..f580f529 100644 --- a/content/browser/fenced_frame/fenced_frame_url_mapping_unittest.cc +++ b/content/browser/fenced_frame/fenced_frame_url_mapping_unittest.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "content/test/test_fenced_frame_url_mapping_result_observer.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/interest_group/ad_auction_constants.h" @@ -46,11 +47,12 @@ // The URNs should not yet be in `fenced_frame_url_mapping`, so they can // safely be added to it. - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - nested_ad_components; - EXPECT_FALSE(fenced_frame_url_mapping->ConvertFencedFrameURNToURL( - ad_component_urns[i], nested_ad_components)); - EXPECT_FALSE(nested_ad_components); + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping->ConvertFencedFrameURNToURL(ad_component_urns[i], + &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_FALSE(observer.mapped_url()); + EXPECT_FALSE(observer.pending_ad_components_map()); } // Add the `pending_ad_components` to a mapping. If `add_to_new_map` is true, @@ -67,35 +69,35 @@ for (size_t i = 0; i < ad_component_urns.size(); ++i) { // The URNs should now be in `fenced_frame_url_mapping`. Look up the // corresponding URL, and make sure it's mapped to the correct URL. - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - nested_pending_ad_components; - absl::optional<GURL> mapped_url = - fenced_frame_url_mapping->ConvertFencedFrameURNToURL( - ad_component_urns[i], nested_pending_ad_components); - ASSERT_TRUE(mapped_url); + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping->ConvertFencedFrameURNToURL(ad_component_urns[i], + &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + if (i < expected_mapped_urls.size()) { - EXPECT_EQ(expected_mapped_urls[i], mapped_url); + EXPECT_EQ(expected_mapped_urls[i], observer.mapped_url()); } else { - EXPECT_EQ(GURL(url::kAboutBlankURL), mapped_url); + EXPECT_EQ(GURL(url::kAboutBlankURL), observer.mapped_url()); } // Each added URN should also have a populated - // `nested_pending_ad_components` structure, to prevent ads from knowing if - // they were loaded in a fenced frame as an ad component or as the main ad. - // Any information passed to ads violates the k-anonymity requirement. - ASSERT_TRUE(nested_pending_ad_components); + // `observer.pending_ad_components_map()` structure, to prevent ads from + // knowing if they were loaded in a fenced frame as an ad component or as + // the main ad. Any information passed to ads violates the k-anonymity + // requirement. + EXPECT_TRUE(observer.pending_ad_components_map()); // If this it not an about:blank URL, then when loaded in a fenced frame, it // can recursively access its own nested ad components array, so recursively // check those as well. - if (*mapped_url != GURL(url::kAboutBlankURL)) { + if (*observer.mapped_url() != GURL(url::kAboutBlankURL)) { // Nested URL maps map everything to "about:blank". They exist solely so // that top-level and nested component ads can't tell which one they are, // to prevent smuggling data based on whether an ad is loaded in a // top-level ad URL or a component ad URL. ValidatePendingAdComponentsMap( fenced_frame_url_mapping, add_to_new_map, - *nested_pending_ad_components, + *observer.pending_ad_components_map(), /*expected_mapped_urls=*/std::vector<GURL>()); } } @@ -107,22 +109,93 @@ FencedFrameURLMapping fenced_frame_url_mapping; GURL test_url("https://foo.test"); GURL urn_uuid = fenced_frame_url_mapping.AddFencedFrameURL(test_url); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> ad_components; - EXPECT_EQ(test_url, fenced_frame_url_mapping - .ConvertFencedFrameURNToURL(urn_uuid, ad_components) - .value()); - EXPECT_EQ(absl::nullopt, ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(test_url, observer.mapped_url()); + EXPECT_EQ(absl::nullopt, observer.pending_ad_components_map()); } TEST(FencedFrameURLMappingTest, NonExistentUUID) { FencedFrameURLMapping fenced_frame_url_mapping; GURL urn_uuid("urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a"); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> ad_components; - absl::optional<GURL> result = - fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, - ad_components); - EXPECT_EQ(absl::nullopt, result); - EXPECT_EQ(absl::nullopt, ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(absl::nullopt, observer.mapped_url()); + EXPECT_EQ(absl::nullopt, observer.pending_ad_components_map()); +} + +TEST(FencedFrameURLMappingTest, PendingMappedUUID_MappingSuccess) { + FencedFrameURLMapping fenced_frame_url_mapping; + const GURL urn_uuid = fenced_frame_url_mapping.GeneratePendingMappedURN(); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_FALSE(observer.mapping_complete_observed()); + + fenced_frame_url_mapping.OnURNMappingResultDetermined( + urn_uuid, GURL("https://foo.com")); + + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(GURL("https://foo.com"), observer.mapped_url()); + EXPECT_EQ(absl::nullopt, observer.pending_ad_components_map()); +} + +TEST(FencedFrameURLMappingTest, PendingMappedUUID_MappingFailure) { + FencedFrameURLMapping fenced_frame_url_mapping; + const GURL urn_uuid = fenced_frame_url_mapping.GeneratePendingMappedURN(); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_FALSE(observer.mapping_complete_observed()); + + fenced_frame_url_mapping.OnURNMappingResultDetermined(urn_uuid, + absl::nullopt); + + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(absl::nullopt, observer.mapped_url()); + EXPECT_EQ(absl::nullopt, observer.pending_ad_components_map()); +} + +TEST(FencedFrameURLMappingTest, RemoveObserverOnPendingMappedUUID) { + FencedFrameURLMapping fenced_frame_url_mapping; + const GURL urn_uuid = fenced_frame_url_mapping.GeneratePendingMappedURN(); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_FALSE(observer.mapping_complete_observed()); + + fenced_frame_url_mapping.RemoveObserverForURN(urn_uuid, &observer); + fenced_frame_url_mapping.OnURNMappingResultDetermined( + urn_uuid, GURL("https://foo.com")); + + EXPECT_FALSE(observer.mapping_complete_observed()); +} + +TEST(FencedFrameURLMappingTest, RegisterTwoObservers) { + FencedFrameURLMapping fenced_frame_url_mapping; + const GURL urn_uuid = fenced_frame_url_mapping.GeneratePendingMappedURN(); + + TestFencedFrameURLMappingResultObserver observer1; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer1); + EXPECT_FALSE(observer1.mapping_complete_observed()); + + TestFencedFrameURLMappingResultObserver observer2; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer2); + EXPECT_FALSE(observer2.mapping_complete_observed()); + + fenced_frame_url_mapping.OnURNMappingResultDetermined( + urn_uuid, GURL("https://foo.com")); + + EXPECT_TRUE(observer1.mapping_complete_observed()); + EXPECT_EQ(GURL("https://foo.com"), observer1.mapped_url()); + EXPECT_EQ(absl::nullopt, observer1.pending_ad_components_map()); + EXPECT_TRUE(observer2.mapping_complete_observed()); + EXPECT_EQ(GURL("https://foo.com"), observer2.mapped_url()); + EXPECT_EQ(absl::nullopt, observer2.pending_ad_components_map()); } // Test the case `ad_component_urls` is empty. In this case, it should be filled @@ -136,21 +209,22 @@ GURL urn_uuid = fenced_frame_url_mapping .AddFencedFrameURLWithInterestGroupAdComponentUrls( top_level_url, ad_component_urls); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components; - EXPECT_EQ(top_level_url, fenced_frame_url_mapping.ConvertFencedFrameURNToURL( - urn_uuid, pending_ad_components)); - ASSERT_TRUE(pending_ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(top_level_url, observer.mapped_url()); + EXPECT_TRUE(observer.pending_ad_components_map()); // Call with `add_to_new_map` set to false and true, to simulate ShadowDOM // and MPArch behavior, respectively. ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/true, - *pending_ad_components, + *observer.pending_ad_components_map(), /*expected_mapped_urls=*/{}); ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/false, - *pending_ad_components, + *observer.pending_ad_components_map(), /*expected_mapped_urls=*/{}); } @@ -164,20 +238,23 @@ GURL urn_uuid = fenced_frame_url_mapping .AddFencedFrameURLWithInterestGroupAdComponentUrls( top_level_url, ad_component_urls); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components; - EXPECT_EQ(top_level_url, fenced_frame_url_mapping.ConvertFencedFrameURNToURL( - urn_uuid, pending_ad_components)); - ASSERT_TRUE(pending_ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(top_level_url, observer.mapped_url()); + EXPECT_TRUE(observer.pending_ad_components_map()); // Call with `add_to_new_map` set to false and true, to simulate ShadowDOM // and MPArch behavior, respectively. ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/true, - *pending_ad_components, ad_component_urls); + *observer.pending_ad_components_map(), + ad_component_urls); ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/false, - *pending_ad_components, ad_component_urls); + *observer.pending_ad_components_map(), + ad_component_urls); } // Test the case `ad_component_urls` has the maximum number of allowed ad @@ -195,20 +272,23 @@ GURL urn_uuid = fenced_frame_url_mapping .AddFencedFrameURLWithInterestGroupAdComponentUrls( top_level_url, ad_component_urls); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components; - EXPECT_EQ(top_level_url, fenced_frame_url_mapping.ConvertFencedFrameURNToURL( - urn_uuid, pending_ad_components)); - ASSERT_TRUE(pending_ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(top_level_url, observer.mapped_url()); + EXPECT_TRUE(observer.pending_ad_components_map()); // Call with `add_to_new_map` set to false and true, to simulate ShadowDOM // and MPArch behavior, respectively. ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/true, - *pending_ad_components, ad_component_urls); + *observer.pending_ad_components_map(), + ad_component_urls); ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/false, - *pending_ad_components, ad_component_urls); + *observer.pending_ad_components_map(), + ad_component_urls); } // Test the case `ad_component_urls` has the maximum number of allowed ad @@ -225,21 +305,22 @@ GURL urn_uuid = fenced_frame_url_mapping .AddFencedFrameURLWithInterestGroupAdComponentUrls( top_level_url, ad_component_urls); - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components; - EXPECT_EQ(top_level_url, fenced_frame_url_mapping.ConvertFencedFrameURNToURL( - urn_uuid, pending_ad_components)); - ASSERT_TRUE(pending_ad_components); + + TestFencedFrameURLMappingResultObserver observer; + fenced_frame_url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &observer); + EXPECT_TRUE(observer.mapping_complete_observed()); + EXPECT_EQ(top_level_url, observer.mapped_url()); + EXPECT_TRUE(observer.pending_ad_components_map()); // Call with `add_to_new_map` set to false and true, to simulate ShadowDOM // and MPArch behavior, respectively. ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/true, - *pending_ad_components, + *observer.pending_ad_components_map(), /*expected_mapped_urls=*/ad_component_urls); ValidatePendingAdComponentsMap(&fenced_frame_url_mapping, /*add_to_new_map=*/false, - *pending_ad_components, + *observer.pending_ad_components_map(), /*expected_mapped_urls=*/ad_component_urls); }
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 4542f1b..fc2f0598 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -305,19 +305,14 @@ gpu_client_id_, cache_dir)); } - bool use_gr_shader_cache = base::FeatureList::IsEnabled( - features::kDefaultEnableOopRasterization) || - features::IsUsingSkiaRenderer(); - if (use_gr_shader_cache) { - base::FilePath gr_cache_dir = - GetContentClient()->browser()->GetGrShaderDiskCacheDirectory(); - if (!gr_cache_dir.empty()) { - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce( - &BrowserGpuChannelHostFactory::InitializeGrShaderDiskCacheOnIO, - gr_cache_dir)); - } + base::FilePath gr_cache_dir = + GetContentClient()->browser()->GetGrShaderDiskCacheDirectory(); + if (!gr_cache_dir.empty()) { + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &BrowserGpuChannelHostFactory::InitializeGrShaderDiskCacheOnIO, + gr_cache_dir)); } } }
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index b3f08e1..0fe57acb 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -609,7 +609,7 @@ EXPECT_EQ(a.last_modified(), b.last_modified()); return false; } - FALLTHROUGH; + [[fallthrough]]; case IndexedDBExternalObject::ObjectType::kBlob: if (a.type() != b.type()) { EXPECT_EQ(a.type(), b.type());
diff --git a/content/browser/interest_group/DEPS b/content/browser/interest_group/DEPS index be1d75fb..8ba2547 100644 --- a/content/browser/interest_group/DEPS +++ b/content/browser/interest_group/DEPS
@@ -3,9 +3,8 @@ ] specific_include_rules = { - # The AuctionRunnerTests have integration tests that directly instantiate an - # in-process auction_worklet service. - "auction_runner_unittest\.cc": [ + # Some unit tests directly instantiate an in-process auction_worklet service. + ".*_unittest\.cc": [ "+content/services/auction_worklet", ], -} \ No newline at end of file +}
diff --git a/content/browser/interest_group/ad_auction_result_metrics.cc b/content/browser/interest_group/ad_auction_result_metrics.cc new file mode 100644 index 0000000..694405b --- /dev/null +++ b/content/browser/interest_group/ad_auction_result_metrics.cc
@@ -0,0 +1,59 @@ +// 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 "content/browser/interest_group/ad_auction_result_metrics.h" + +#include "base/check_op.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/sparse_histogram.h" +#include "base/time/time.h" +#include "content/public/browser/page_user_data.h" + +namespace content { + +class Page; + +AdAuctionResultMetrics::AdAuctionResultMetrics(content::Page& page) + : PageUserData<AdAuctionResultMetrics>(page) {} + +AdAuctionResultMetrics::~AdAuctionResultMetrics() { + if (num_auctions_ <= 0) + return; + base::UmaHistogramCounts100("Ads.InterestGroup.Auction.NumAuctionsPerPage", + num_auctions_); + base::UmaHistogramPercentage( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage", + num_successful_auctions_ * 100 / num_auctions_); + DCHECK_GE(first_auction_bits_, 0b10u); + DCHECK_LE(first_auction_bits_, (1 << kNumFirstAuctionBits) - 1); + base::SparseHistogram::FactoryGet( + "Ads.InterestGroup.Auction.First6AuctionsBitsPerPage", + base::HistogramBase::kUmaTargetedHistogramFlag) + ->Add(first_auction_bits_); +} + +void AdAuctionResultMetrics::ReportAuctionResult( + AdAuctionResultMetrics::AuctionResult result) { + num_auctions_++; + if (num_auctions_ < kNumFirstAuctionBits) + first_auction_bits_ <<= 1; + if (result == AdAuctionResultMetrics::AuctionResult::kSucceeded) { + num_successful_auctions_++; + if (num_auctions_ < kNumFirstAuctionBits) + first_auction_bits_ |= 0x1; + } + const base::TimeTicks now = base::TimeTicks::Now(); + const base::TimeDelta time_since_last_auction = + (last_auction_time_ == base::TimeTicks::Min()) ? base::TimeDelta::Max() + : now - last_auction_time_; + last_auction_time_ = now; + + base::UmaHistogramLongTimes100( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", + time_since_last_auction); +} + +PAGE_USER_DATA_KEY_IMPL(AdAuctionResultMetrics); + +} // namespace content
diff --git a/content/browser/interest_group/ad_auction_result_metrics.h b/content/browser/interest_group/ad_auction_result_metrics.h new file mode 100644 index 0000000..e2353bc40 --- /dev/null +++ b/content/browser/interest_group/ad_auction_result_metrics.h
@@ -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. + +#ifndef CONTENT_BROWSER_INTEREST_GROUP_AD_AUCTION_RESULT_METRICS_H_ +#define CONTENT_BROWSER_INTEREST_GROUP_AD_AUCTION_RESULT_METRICS_H_ + +#include <climits> + +#include "base/time/time.h" +#include "content/public/browser/page_user_data.h" + +namespace content { + +class Page; + +class AdAuctionResultMetrics + : public content::PageUserData<AdAuctionResultMetrics> { + public: + enum class AuctionResult { kSucceeded, kFailed }; + + explicit AdAuctionResultMetrics(content::Page& page); + ~AdAuctionResultMetrics() override; + + void ReportAuctionResult(AuctionResult result); + + private: + // Number of bits to record for the first N auctions, including a leading 1. + // That is, kNumFirstAuctionBits - 1 auctions will be recorded. Increasing + // this number will increase the number of UMA buckets, so don't set it too + // high. + static constexpr int kNumFirstAuctionBits = 7; + + int num_auctions_ = 0; + int num_successful_auctions_ = 0; + uint8_t first_auction_bits_ = 1u; + base::TimeTicks last_auction_time_ = base::TimeTicks::Min(); + + static_assert(kNumFirstAuctionBits <= + sizeof(AdAuctionResultMetrics::first_auction_bits_) * + CHAR_BIT, + "Not enough bits in `last_auction_time_`."); + + friend PageUserData; + PAGE_USER_DATA_KEY_DECL(); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_INTEREST_GROUP_AD_AUCTION_RESULT_METRICS_H_
diff --git a/content/browser/interest_group/ad_auction_service_impl.cc b/content/browser/interest_group/ad_auction_service_impl.cc index 0dbb7da..fd46537f 100644 --- a/content/browser/interest_group/ad_auction_service_impl.cc +++ b/content/browser/interest_group/ad_auction_service_impl.cc
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/fenced_frame/fenced_frame_url_mapping.h" +#include "content/browser/interest_group/ad_auction_result_metrics.h" #include "content/browser/interest_group/auction_runner.h" #include "content/browser/interest_group/interest_group_manager.h" #include "content/browser/renderer_host/page_impl.h" @@ -93,7 +94,7 @@ network::SimpleURLLoader* simple_url_loader_ptr = simple_url_loader.get(); // Pass simple_url_loader to keep it alive until the request fails or succeeds // to prevent cancelling the request. - // TODO(qingxin): time out these requests if they take too long. + simple_url_loader_ptr->SetTimeoutDuration(base::Seconds(30)); simple_url_loader_ptr->DownloadHeadersOnly( url_loader_factory, base::BindOnce([](std::unique_ptr<network::SimpleURLLoader>, @@ -139,22 +140,28 @@ return false; } - if (!config.interest_group_buyers || - config.interest_group_buyers->is_all_buyers()) { + const auto& shareable_config = config.shareable_auction_ad_config; + // This isn't marked as optional in the Mojo struct, so Mojo should make sure + // it is non-null. + DCHECK(shareable_config); + + if (!shareable_config->interest_group_buyers || + shareable_config->interest_group_buyers->is_all_buyers()) { return false; } - DCHECK(config.interest_group_buyers->is_buyers()); + DCHECK(shareable_config->interest_group_buyers->is_buyers()); // All interest group owners must be HTTPS. - for (const url::Origin& buyer : config.interest_group_buyers->get_buyers()) { + for (const url::Origin& buyer : + shareable_config->interest_group_buyers->get_buyers()) { if (buyer.scheme() != url::kHttpsScheme) return false; } // All buyer signals must be for listed buyers. - if (config.per_buyer_signals) { - for (const auto& it : config.per_buyer_signals.value()) { - if (!base::Contains(config.interest_group_buyers->get_buyers(), + if (shareable_config->per_buyer_signals) { + for (const auto& it : shareable_config->per_buyer_signals.value()) { + if (!base::Contains(shareable_config->interest_group_buyers->get_buyers(), it.first)) { return false; } @@ -294,7 +301,8 @@ // Filter out buyers for whom the interest group API is not allowed. std::vector<url::Origin> filtered_buyers; - const auto& buyers = config->interest_group_buyers->get_buyers(); + const auto& buyers = + config->shareable_auction_ad_config->interest_group_buyers->get_buyers(); std::copy_if( buyers.begin(), buyers.end(), std::back_inserter(filtered_buyers), [browser_context, &frame_origin](const url::Origin& buyer) { @@ -429,10 +437,15 @@ base::StrCat({"Worklet error: ", error})); } + auto* auction_result_metrics = AdAuctionResultMetrics::GetOrCreateForPage( + render_frame_host()->GetPage()); + if (!render_url) { DCHECK(!bidder_report_url); DCHECK(!seller_report_url); std::move(callback).Run(absl::nullopt); + auction_result_metrics->ReportAuctionResult( + AdAuctionResultMetrics::AuctionResult::kFailed); return; } @@ -452,6 +465,8 @@ DCHECK(render_url->is_valid()); std::move(callback).Run(render_url); + auction_result_metrics->ReportAuctionResult( + AdAuctionResultMetrics::AuctionResult::kSucceeded); network::mojom::URLLoaderFactory* factory = GetTrustedURLLoaderFactory(); if (bidder_report_url) {
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc index 3488fd75..2e5ae14 100644 --- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc +++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -6,10 +6,12 @@ #include <memory> #include <string> +#include <vector> #include "base/bind.h" #include "base/containers/flat_map.h" #include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/synchronization/lock.h" #include "base/test/bind.h" @@ -17,15 +19,26 @@ #include "base/thread_annotations.h" #include "base/time/time.h" #include "build/build_config.h" +#include "build/buildflag.h" +#include "content/browser/fenced_frame/fenced_frame_url_mapping.h" +#include "content/browser/interest_group/auction_process_manager.h" #include "content/browser/interest_group/interest_group_manager.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/storage_partition_impl.h" +#include "content/public/browser/back_forward_cache.h" #include "content/public/browser/browser_context.h" #include "content/public/common/content_client.h" +#include "content/public/test/back_forward_cache_util.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/test_renderer_host.h" +#include "content/public/test/test_utils.h" #include "content/public/test/url_loader_interceptor.h" +#include "content/services/auction_worklet/auction_v8_helper.h" +#include "content/services/auction_worklet/auction_worklet_service_impl.h" +#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h" #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h" #include "content/test/test_content_browser_client.h" +#include "content/test/test_fenced_frame_url_mapping_result_observer.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,6 +60,7 @@ constexpr char kOriginStringC[] = "https://c.test"; constexpr char kBiddingUrlPath[] = "/interest_group/bidding_logic.js"; constexpr char kNewBiddingUrlPath[] = "/interest_group/new_bidding_logic.js"; +constexpr char kDecisionUrlPath[] = "/interest_group/decision_logic.js"; constexpr char kTrustedBiddingSignalsUrlPath[] = "/interest_group/trusted_bidding_signals.json"; constexpr char kDailyUpdateUrlPath[] = @@ -81,108 +95,239 @@ } }; -constexpr char kFledgeHeaders[] = +constexpr char kFledgeUpdateHeaders[] = "HTTP/1.1 200 OK\n" "Content-type: Application/JSON\n" "X-Allow-FLEDGE: true\n"; -// Allows registering network responses to update requests; *must* be destroyed -// before the task environment is shutdown (which happens in -// RenderViewHostTestHarness::TearDown()). -class UpdateResponder { +constexpr char kFledgeScriptHeaders[] = + "HTTP/1.1 200 OK\n" + "Content-type: Application/Javascript\n" + "X-Allow-FLEDGE: true\n"; + +constexpr char kFledgeReportHeaders[] = + "HTTP/1.1 200 OK\n" + "X-Allow-FLEDGE: true\n"; + +// Allows registering network responses to update and scoring / bidding script +// requests; *must* be destroyed before the task environment is shutdown (which +// happens in RenderViewHostTestHarness::TearDown()). +// +// Updates and script serving have different requirements, but unfortunately +// it's not possible to simultaneously instantiate 2 classes that both use their +// own URLLoaderInterceptor...so these are combined in this same class. +class NetworkResponder { public: + // Register interest group update `response` to be served with JSON content + // type when a request to `url_path` is made. void RegisterUpdateResponse(const std::string& url_path, const std::string& response) { - base::AutoLock auto_lock(json_update_lock_); + base::AutoLock auto_lock(lock_); json_update_map_[url_path] = response; } - // Registers a URL to use a "deferred" response. For a deferred response, the - // request handler returns true without a write, and writes are performed - // later in DoDeferredWrite() using a "stolen" Mojo pipe to the + // Register script `response` to be served with Javascript content type when a + // request to `url_path` is made. + void RegisterScriptResponse(const std::string& url_path, + const std::string& response) { + base::AutoLock auto_lock(lock_); + script_map_[url_path] = response; + } + + // Register ad auction reporting `response` to be served when a request to + // `url_path` is made. + void RegisterReportResponse(const std::string& url_path, + const std::string& response) { + base::AutoLock auto_lock(lock_); + report_map_[url_path] = response; + } + + // Registers a URL to use a "deferred" update response. For a deferred + // response, the request handler returns true without a write, and writes are + // performed later in DoDeferredWrite() using a "stolen" Mojo pipe to the // URLLoaderClient. // // Only one request / response can be handled with this method at a time. - void RegisterDeferredResponse(const std::string& url_path) { - base::AutoLock auto_lock(json_update_lock_); + void RegisterDeferredUpdateResponse(const std::string& url_path) { + base::AutoLock auto_lock(lock_); deferred_response_url_path_ = url_path; } + // Registers a URL that, when seen, will have its URLLoaderClient stored in + // `stored_url_loader_client_` without sending a response. + // + // Only one request can be handled with this method at a time. + void RegisterStoreUrlLoaderClient(const std::string& url_path) { + base::AutoLock auto_lock(lock_); + store_url_loader_client_url_path_ = url_path; + } + // Perform the deferred response -- the test fails if the client isn't waiting - // on `url_path` registered with RegisterDeferredResponse(). - void DoDeferredResponse(const std::string& response) { - base::AutoLock auto_lock(json_update_lock_); + // on `url_path` registered with RegisterDeferredUpdateResponse(). + void DoDeferredUpdateResponse(const std::string& response) { + base::AutoLock auto_lock(lock_); ASSERT_TRUE(deferred_response_url_loader_client_.is_bound()); URLLoaderInterceptor::WriteResponse( - kFledgeHeaders, response, deferred_response_url_loader_client_.get()); + kFledgeUpdateHeaders, response, + deferred_response_url_loader_client_.get()); deferred_response_url_loader_client_.reset(); deferred_response_url_path_ = ""; } // Make the next request fail with `error` -- subsequent requests will succeed - // again unless another FailNextRequestWithError() call is made. - void FailNextRequestWithError(net::Error error) { - base::AutoLock auto_lock(json_update_lock_); + // again unless another FailNextUpdateRequestWithError() call is made. + void FailNextUpdateRequestWithError(net::Error error) { + base::AutoLock auto_lock(lock_); next_error_ = error; } + // Returns the number of updates that occurred -- does not include other + // network requests. size_t UpdateCount() const { - base::AutoLock auto_lock(json_update_lock_); + base::AutoLock auto_lock(lock_); return update_count_; } + // Returns the number of reports that occurred -- does not include other + // network requests. + size_t ReportCount() const { + base::AutoLock auto_lock(lock_); + return report_count_; + } + + // Indicates whether `stored_url_loader_client_` is connected to a receiver. + bool RemoteIsConnected() { + base::AutoLock auto_lock(lock_); + return stored_url_loader_client_.is_connected(); + } + private: - bool RequestHandlerForUpdates(URLLoaderInterceptor::RequestParams* params) { - base::AutoLock auto_lock(json_update_lock_); + bool RequestHandler(URLLoaderInterceptor::RequestParams* params) { + base::AutoLock auto_lock(lock_); + const auto script_it = script_map_.find(params->url_request.url.path()); + if (script_it != script_map_.end()) { + URLLoaderInterceptor::WriteResponse( + kFledgeScriptHeaders, script_it->second, params->client.get()); + return true; + } + + // Not a script request, check if it's a reporting request. + const auto report_it = report_map_.find(params->url_request.url.path()); + if (report_it != report_map_.end()) { + report_count_++; + URLLoaderInterceptor::WriteResponse( + kFledgeReportHeaders, report_it->second, params->client.get()); + return true; + } + + if ((params->url_request.url.path() == store_url_loader_client_url_path_)) { + CHECK(!stored_url_loader_client_); + stored_url_loader_client_ = std::move(params->client); + report_count_++; + return true; + } + + // Not a script request or report request, so consider this an update + // request. update_count_++; EXPECT_TRUE(params->url_request.trusted_params->isolation_info .network_isolation_key() .IsTransient()); + const auto update_it = + json_update_map_.find(params->url_request.url.path()); + if (update_it != json_update_map_.end()) { + URLLoaderInterceptor::WriteResponse( + kFledgeUpdateHeaders, update_it->second, params->client.get()); + return true; + } + + if (params->url_request.url.path() == deferred_response_url_path_) { + CHECK(!deferred_response_url_loader_client_); + deferred_response_url_loader_client_ = std::move(params->client); + return true; + } + if (next_error_ != net::OK) { params->client->OnComplete( network::URLLoaderCompletionStatus(next_error_)); next_error_ = net::OK; return true; } - if (params->url_request.url.path() == deferred_response_url_path_) { - CHECK(!deferred_response_url_loader_client_); - deferred_response_url_loader_client_ = std::move(params->client); - return true; - } - const auto it = json_update_map_.find(params->url_request.url.path()); - if (it == json_update_map_.end()) - return false; - URLLoaderInterceptor::WriteResponse(kFledgeHeaders, it->second, - params->client.get()); - return true; + + return false; } - // Handles network requests for interest group updates. - URLLoaderInterceptor update_interceptor_{ - base::BindRepeating(&UpdateResponder::RequestHandlerForUpdates, + // Handles network requests for interest group updates and scripts. + URLLoaderInterceptor network_interceptor_{ + base::BindRepeating(&NetworkResponder::RequestHandler, base::Unretained(this))}; - mutable base::Lock json_update_lock_; + mutable base::Lock lock_; // For each HTTPS request, we see if any path in the map matches the request - // path. If so, the server returns the mapped value string as the response. - base::flat_map<std::string, std::string> json_update_map_ - GUARDED_BY(json_update_lock_); + // path. If so, the server returns the mapped value string as the response, + // with JSON MIME type. + base::flat_map<std::string, std::string> json_update_map_ GUARDED_BY(lock_); + + // Like `json_update_map_`, but for serving bidding / scoring scripts, with + // the Javascript MIME type. + base::flat_map<std::string, std::string> script_map_ GUARDED_BY(lock_); + + base::flat_map<std::string, std::string> report_map_ GUARDED_BY(lock_); // Stores the last URL path that was registered with - // RegisterDeferredResponse(). Empty initially and after DoDeferredResponse() - // -- when empty, no deferred response can occur. - std::string deferred_response_url_path_ GUARDED_BY(json_update_lock_); + // RegisterDeferredUpdateResponse(). Empty initially and after + // DoDeferredUpdateResponse() -- when empty, no deferred response can occur. + std::string deferred_response_url_path_ GUARDED_BY(lock_); + + // Stores the last URL path that was registered with + // RegisterStoreUrlLoaderClient(). + std::string store_url_loader_client_url_path_ GUARDED_BY(lock_); + + // Stores the Mojo URLLoaderClient remote "stolen" from RequestHandler() for + // use with deferred responses -- unbound if no remote has been "stolen" yet, + // or if the last deferred response completed. + mojo::Remote<network::mojom::URLLoaderClient> + deferred_response_url_loader_client_ GUARDED_BY(lock_); // Stores the Mojo URLLoaderClient remote "stolen" from - // RequestHandlerForUpdates() for use with deferred responses -- unbound if no - // remote has been "stolen" yet, or if the last deferred response completed. - mojo::Remote<network::mojom::URLLoaderClient> - deferred_response_url_loader_client_ GUARDED_BY(json_update_lock_); + // RequestHandlerForUpdates() for use with no responses -- unbound if no + // remote has been "stolen" yet, or if the last no response request timed out. + mojo::Remote<network::mojom::URLLoaderClient> stored_url_loader_client_ + GUARDED_BY(lock_); - net::Error next_error_ GUARDED_BY(json_update_lock_) = net::OK; + net::Error next_error_ GUARDED_BY(lock_) = net::OK; - size_t update_count_ GUARDED_BY(json_update_lock_) = 0; + size_t update_count_ GUARDED_BY(lock_) = 0; + + size_t report_count_ GUARDED_BY(lock_) = 0; +}; + +// AuctionProcessManager that allows running auctions in-proc. +class SameProcessAuctionProcessManager : public AuctionProcessManager { + public: + SameProcessAuctionProcessManager() = default; + SameProcessAuctionProcessManager(const SameProcessAuctionProcessManager&) = + delete; + SameProcessAuctionProcessManager& operator=( + const SameProcessAuctionProcessManager&) = delete; + ~SameProcessAuctionProcessManager() override = default; + + private: + void LaunchProcess( + mojo::PendingReceiver<auction_worklet::mojom::AuctionWorkletService> + auction_worklet_service_receiver, + const std::string& display_name) override { + // Create one AuctionWorkletServiceImpl per Mojo pipe, just like in + // production code. Don't bother to delete the service on pipe close, + // though; just keep it in a vector instead. + auction_worklet_services_.push_back( + std::make_unique<auction_worklet::AuctionWorkletServiceImpl>( + std::move(auction_worklet_service_receiver))); + } + + std::vector<std::unique_ptr<auction_worklet::AuctionWorkletServiceImpl>> + auction_worklet_services_; }; } // namespace @@ -212,16 +357,35 @@ manager_ = (static_cast<StoragePartitionImpl*>( browser_context()->GetDefaultStoragePartition())) ->GetInterestGroupManager(); + // Process creation crashes in the Chrome zygote init in unit tests, so run + // the auction "processes" in-process instead. + manager_->set_auction_process_manager_for_testing( + std::make_unique<SameProcessAuctionProcessManager>()); } void TearDown() override { - // `update_responder_` must be destructed while the task environment, + // `network_responder_` must be destructed while the task environment, // which gets destroyed by RenderViewHostTestHarness::TearDown(), is still // active. - update_responder_.reset(); + network_responder_.reset(); RenderViewHostTestHarness::TearDown(); } + void NavigateAndWaitForPageDestroyed(const GURL& dest_url) { + // Wait until the main render frame is deleted, which happens asynchronously + // after navigation -- the page gets destroyed with the main render frame. + // On Android, this hangs, likely due to architectural differences, so don't + // perform this wait on Android. +#if !defined(OS_ANDROID) + RenderFrameHostWrapper main_frame_wrapper(web_contents()->GetMainFrame()); + ASSERT_FALSE(main_frame_wrapper.IsDestroyed()); +#endif // !defined(OS_ANDROID) + NavigateAndCommit(dest_url); +#if !defined(OS_ANDROID) + ASSERT_TRUE(main_frame_wrapper.WaitUntilRenderFrameDeleted()); +#endif // !defined(OS_ANDROID) + } + std::vector<StorageInterestGroup> GetInterestGroupsForOwner( const url::Origin& owner) { std::vector<StorageInterestGroup> interest_groups; @@ -246,6 +410,17 @@ return 0; } + absl::optional<GURL> ConvertFencedFrameURNToURL(const GURL& urn_url) { + TestFencedFrameURLMappingResultObserver observer; + FencedFrameURLMapping& fenced_frame_urls_map = + static_cast<RenderFrameHostImpl*>(main_rfh()) + ->GetPage() + .fenced_frame_urls_map(); + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> ignored; + fenced_frame_urls_map.ConvertFencedFrameURNToURL(urn_url, &observer); + return observer.mapped_url(); + } + // Create a new AdAuctionServiceImpl and use it to try and join // `interest_group`. Flushes the Mojo pipe to force the Mojo message to be // handled before returning. @@ -303,6 +478,37 @@ interest_service->UpdateAdInterestGroups(); } + // Runs an ad auction using the config specified in `auction_config` in the + // frame `rfh`. Returns the result of the auction, which is either a URL to + // the winning ad, or absl::nullopt if no ad won the auction. + absl::optional<GURL> RunAdAuctionAndFlushForFrame( + blink::mojom::AuctionAdConfigPtr auction_config, + RenderFrameHost* rfh) { + mojo::Remote<blink::mojom::AdAuctionService> interest_service; + AdAuctionServiceImpl::CreateMojoService( + rfh, interest_service.BindNewPipeAndPassReceiver()); + + base::RunLoop run_loop; + absl::optional<GURL> maybe_url; + interest_service->RunAdAuction( + std::move(auction_config), + base::BindLambdaForTesting( + [&run_loop, &maybe_url](const absl::optional<GURL>& result) { + maybe_url = result; + run_loop.Quit(); + })); + interest_service.FlushForTesting(); + run_loop.Run(); + return maybe_url; + } + + // Like RunAdAuctionAndFlushForFrame(), but uses the render frame host of the + // main frame. + absl::optional<GURL> RunAdAuctionAndFlush( + blink::mojom::AuctionAdConfigPtr auction_config) { + return RunAdAuctionAndFlushForFrame(std::move(auction_config), main_rfh()); + } + // Like UpdateInterestGroupNoFlushForFrame, but uses the render frame host of // the main frame. void UpdateInterestGroupNoFlush() { @@ -361,8 +567,8 @@ data_decoder::test::InProcessDataDecoder in_process_data_decoder_; // Must be destroyed before RenderViewHostTestHarness::TearDown(). - std::unique_ptr<UpdateResponder> update_responder_{ - std::make_unique<UpdateResponder>()}; + std::unique_ptr<NetworkResponder> network_responder_{ + std::make_unique<NetworkResponder>()}; }; // Check basic success case. @@ -543,7 +749,7 @@ // The server JSON updates all fields that can be updated. TEST_F(AdAuctionServiceImplTest, UpdateAllUpdatableFields) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({ "biddingLogicUrl": "%s/interest_group/new_bidding_logic.js", @@ -599,13 +805,13 @@ // Only set the ads field -- the other fields shouldn't be changed. TEST_F(AdAuctionServiceImplTest, UpdatePartialPerformsMerge) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -653,13 +859,13 @@ // The update shouldn't change the expiration time of the interest group. TEST_F(AdAuctionServiceImplTest, UpdateDoesntChangeExpiration) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -700,7 +906,7 @@ // Only set the ads field -- the other fields shouldn't be changed. TEST_F(AdAuctionServiceImplTest, UpdateSucceedsIfOptionalNameOwnerMatch) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({ "name": "%s", @@ -759,14 +965,14 @@ // allowed to change. If they don't match the interest group (update URLs are // registered per interest group), fail the update and don't update anything. TEST_F(AdAuctionServiceImplTest, NoUpdateIfOptionalNameDoesntMatch) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "name": "boats", "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata":{"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -802,7 +1008,7 @@ // allowed to change. If they don't match the interest group (update URLs are // registered per interest group), fail the update and don't update anything. TEST_F(AdAuctionServiceImplTest, NoUpdateIfOptionalOwnerDoesntMatch) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({ "owner": "%s", "ads": [{"renderUrl": "%s/new_ad_render_url", @@ -850,20 +1056,20 @@ "/interest_group/daily_update_partial1.json"; constexpr char kDailyUpdateUrlPath2[] = "/interest_group/daily_update_partial2.json"; - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath1, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath1, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url1", "metadata": {"new_a": "b1"} }] })", - kOriginStringA)); - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath2, - base::StringPrintf(R"({ + kOriginStringA)); + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath2, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url2", "metadata": {"new_a": "b2"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.name = kGroupName1; @@ -932,13 +1138,13 @@ TEST_F(AdAuctionServiceImplTest, UpdateOnlyOwnOrigin) { // Both interest groups can share the same update logic and path (they just // use different origins). - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1005,13 +1211,13 @@ TEST_F(AdAuctionServiceImplTest, UpdateFromCrossSiteIFrame) { // All interest groups can share the same update logic and path (they just // use different origins). - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1127,14 +1333,14 @@ // The `ads` field is valid, but the ad `renderUrl` field is an invalid // URL. The entire update should get cancelled, since updates are atomic. TEST_F(AdAuctionServiceImplTest, UpdateInvalidFieldCancelsAllUpdates) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "biddingLogicUrl": "%s/interest_group/new_bidding_logic.js", "ads": [{"renderUrl": "https://invalid^&", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1168,8 +1374,8 @@ // The server response can't be parsed as valid JSON. The update is cancelled. TEST_F(AdAuctionServiceImplTest, UpdateInvalidJSONIgnored) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - "This isn't JSON."); + network_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, + "This isn't JSON."); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1210,13 +1416,13 @@ // The server response is valid, but we simulate the JSON parser (which may // run in a separate process) crashing, so the update doesn't happen. TEST_F(AdAuctionServiceImplTest, UpdateJSONParserCrash) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1290,7 +1496,7 @@ // The network request for updating interest groups times out, so the update // fails. TEST_F(AdAuctionServiceImplTest, UpdateTimeout) { - update_responder_->RegisterDeferredResponse(kDailyUpdateUrlPath); + network_responder_->RegisterDeferredUpdateResponse(kDailyUpdateUrlPath); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; interest_group.bidding_url = kBiddingLogicUrlA; @@ -1333,7 +1539,7 @@ "metadata": {"new_a": "b"}}] })", kOriginStringA); - update_responder_->RegisterDeferredResponse(kDailyUpdateUrlPath); + network_responder_->RegisterDeferredUpdateResponse(kDailyUpdateUrlPath); // Make the interest group expire before the DB maintenance task should be // run, with a gap second where expiration has happened, but DB maintenance @@ -1378,7 +1584,7 @@ // Now return the server response. The interest group shouldn't change as it's // expired. - update_responder_->DoDeferredResponse(kServerResponse); + network_responder_->DoDeferredUpdateResponse(kServerResponse); task_environment()->RunUntilIdle(); EXPECT_EQ(0, GetJoinCount(kOriginA, kInterestGroupName)); EXPECT_EQ(0u, GetInterestGroupsForOwner(kOriginA).size()); @@ -1388,8 +1594,8 @@ // update actually happens. task_environment()->FastForwardBy( InterestGroupStorage::kUpdateSucceededBackoffPeriod + base::Seconds(1)); - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - kServerResponse); + network_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, + kServerResponse); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); EXPECT_EQ(0, GetJoinCount(kOriginA, kInterestGroupName)); @@ -1411,7 +1617,7 @@ "metadata": {"new_a": "b"}}] })", kOriginStringA); - update_responder_->RegisterDeferredResponse(kDailyUpdateUrlPath); + network_responder_->RegisterDeferredUpdateResponse(kDailyUpdateUrlPath); // Make the interest group expire just before the DB maintenance task should // be run. Time order: @@ -1460,7 +1666,7 @@ // Now return the server response. The interest group shouldn't change as it's // expired. - update_responder_->DoDeferredResponse(kServerResponse); + network_responder_->DoDeferredUpdateResponse(kServerResponse); task_environment()->RunUntilIdle(); EXPECT_EQ(0, GetJoinCount(kOriginA, kInterestGroupName)); EXPECT_EQ(0u, GetInterestGroupsForOwner(kOriginA).size()); @@ -1470,8 +1676,8 @@ // update actually happens. task_environment()->FastForwardBy( InterestGroupStorage::kUpdateSucceededBackoffPeriod + base::Seconds(1)); - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - kServerResponse); + network_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, + kServerResponse); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); EXPECT_EQ(0, GetJoinCount(kOriginA, kInterestGroupName)); @@ -1481,13 +1687,13 @@ // The update doesn't happen because the update URL isn't specified at // Join() time. TEST_F(AdAuctionServiceImplTest, DoesntChangeGroupsWithNoUpdateUrl) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.bidding_url = kBiddingLogicUrlA; @@ -1521,13 +1727,13 @@ // Register a bid and a win, then perform a successful update. The bid and win // stats shouldn't change. TEST_F(AdAuctionServiceImplTest, UpdateDoesntChangeBrowserSignals) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); interest_group.update_url = kUpdateUrlA; @@ -1585,13 +1791,13 @@ // Advance to just before time limit drops, update does nothing (rate limited). // Advance after time limit. Update should work. TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterSuccessfulUpdate) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); // Set a long expiration delta so that we can advance to the next rate limit @@ -1621,13 +1827,13 @@ EXPECT_EQ(group.ads.value()[0].metadata, "{\"new_a\":\"b\"}"); // Change the update response and try updating again. - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/newer_ad_render_url", "metadata": {"newer_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); @@ -1689,8 +1895,8 @@ // "successful" duration), update does nothing (rate limited). // Advance after time limit. Update should work. TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterBadUpdateResponse) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - "This isn't JSON."); + network_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, + "This isn't JSON."); blink::InterestGroup interest_group = CreateInterestGroup(); // Set a long expiration delta so that we can advance to the next rate limit @@ -1721,13 +1927,13 @@ "{\"ad\":\"metadata\",\"here\":[1,2,3]}"); // Change the update response and try updating again. - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); @@ -1791,7 +1997,7 @@ // Advance to just before rate limit drops, update does nothing (rate limited). // Advance after time limit. Update should work. TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterFailedUpdate) { - update_responder_->FailNextRequestWithError(net::ERR_CONNECTION_RESET); + network_responder_->FailNextUpdateRequestWithError(net::ERR_CONNECTION_RESET); blink::InterestGroup interest_group = CreateInterestGroup(); // Set a long expiration delta so that we can advance to the next rate limit @@ -1822,13 +2028,13 @@ "{\"ad\":\"metadata\",\"here\":[1,2,3]}"); // Change the update response and try updating again. - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); @@ -1891,7 +2097,8 @@ // Change update response to different value that will succeed. // Update succeeds (not rate limited). TEST_F(AdAuctionServiceImplTest, UpdateNotRateLimitedIfDisconnected) { - update_responder_->FailNextRequestWithError(net::ERR_INTERNET_DISCONNECTED); + network_responder_->FailNextUpdateRequestWithError( + net::ERR_INTERNET_DISCONNECTED); blink::InterestGroup interest_group = CreateInterestGroup(); // Set a long expiration delta so that we can advance to the next rate limit @@ -1922,13 +2129,13 @@ "{\"ad\":\"metadata\",\"here\":[1,2,3]}"); // Change the update response and try updating again. - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); UpdateInterestGroupNoFlush(); task_environment()->RunUntilIdle(); @@ -1946,13 +2153,13 @@ // Fire off many updates rapidly in a loop. Only one update should happen. TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedTightLoop) { - update_responder_->RegisterUpdateResponse(kDailyUpdateUrlPath, - base::StringPrintf(R"({ + network_responder_->RegisterUpdateResponse( + kDailyUpdateUrlPath, base::StringPrintf(R"({ "ads": [{"renderUrl": "%s/new_ad_render_url", "metadata": {"new_a": "b"} }] })", - kOriginStringA)); + kOriginStringA)); blink::InterestGroup interest_group = CreateInterestGroup(); // Set a long expiration delta so that we can advance to the next rate limit @@ -1967,14 +2174,14 @@ JoinInterestGroupAndFlush(std::move(interest_group)); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - EXPECT_EQ(update_responder_->UpdateCount(), 0u); + EXPECT_EQ(network_responder_->UpdateCount(), 0u); for (size_t i = 0; i < 1000u; i++) { UpdateInterestGroupNoFlush(); } task_environment()->RunUntilIdle(); - EXPECT_EQ(update_responder_->UpdateCount(), 1u); + EXPECT_EQ(network_responder_->UpdateCount(), 1u); // One of the updates completes successfully. std::vector<StorageInterestGroup> groups = @@ -1988,6 +2195,422 @@ EXPECT_EQ(group.ads.value()[0].metadata, "{\"new_a\":\"b\"}"); } +// Add an interest group, and run an ad auction. +TEST_F(AdAuctionServiceImplTest, RunAdAuction) { + constexpr char kBiddingScript[] = R"( +function generateBid( + interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, + browserSignals) { + return {'ad': 'example', 'bid': 1, 'render': 'https://example.com/render'}; +} + )"; + constexpr char kDecisionScript[] = R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return bid; +} + )"; + network_responder_->RegisterScriptResponse(kBiddingUrlPath, kBiddingScript); + network_responder_->RegisterScriptResponse(kDecisionUrlPath, kDecisionScript); + blink::InterestGroup interest_group = CreateInterestGroup(); + interest_group.bidding_url = kUrlA.Resolve(kBiddingUrlPath); + interest_group.ads.emplace(); + blink::InterestGroup::Ad ad; + ad.render_url = GURL("https://example.com/render"); + interest_group.ads->push_back(std::move(ad)); + JoinInterestGroupAndFlush(std::move(interest_group)); + EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); + + auto auction_config = blink::mojom::AuctionAdConfig::New(); + auction_config->seller = kOriginA; + auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + absl::optional<GURL> auction_result = + RunAdAuctionAndFlush(std::move(auction_config)); + ASSERT_NE(auction_result, absl::nullopt); + EXPECT_EQ(ConvertFencedFrameURNToURL(*auction_result), + GURL("https://example.com/render")); +} + +TEST_F(AdAuctionServiceImplTest, FetchReport) { + const std::string kBiddingScript = base::StringPrintf(R"( +function generateBid( + interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, + browserSignals) { + return {'ad': 'example', 'bid': 1, 'render': 'https://example.com/render'}; +} +function reportWin( + auctionSignals, perBuyerSignals, sellerSignals, browserSignals) { + sendReportTo('%s/report_bidder'); +} + )", + kOriginStringA); + const std::string kDecisionScript = + base::StringPrintf(R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return bid; +} +function reportResult(auctionConfig, browserSignals) { + sendReportTo('%s/report_seller'); + return { + 'success': true, + 'signalsForWinner': {'signalForWinner': 1}, + 'reportUrl': '%s/report_seller', + }; +} + )", + kOriginStringA, kOriginStringA); + network_responder_->RegisterScriptResponse(kBiddingUrlPath, kBiddingScript); + network_responder_->RegisterScriptResponse(kDecisionUrlPath, kDecisionScript); + network_responder_->RegisterReportResponse("/report_bidder", ""); + network_responder_->RegisterStoreUrlLoaderClient("/report_seller"); + + blink::InterestGroup interest_group = CreateInterestGroup(); + interest_group.bidding_url = kUrlA.Resolve(kBiddingUrlPath); + interest_group.ads.emplace(); + blink::InterestGroup::Ad ad; + ad.render_url = GURL("https://example.com/render"); + interest_group.ads->push_back(std::move(ad)); + JoinInterestGroupAndFlush(std::move(interest_group)); + EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); + + auto auction_config = blink::mojom::AuctionAdConfig::New(); + auction_config->seller = kOriginA; + auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + absl::optional<GURL> auction_result = + RunAdAuctionAndFlush(std::move(auction_config)); + EXPECT_NE(auction_result, absl::nullopt); + + task_environment()->FastForwardBy(base::Seconds(30) - base::Seconds(1)); + // There should be two reports, one for winning bidder and one for seller. + EXPECT_EQ(network_responder_->ReportCount(), 2u); + // The request to seller report url should hang before 30s. + EXPECT_TRUE(network_responder_->RemoteIsConnected()); + task_environment()->FastForwardBy(base::Seconds(2)); + // The request to seller report url should be disconnected after 30s due to + // timeout. + EXPECT_FALSE(network_responder_->RemoteIsConnected()); +} + +// Run several auctions, some of which have a winner, and some of which do +// not. Verify that the auction result UMA is recorded correctly. +TEST_F(AdAuctionServiceImplTest, + AddInterestGroupRunAuctionVerifyResultMetrics) { + // The test assumes that the main frame RFH will be replaced during + // navigation. + DisableBackForwardCacheForTesting(web_contents(), + BackForwardCache::TEST_ASSUMES_NO_CACHING); + base::HistogramTester histogram_tester; + constexpr char kDecisionFailAllUrlPath[] = + "/interest_group/decision_logic_fail_all.js"; + constexpr char kBiddingScript[] = R"( +function generateBid( + interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, + browserSignals) { + return {'ad': 'example', 'bid': 1, 'render': 'https://example.com/render'}; +} +function reportWin() {} + )"; + constexpr char kDecisionScript[] = R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return bid; +} +function reportResult() {} + )"; + constexpr char kDecisionScriptFailAll[] = R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return 0; +} +function reportResult() {} +)"; + network_responder_->RegisterScriptResponse(kBiddingUrlPath, kBiddingScript); + network_responder_->RegisterScriptResponse(kDecisionUrlPath, kDecisionScript); + network_responder_->RegisterScriptResponse(kDecisionFailAllUrlPath, + kDecisionScriptFailAll); + blink::InterestGroup interest_group = CreateInterestGroup(); + interest_group.expiry = base::Time::Now() + base::Days(10); + interest_group.bidding_url = kUrlA.Resolve(kBiddingUrlPath); + interest_group.ads.emplace(); + blink::InterestGroup::Ad ad; + ad.render_url = GURL("https://example.com/render"); + interest_group.ads->push_back(std::move(ad)); + JoinInterestGroupAndFlush(std::move(interest_group)); + EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); + + // Run 7 auctions, with delays: + // + // succeed, (1s), fail, (3s), succeed, (1m), succeed, (10m) succeed, (30m) + // fail, (1h), fail, which in bits (with an extra leading 1) is 0b1101110 -- + // the last failure isn't recorded in the bitfield, since only the first 6 + // auctions get recorded in the bitfield. + + // Expect*TimeSample() doesn't accept base::TimeDelta::Max(), but the max time + // bucket size is 1 hour, so specifying kMaxTime will select the max bucket. + constexpr base::TimeDelta kMaxTime{base::Days(1)}; + + auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); + succeed_auction_config->seller = kOriginA; + succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + succeed_auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + + auto fail_auction_config = blink::mojom::AuctionAdConfig::New(); + fail_auction_config->seller = kOriginA; + fail_auction_config->decision_logic_url = + kUrlA.Resolve(kDecisionFailAllUrlPath); + fail_auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + fail_auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + + // 1st auction + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), + absl::nullopt); + // Time metrics are published every auction. + histogram_tester.ExpectUniqueTimeSample( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 1); + + // 2nd auction + task_environment()->FastForwardBy(base::Seconds(1)); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(1), + 1); + + // 3rd auction + task_environment()->FastForwardBy(base::Seconds(3)); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), + absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(3), + 1); + + // 4th auction + task_environment()->FastForwardBy(base::Minutes(1)); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), + absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Minutes(1), + 1); + + // 5th auction + task_environment()->FastForwardBy(base::Minutes(10)); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), + absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", + base::Minutes(10), 1); + + // 6th auction + task_environment()->FastForwardBy(base::Minutes(30)); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", + base::Minutes(30), 1); + + // 7th auction + task_environment()->FastForwardBy(base::Hours(1)); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + // Since the 1st auction has no prior auction -- it gets put in the same + // bucket with the 7th auction -- there are 2 auctions now in this bucket. + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 2); + + // Some metrics only get reported until after navigation. + EXPECT_EQ(histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.NumAuctionsPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.First6AuctionsBitsPerPage") + .size(), + 0u); + + // Navigate to populate remaining metrics. + ASSERT_NO_FATAL_FAILURE(NavigateAndWaitForPageDestroyed(kUrlB)); + + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.NumAuctionsPerPage", 7, 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage", 4 * 100 / 7, + 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.First6AuctionsBitsPerPage", 0b1101110, 1); +} + +// Like AddInterestGroupRunAuctionVerifyResultMetrics, but with a smaller number +// of auctions -- this verifies that metrics (especially the bit metrics) are +// reported correctly in this scenario. +TEST_F(AdAuctionServiceImplTest, + AddInterestGroupRunAuctionVerifyResultMetricsFewAuctions) { + // The test assumes that the main frame RFH will be replaced during + // navigation. + DisableBackForwardCacheForTesting(web_contents(), + BackForwardCache::TEST_ASSUMES_NO_CACHING); + base::HistogramTester histogram_tester; + constexpr char kDecisionFailAllUrlPath[] = + "/interest_group/decision_logic_fail_all.js"; + constexpr char kBiddingScript[] = R"( +function generateBid( + interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, + browserSignals) { + return {'ad': 'example', 'bid': 1, 'render': 'https://example.com/render'}; +} +function reportWin() {} + )"; + constexpr char kDecisionScript[] = R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return bid; +} +function reportResult() {} + )"; + constexpr char kDecisionScriptFailAll[] = R"( +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) { + return 0; +} +function reportResult() {} +)"; + network_responder_->RegisterScriptResponse(kBiddingUrlPath, kBiddingScript); + network_responder_->RegisterScriptResponse(kDecisionUrlPath, kDecisionScript); + network_responder_->RegisterScriptResponse(kDecisionFailAllUrlPath, + kDecisionScriptFailAll); + blink::InterestGroup interest_group = CreateInterestGroup(); + interest_group.expiry = base::Time::Now() + base::Days(10); + interest_group.bidding_url = kUrlA.Resolve(kBiddingUrlPath); + interest_group.ads.emplace(); + blink::InterestGroup::Ad ad; + ad.render_url = GURL("https://example.com/render"); + interest_group.ads->push_back(std::move(ad)); + JoinInterestGroupAndFlush(std::move(interest_group)); + EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); + + // Run 2 auctions, with delays: + // + // succeed, (1s), fail, which in bits (with an extra leading 1) is 0b110. + + // Expect*TimeSample() doesn't accept base::TimeDelta::Max(), but the max time + // bucket size is 1 hour, so specifying kMaxTime will select the max bucket. + constexpr base::TimeDelta kMaxTime{base::Days(1)}; + + auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); + succeed_auction_config->seller = kOriginA; + succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + succeed_auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + + auto fail_auction_config = blink::mojom::AuctionAdConfig::New(); + fail_auction_config->seller = kOriginA; + fail_auction_config->decision_logic_url = + kUrlA.Resolve(kDecisionFailAllUrlPath); + fail_auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + fail_auction_config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::NewBuyers({kOriginA}); + + // 1st auction + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), + absl::nullopt); + // Time metrics are published every auction. + histogram_tester.ExpectUniqueTimeSample( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 1); + + // 2nd auction + task_environment()->FastForwardBy(base::Seconds(1)); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + histogram_tester.ExpectTimeBucketCount( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(1), + 1); + + // Some metrics only get reported until after navigation. + EXPECT_EQ(histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.NumAuctionsPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.First6AuctionsBitsPerPage") + .size(), + 0u); + + // Navigate to populate remaining metrics. + ASSERT_NO_FATAL_FAILURE(NavigateAndWaitForPageDestroyed(kUrlB)); + + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.NumAuctionsPerPage", 2, 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage", 1 * 100 / 2, + 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.First6AuctionsBitsPerPage", 0b110, 1); +} + +// Like AddInterestGroupRunAuctionVerifyResultMetricsFewAuctions, but with no +// auctions. +TEST_F(AdAuctionServiceImplTest, + AddInterestGroupRunAuctionVerifyResultMetricsNoAuctions) { + // The test assumes that the main frame RFH will be replaced during + // navigation. + DisableBackForwardCacheForTesting(web_contents(), + BackForwardCache::TEST_ASSUMES_NO_CACHING); + base::HistogramTester histogram_tester; + + // Don't run any auctions. + + // Navigate to "populate" remaining metrics. + ASSERT_NO_FATAL_FAILURE(NavigateAndWaitForPageDestroyed(kUrlB)); + + // Nothing gets reported since there were no auctions. + EXPECT_EQ(histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.NumAuctionsPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples( + "Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage") + .size(), + 0u); + EXPECT_EQ( + histogram_tester + .GetAllSamples("Ads.InterestGroup.Auction.First6AuctionsBitsPerPage") + .size(), + 0u); + EXPECT_EQ(histogram_tester + .GetAllSamples( + "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage") + .size(), + 0u); +} + class AdAuctionServiceImplRestrictedPermissionsPolicyTest : public AdAuctionServiceImplTest { public: @@ -2007,7 +2630,7 @@ // APIs should succeed. TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest, APICallsFromTopFrame) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})", kOriginStringA, kNewBiddingUrlPath)); @@ -2037,7 +2660,7 @@ // instead of a top frame. TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest, APICallsFromSameSiteIframe) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})", kOriginStringA, kNewBiddingUrlPath)); @@ -2075,7 +2698,7 @@ // APIs should not work. TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest, APICallsFromCrossSiteIFrame) { - update_responder_->RegisterUpdateResponse( + network_responder_->RegisterUpdateResponse( kDailyUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})", kOriginStringC, kNewBiddingUrlPath)); @@ -2201,6 +2824,8 @@ // An empty config will cause FinalizeAd to fail and run the supplied callback. TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsEmptyConfig) { auto mojo_config = blink::mojom::AuctionAdConfig::New(); + mojo_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); bool callback_fired = false; FinalizeAd( @@ -2214,6 +2839,8 @@ TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsHTTPDecisionUrl) { auto mojo_config = blink::mojom::AuctionAdConfig::New(); + mojo_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); mojo_config->seller = url::Origin::Create(GURL("https://site.test")); mojo_config->decision_logic_url = GURL("http://site.test/"); @@ -2230,6 +2857,8 @@ // An empty GUID should trigger any FinalizeAd request to fail. TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsMissingGuid) { auto mojo_config = blink::mojom::AuctionAdConfig::New(); + mojo_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); mojo_config->seller = url::Origin::Create(GURL("https://site.test")); mojo_config->decision_logic_url = GURL("https://site.test/");
diff --git a/content/browser/interest_group/auction_process_manager_unittest.cc b/content/browser/interest_group/auction_process_manager_unittest.cc index 50f027e..cccd0f1 100644 --- a/content/browser/interest_group/auction_process_manager_unittest.cc +++ b/content/browser/interest_group/auction_process_manager_unittest.cc
@@ -62,6 +62,8 @@ bool should_pause_on_start, mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory, const GURL& script_source_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, LoadSellerWorkletCallback callback) override { NOTREACHED(); }
diff --git a/content/browser/interest_group/auction_runner.cc b/content/browser/interest_group/auction_runner.cc index 76430ad8..c087438 100644 --- a/content/browser/interest_group/auction_runner.cc +++ b/content/browser/interest_group/auction_runner.cc
@@ -219,7 +219,8 @@ return; } - outstanding_bids_ = bid_states_.size(); + num_bids_not_sent_to_seller_worklet_ = bid_states_.size(); + outstanding_bids_ = num_bids_not_sent_to_seller_worklet_; RequestSellerWorkletProcess(); } @@ -266,6 +267,8 @@ std::move(worklet_receiver), seller_worklet_debug_->should_pause_on_start(), std::move(url_loader_factory), seller_url, + auction_config_->trusted_scoring_signals_url, + browser_signals_->top_frame_origin, base::BindOnce(&AuctionRunner::OnSellerWorkletLoaded, base::Unretained(this))); // Fail auction if the seller worklet pipe is disconnected. @@ -303,9 +306,9 @@ &AuctionRunner::OnGenerateBidCrashed, base::Unretained(this), bid_state)); bid_state->bidder_worklet->GenerateBid( - auction_config_->auction_signals, PerBuyerSignals(bid_state), - browser_signals_->top_frame_origin, browser_signals_->seller, - auction_start_time_, + auction_config_->shareable_auction_ad_config->auction_signals, + PerBuyerSignals(bid_state), browser_signals_->top_frame_origin, + browser_signals_->seller, auction_start_time_, base::BindOnce(&AuctionRunner::OnGenerateBidComplete, base::Unretained(this), bid_state)); } @@ -323,6 +326,7 @@ auction_worklet::mojom::BidderWorkletBidPtr bid, const std::vector<std::string>& errors) { DCHECK(!state->bid_result); + DCHECK_GT(num_bids_not_sent_to_seller_worklet_, 0); DCHECK_GT(outstanding_bids_, 0); DCHECK_EQ(state->state, BidState::State::kGeneratingBid); @@ -342,6 +346,16 @@ if (!bid) { state->state = BidState::State::kScoringComplete; + --num_bids_not_sent_to_seller_worklet_; + // If this is the only bid that yet to be sent to the seller worklet, and + // the seller worklet has loaded, then need to tell the SellerWorklet that + // no more bids coming. + // + // Note that this is called even if the seller hasn't loaded yet (which is + // safe to do, but not useful). Calling unconditionally is currently needed + // for a couple unit tests to pass. + if (num_bids_not_sent_to_seller_worklet_ == 0) + seller_worklet_->SendPendingSignalsRequests(); --outstanding_bids_; MaybeCompleteAuction(); return; @@ -379,17 +393,28 @@ } void AuctionRunner::ScoreBid(BidState* state) { + DCHECK(seller_loaded_); + DCHECK_GT(num_bids_not_sent_to_seller_worklet_, 0); + DCHECK_GT(outstanding_bids_, 0); DCHECK_EQ(state->state, BidState::State::kWaitingOnSellerWorkletLoad); state->state = BidState::State::kSellerScoringBid; + seller_worklet_->ScoreAd( - state->bid_result->ad, state->bid_result->bid, auction_config_.Clone(), - browser_signals_->top_frame_origin, + state->bid_result->ad, state->bid_result->bid, + auction_config_->shareable_auction_ad_config.Clone(), state->bidder.bidding_group->group.owner, state->bid_result->render_url, state->bid_result->ad_components ? *state->bid_result->ad_components : std::vector<GURL>(), state->bid_result->bid_duration.InMilliseconds(), base::BindOnce(&AuctionRunner::OnBidScored, base::Unretained(this), state)); + + // If this was the last bid that needed to be passed to ScoreAd(), tell the + // SellerWorklet no more bids are coming, so it can send a request for any + // needed scoring signals now, if needed. + --num_bids_not_sent_to_seller_worklet_; + if (num_bids_not_sent_to_seller_worklet_ == 0) + seller_worklet_->SendPendingSignalsRequests(); } void AuctionRunner::OnBidScored(BidState* state, @@ -434,10 +459,12 @@ absl::optional<std::string> AuctionRunner::PerBuyerSignals( const BidState* state) { - if (auction_config_->per_buyer_signals.has_value()) { - auto it = auction_config_->per_buyer_signals.value().find( + const auto& per_buyer_signals = + auction_config_->shareable_auction_ad_config->per_buyer_signals; + if (per_buyer_signals.has_value()) { + auto it = per_buyer_signals.value().find( state->bidder.bidding_group->group.owner); - if (it != auction_config_->per_buyer_signals.value().end()) + if (it != per_buyer_signals.value().end()) return it->second; } return absl::nullopt; @@ -447,6 +474,10 @@ if (!AllBidsScored()) return; + // Since all bids have been scored, they also should have all been sent to the + // SellerWorklet by this point. + DCHECK_EQ(0, num_bids_not_sent_to_seller_worklet_); + // Record which interest groups bid. // // TODO(mmenke): Maybe this should be recorded at bid time, and the interest @@ -478,7 +509,7 @@ DCHECK_GT(top_bidder_->seller_score, 0); seller_worklet_->ReportResult( - auction_config_.Clone(), browser_signals_->top_frame_origin, + auction_config_->shareable_auction_ad_config.Clone(), top_bidder_->bidder.bidding_group->group.owner, top_bidder_->bid_result->render_url, top_bidder_->bid_result->bid, top_bidder_->seller_score, @@ -548,9 +579,10 @@ {top_bidder_->bidder.bidding_group->group.bidding_url->spec(), " crashed while trying to run reportWin()."}))); top_bidder_->bidder_worklet->ReportWin( - auction_config_->auction_signals, PerBuyerSignals(top_bidder_), - browser_signals_->top_frame_origin, signals_for_winner_arg, - top_bidder_->bid_result->render_url, top_bidder_->bid_result->bid, + auction_config_->shareable_auction_ad_config->auction_signals, + PerBuyerSignals(top_bidder_), browser_signals_->top_frame_origin, + signals_for_winner_arg, top_bidder_->bid_result->render_url, + top_bidder_->bid_result->bid, auction_config_->seller, base::BindOnce(&AuctionRunner::OnReportBidWinComplete, base::Unretained(this))); }
diff --git a/content/browser/interest_group/auction_runner.h b/content/browser/interest_group/auction_runner.h index c36fdee5..c225d95 100644 --- a/content/browser/interest_group/auction_runner.h +++ b/content/browser/interest_group/auction_runner.h
@@ -335,10 +335,22 @@ const url::Origin frame_origin_; RunAuctionCallback callback_; - // Number of bids which the seller has not yet scored. These bids may be - // fetching URLs, generating bids, waiting for the seller worklet to load, or - // the seller worklet may be scoring their bids. + // Number of bids that have yet to be sent to the SellerWorklet. This + // includes BidderWorklets that have not yet been loaded, those whose + // GenerateBid() method is currently being run, and those that are waiting on + // the seller worklet to load. Decremented when GenerateBid() fails to + // generate a bid, or just after invoking the SellerWorklet's ScoreAd() + // method. When this reaches 0, the SellerWorklet's + // SendPendingSignalsRequests() should be invoked, so it can send any pending + // scoring signals requests. + int num_bids_not_sent_to_seller_worklet_; + // Number of bids which the seller has not yet finished scoring. These bids + // may be fetching URLs, generating bids, waiting for the seller worklet to + // load, or the seller worklet may be scoring their bids. When this reaches 0, + // the bid with the highest score is the winner, and the auction is completed, + // apart from reporting the result. int outstanding_bids_; + // State of all loaded interest groups. std::vector<BidState> bid_states_; // The time the auction started. Use a single base time for all Worklets, to
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc index ba260c2..fac0cf0b9 100644 --- a/content/browser/interest_group/auction_runner_unittest.cc +++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -167,6 +167,8 @@ throw new Error("wrong browserSignals.renderUrl"); if (browserSignals.bid !== bid) throw new Error("wrong browserSignals.bid"); + if (browserSignals.seller != 'https://adstuff.publisher1.com') + throw new Error("wrong seller"); sendReportTo("https://buyer-reporting.example.com"); } @@ -332,6 +334,7 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const url::Origin& browser_signal_seller_origin, ReportWinCallback report_win_callback) override { // While the real BidderWorklet implementation supports multiple pending // callbacks, this class does not. @@ -460,19 +463,25 @@ MockSellerWorklet(const MockSellerWorklet&) = delete; const MockSellerWorklet& operator=(const MockSellerWorklet&) = delete; - ~MockSellerWorklet() override = default; + ~MockSellerWorklet() override { + EXPECT_EQ(expect_send_pending_signals_requests_called_, + send_pending_signals_requests_called_); + } // auction_worklet::mojom::SellerWorklet implementation: void ScoreAd(const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, + blink::mojom::ShareableAuctionAdConfigPtr shareable_config, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<GURL>& browser_signal_ad_components, uint32_t browser_signal_bidding_duration_msecs, ScoreAdCallback score_ad_callback) override { + // SendPendingSignalsRequests() should only be called once all ads are + // scored. + EXPECT_FALSE(send_pending_signals_requests_called_); + ScoreAdParams score_ad_params; score_ad_params.callback = std::move(score_ad_callback); score_ad_params.bid = bid; @@ -482,8 +491,15 @@ score_ad_run_loop_->Quit(); } - void ReportResult(blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, + void SendPendingSignalsRequests() override { + // SendPendingSignalsRequests() should only be called once by a single + // AuctionRunner. + EXPECT_FALSE(send_pending_signals_requests_called_); + + send_pending_signals_requests_called_ = true; + } + + void ReportResult(blink::mojom::ShareableAuctionAdConfigPtr shareable_config, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, @@ -503,6 +519,13 @@ // Informs the consumer that the seller worklet has successfully loaded. void CompleteLoading() { DCHECK(load_worklet_callback_); + + // If a worklet completes loading successfully, + // `send_pending_signals_requests_called_` is always called, unless the + // seller worklet crashes. This includes the case where no bidders + // successfully bid, though it's not strictly needed in that case. + expect_send_pending_signals_requests_called_ = true; + std::move(load_worklet_callback_) .Run(true /* success */, std::vector<std::string>() /* errors */); } @@ -551,6 +574,12 @@ void Flush() { receiver_.FlushForTesting(); } + // `expect_send_pending_signals_requests_called_` needs to be set to false in + // the case a SellerWorklet crash is simulated before the final bid is scored. + void set_expect_send_pending_signals_requests_called(bool value) { + expect_send_pending_signals_requests_called_ = value; + } + private: auction_worklet::mojom::AuctionWorkletService::LoadSellerWorkletCallback load_worklet_callback_; @@ -563,6 +592,9 @@ mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_; + bool expect_send_pending_signals_requests_called_ = false; + bool send_pending_signals_requests_called_ = false; + // Receiver is last so that destroying `this` while there's a pending callback // over the pipe will not DCHECK. mojo::Receiver<auction_worklet::mojom::SellerWorklet> receiver_; @@ -646,6 +678,8 @@ mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory, const GURL& script_source_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, LoadSellerWorkletCallback load_seller_worklet_callback) override { DCHECK(!seller_worklet_); @@ -744,14 +778,14 @@ receiver_set_; }; -class SameThreadAuctionProcessManager : public AuctionProcessManager { +class SameProcessAuctionProcessManager : public AuctionProcessManager { public: - SameThreadAuctionProcessManager() = default; - SameThreadAuctionProcessManager(const SameThreadAuctionProcessManager&) = + SameProcessAuctionProcessManager() = default; + SameProcessAuctionProcessManager(const SameProcessAuctionProcessManager&) = delete; - SameThreadAuctionProcessManager& operator=( - const SameThreadAuctionProcessManager&) = delete; - ~SameThreadAuctionProcessManager() override = default; + SameProcessAuctionProcessManager& operator=( + const SameProcessAuctionProcessManager&) = delete; + ~SameProcessAuctionProcessManager() override = default; // Resume all worklets paused waiting for debugger on startup. void ResumeAllPaused() { @@ -862,18 +896,23 @@ auction_config->seller = url::Origin::Create(seller_decision_logic_url); auction_config->decision_logic_url = seller_decision_logic_url; auction_config->trusted_scoring_signals_url = trusted_scoring_signals_url_; + auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); // This is ignored by AuctionRunner, in favor of its `filtered_buyers` // parameter. - auction_config->interest_group_buyers = + auction_config->shareable_auction_ad_config->interest_group_buyers = blink::mojom::InterestGroupBuyers::NewAllBuyers( blink::mojom::AllBuyers::New()); - auction_config->auction_signals = auction_signals_json; - auction_config->seller_signals = R"({"isSellerSignals": true})"; + auction_config->shareable_auction_ad_config->auction_signals = + auction_signals_json; + auction_config->shareable_auction_ad_config->seller_signals = + R"({"isSellerSignals": true})"; base::flat_map<url::Origin, std::string> per_buyer_signals; per_buyer_signals[kBidder1] = R"({"signalsFor": ")" + kBidder1Name + "\"}"; per_buyer_signals[kBidder2] = R"({"signalsFor": ")" + kBidder2Name + "\"}"; - auction_config->per_buyer_signals = std::move(per_buyer_signals); + auction_config->shareable_auction_ad_config->per_buyer_signals = + std::move(per_buyer_signals); interest_group_manager_ = std::make_unique<InterestGroupManager>( base::FilePath(), true /* in_memory */, @@ -883,7 +922,7 @@ std::move(auction_process_manager_)); } else { interest_group_manager_->set_auction_process_manager_for_testing( - std::make_unique<SameThreadAuctionProcessManager>()); + std::make_unique<SameProcessAuctionProcessManager>()); } histogram_tester_ = std::make_unique<base::HistogramTester>(); @@ -1167,9 +1206,9 @@ // This is used (and consumed) when starting an auction, if non-null. Allows // either using a MockAuctionProcessManager instead of a - // SameThreadAuctionProcessManager, or using a SameThreadAuctionProcessManager + // SameProcessAuctionProcessManager, or using a SameProcessAuctionProcessManager // that has already vended processes. If nullptr, a new - // SameThreadAuctionProcessManager() is created when an auction is started. + // SameProcessAuctionProcessManager() is created when an auction is started. std::unique_ptr<AuctionProcessManager> auction_process_manager_; // Set by UseMockWorkletService(). Non-owning reference to the @@ -1508,10 +1547,10 @@ TEST_F(AuctionRunnerTest, PauseBidder) { pause_worklet_url_ = kBidder2Url; - // Save a pointer to SameThreadAuctionProcessManager since we'll need its help + // Save a pointer to SameProcessAuctionProcessManager since we'll need its help // to resume things. - auto process_manager = std::make_unique<SameThreadAuctionProcessManager>(); - SameThreadAuctionProcessManager* process_manager_impl = process_manager.get(); + auto process_manager = std::make_unique<SameProcessAuctionProcessManager>(); + SameProcessAuctionProcessManager* process_manager_impl = process_manager.get(); auction_process_manager_ = std::move(process_manager); // Have a 404 for script 2 until ready to resume. @@ -1561,10 +1600,10 @@ TEST_F(AuctionRunnerTest, PauseSeller) { pause_worklet_url_ = kSellerUrl; - // Save a pointer to SameThreadAuctionProcessManager since we'll need its help + // Save a pointer to SameProcessAuctionProcessManager since we'll need its help // to resume things. - auto process_manager = std::make_unique<SameThreadAuctionProcessManager>(); - SameThreadAuctionProcessManager* process_manager_impl = process_manager.get(); + auto process_manager = std::make_unique<SameProcessAuctionProcessManager>(); + SameProcessAuctionProcessManager* process_manager_impl = process_manager.get(); auction_process_manager_ = std::move(process_manager); // Have a 404 for seller until ready to resume. @@ -2187,21 +2226,18 @@ } )") + kReportResultScript); - // Only accept first bidder's bid. + // Only accept first bidder's bid. Requests will always be batched non-racily, + // since a mock time is in use. auction_worklet::AddJsonResponse( &url_loader_factory_, GURL(trusted_scoring_signals_url_->spec() + "?hostname=publisher1.com" - "&renderUrls=https%3A%2F%2Fad1.com%2F" - "&adComponentRenderUrls=https%3A%2F%2Fad1.com-component1.com%2F"), - R"({"renderUrls":{"https://ad1.com/":"accept"}})"); - auction_worklet::AddJsonResponse( - &url_loader_factory_, - GURL(trusted_scoring_signals_url_->spec() + - "?hostname=publisher1.com" - "&renderUrls=https%3A%2F%2Fad2.com%2F" - "&adComponentRenderUrls=https%3A%2F%2Fad2.com-component1.com%2F"), - R"({"renderUrls":{"https://ad2.com/":"reject"}})"); + "&renderUrls=https%3A%2F%2Fad1.com%2F,https%3A%2F%2Fad2.com%2F" + "&adComponentRenderUrls=https%3A%2F%2Fad1.com-component1.com%2F," + "https%3A%2F%2Fad2.com-component1.com%2F"), + R"( +{"renderUrls":{"https://ad1.com/":"accept", "https://ad2.com/":"reject"}} + )"); RunStandardAuction(); EXPECT_EQ(GURL("https://ad1.com/"), result_.ad_url); @@ -2246,7 +2282,7 @@ // Create AuctionProcessManager in advance of starting the auction so can // create seller worklets before the auction starts. auction_process_manager_ = - std::make_unique<SameThreadAuctionProcessManager>(); + std::make_unique<SameProcessAuctionProcessManager>(); AuctionProcessManager* auction_process_manager = auction_process_manager_.get();
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index c2b51de..6457be3 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -43,6 +43,7 @@ #include "content/public/test/url_loader_monitor.h" #include "content/shell/browser/shell.h" #include "content/test/test_content_browser_client.h" +#include "content/test/test_fenced_frame_url_mapping_result_observer.h" #include "net/base/isolation_info.h" #include "net/base/network_isolation_key.h" #include "net/dns/mock_host_resolver.h" @@ -462,9 +463,11 @@ GURL urn_url = GURL(result.ExtractString()); EXPECT_TRUE(urn_url.is_valid()); EXPECT_EQ(url::kUrnScheme, urn_url.scheme_piece()); - absl::optional<GURL> maybe_url = ConvertFencedFrameURNToURL(urn_url); - EXPECT_TRUE(maybe_url) << urn_url; - return maybe_url->spec(); + + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL(urn_url, &observer); + EXPECT_TRUE(observer.mapped_url()) << urn_url; + return observer.mapped_url()->spec(); } // Navigates an iframe with the id="test_iframe" to the provided URL and @@ -494,10 +497,13 @@ GURL urn_url = GURL(result.ExtractString()); EXPECT_TRUE(urn_url.is_valid()); EXPECT_EQ(url::kUrnScheme, urn_url.scheme_piece()); - absl::optional<GURL> maybe_url = ConvertFencedFrameURNToURL(urn_url); - EXPECT_TRUE(maybe_url) << urn_url; + + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL(urn_url, &observer); + EXPECT_TRUE(observer.mapped_url()) << urn_url; + NavigateIframeAndCheckURL(web_contents(), urn_url, expected_url); - EXPECT_EQ(expected_url, maybe_url); + EXPECT_EQ(expected_url, observer.mapped_url()); } // If `execution_target` is non-null, uses it as the target. Otherwise, uses @@ -691,18 +697,18 @@ feature.c_str(), api.c_str()); } - absl::optional<GURL> ConvertFencedFrameURNToURL( + void ConvertFencedFrameURNToURL( const GURL& urn_url, + TestFencedFrameURLMappingResultObserver* observer, const absl::optional<ToRenderFrameHost> execution_target = absl::nullopt) { ToRenderFrameHost adapter(execution_target ? *execution_target : shell()); - const FencedFrameURLMapping& fenced_frame_urls_map = + FencedFrameURLMapping& fenced_frame_urls_map = static_cast<RenderFrameHostImpl*>(adapter.render_frame_host()) ->GetPage() .fenced_frame_urls_map(); absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> ignored; - return fenced_frame_urls_map.ConvertFencedFrameURNToURL( - const_cast<GURL&>(urn_url), ignored); + fenced_frame_urls_map.ConvertFencedFrameURNToURL(urn_url, observer); } WebContentsImpl* web_contents() const { @@ -975,9 +981,11 @@ EXPECT_NE((*all_component_urls)[i], (*all_component_urls)[j]); // Check URNs are mapped to the values in `expected_ad_component_urls`. - absl::optional<GURL> mapped_url = ConvertFencedFrameURNToURL( - (*all_component_urls)[i], render_frame_host); - EXPECT_EQ(expected_ad_component_urls[i], mapped_url); + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL((*all_component_urls)[i], &observer, + render_frame_host); + EXPECT_TRUE(observer.mapped_url()); + EXPECT_EQ(expected_ad_component_urls[i], observer.mapped_url()); } // Make sure smaller values passed to GetAdAuctionComponentsInJS() return @@ -3137,12 +3145,12 @@ NavigateToURL(shell(), https_server_->GetURL(kTopFrameHost, "/echo"))); GURL seller_script_url = https_server_->GetURL( kSellerHost, "/interest_group/decision_argument_validator.js"); - EXPECT_EQ( - "https://example.com/render", - ConvertFencedFrameURNToURL( - GURL(EvalJs(shell(), - JsReplace( - R"( + + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL( + GURL(EvalJs(shell(), + JsReplace( + R"( (async function() { return await navigator.runAdAuction({ seller: $1, @@ -3154,14 +3162,14 @@ perBuyerSignals: {$4: {signalsForBuyer: 1}, $5: {signalsForBuyer: 2}} }); })())", - url::Origin::Create(seller_script_url), - seller_script_url, - https_server_->GetURL( - kSellerHost, - "/interest_group/trusted_scoring_signals.json"), - bidder_origin, second_bidder_origin)) - .ExtractString())) - ->spec()); + url::Origin::Create(seller_script_url), seller_script_url, + https_server_->GetURL( + kSellerHost, + "/interest_group/trusted_scoring_signals.json"), + bidder_origin, second_bidder_origin)) + .ExtractString()), + &observer); + EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); } IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, @@ -3333,10 +3341,11 @@ https_server_->GetURL("a.test", kTrustedBiddingSignalsPath), https_server_->GetURL("a.test", kBiddingLogicPath)))); - EXPECT_EQ("https://example.com/render", - ConvertFencedFrameURNToURL( - GURL(EvalJs(shell(), JsReplace( - R"( + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL( + GURL(EvalJs(shell(), + JsReplace( + R"( (async function() { return await navigator.runAdAuction({ seller: $1, @@ -3347,11 +3356,12 @@ perBuyerSignals: {$1: 5} }); })())", - test_origin, - https_server_->GetURL( - "a.test", kDecisionLogicPath))) - .ExtractString())) - ->spec()); + test_origin, + https_server_->GetURL("a.test", kDecisionLogicPath))) + .ExtractString()), + &observer); + + EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); } // Make sure that qutting with a live auction doesn't crash. @@ -3543,8 +3553,12 @@ base::RunLoop run_loop; + auto auction_config = blink::mojom::AuctionAdConfig::New(); + auction_config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + auction_service->RunAdAuction( - blink::mojom::AuctionAdConfig::New(), + std::move(auction_config), base::BindLambdaForTesting([&run_loop](const absl::optional<GURL>& url) { EXPECT_THAT(url, Eq(absl::nullopt)); run_loop.Quit(); @@ -3612,10 +3626,12 @@ })); run_loop.Run(); if (maybe_url) { - absl::optional<GURL> decoded_URL = ConvertFencedFrameURNToURL(*maybe_url); + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL(*maybe_url, &observer); + EXPECT_TRUE(observer.mapped_url()); NavigateIframeAndCheckURL(web_contents(), *maybe_url, - decoded_URL.value_or(GURL())); - return decoded_URL; + *observer.mapped_url()); + return *observer.mapped_url(); } return absl::nullopt; } @@ -3635,8 +3651,12 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Optional(Eq(ad_url_))); } @@ -3652,8 +3672,12 @@ config->decision_logic_url = embedded_test_server()->GetURL( "b.test", "/interest_group/decision_logic.js"); ASSERT_TRUE(config->decision_logic_url.SchemeIs(url::kHttpScheme)); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); } @@ -3665,8 +3689,12 @@ config->seller = test_origin_a_; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); } @@ -3688,8 +3716,12 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_http}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_http}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); } @@ -3712,8 +3744,11 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers( + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( {test_origin_a_, test_origin_a_http}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); @@ -3737,8 +3772,12 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_, test_origin_c}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_, test_origin_c}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Optional(Eq(ad_url_))); } @@ -3754,8 +3793,12 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_all_buyers(blink::mojom::AllBuyers::New()); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_all_buyers( + blink::mojom::AllBuyers::New()); // All buyers isn't supported. EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); @@ -3774,11 +3817,15 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); - config->per_buyer_signals.emplace(); - config->per_buyer_signals.value()[test_origin_a_] = - "{\"even\": \"more\", \"x\": 4.5}"; + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); + config->shareable_auction_ad_config->per_buyer_signals.emplace(); + config->shareable_auction_ad_config->per_buyer_signals + .value()[test_origin_a_] = "{\"even\": \"more\", \"x\": 4.5}"; EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Optional(Eq(ad_url_))); } @@ -3796,12 +3843,16 @@ config->seller = test_origin_b; config->decision_logic_url = https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); - config->per_buyer_signals.emplace(); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); + config->shareable_auction_ad_config->per_buyer_signals.emplace(); // `test_origin_b` isn't in `interest_group_buyers`. - config->per_buyer_signals.value()[test_origin_b] = - "{\"even\": \"more\", \"x\": 4.5}"; + config->shareable_auction_ad_config->per_buyer_signals + .value()[test_origin_b] = "{\"even\": \"more\", \"x\": 4.5}"; EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); } @@ -3819,8 +3870,12 @@ https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); config->trusted_scoring_signals_url = https_server_->GetURL( "not-b.test", "/interest_group/trusted_scoring_signals.json"); - config->interest_group_buyers = blink::mojom::InterestGroupBuyers::New(); - config->interest_group_buyers->set_buyers({test_origin_a_}); + config->shareable_auction_ad_config = + blink::mojom::ShareableAuctionAdConfig::New(); + config->shareable_auction_ad_config->interest_group_buyers = + blink::mojom::InterestGroupBuyers::New(); + config->shareable_auction_ad_config->interest_group_buyers->set_buyers( + {test_origin_a_}); EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); }
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index c3de66fa..a809a0c3 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -313,13 +313,7 @@ // Ensure that Mime sniffing works. options |= network::mojom::kURLLoadOptionSniffMimeType; - if (is_in_fenced_frame_tree) { - // Fenced frames cannot have any credentialed requests. - // TODO(https://crbug.com/1229638): Once cookies partitioning is in place, - // consider using a unique partition for those cookies instead of blocking. - // For unpartitioned cookies though, we will continue to block them. - options |= network::mojom::kURLLoadOptionBlockAllCookies; - } else if (is_main_frame) { + if (is_main_frame && !is_in_fenced_frame_tree) { // SSLInfo is not needed on subframe or fenced frame responses because users // can inspect only the certificate for the main frame when using the info // bubble.
diff --git a/content/browser/loader/prefetch_url_loader_service.cc b/content/browser/loader/prefetch_url_loader_service.cc index fe176dc..f2e9ef2 100644 --- a/content/browser/loader/prefetch_url_loader_service.cc +++ b/content/browser/loader/prefetch_url_loader_service.cc
@@ -202,29 +202,25 @@ ->prefetched_signed_exchange_cache; } - // For now we make self owned receiver for the loader to the request, while we - // can also possibly make the new loader owned by the factory so that they can - // live longer than the client (i.e. run in detached mode). - // TODO(kinuko): Revisit this. - mojo::MakeSelfOwnedReceiver( - std::make_unique<PrefetchURLLoader>( - request_id, options, current_context.frame_tree_node_id, - resource_request, - resource_request.trusted_params - ? resource_request.trusted_params->isolation_info - .network_isolation_key() - : current_context.render_frame_host->GetNetworkIsolationKey(), - std::move(client), traffic_annotation, - std::move(network_loader_factory_to_use), - base::BindRepeating( - &PrefetchURLLoaderService::CreateURLLoaderThrottles, this, - resource_request, current_context.frame_tree_node_id), - browser_context_, signed_exchange_prefetch_metric_recorder_, - std::move(prefetched_signed_exchange_cache), accept_langs_, - base::BindOnce( - &PrefetchURLLoaderService::GenerateRecursivePrefetchToken, this, - current_context.weak_ptr_factory.GetWeakPtr())), - std::move(receiver)); + // base::Unretained is safe here since |this| owns the loader. + auto loader = std::make_unique<PrefetchURLLoader>( + request_id, options, current_context.frame_tree_node_id, resource_request, + resource_request.trusted_params + ? resource_request.trusted_params->isolation_info + .network_isolation_key() + : current_context.render_frame_host->GetNetworkIsolationKey(), + std::move(client), traffic_annotation, + std::move(network_loader_factory_to_use), + base::BindRepeating(&PrefetchURLLoaderService::CreateURLLoaderThrottles, + base::Unretained(this), resource_request, + current_context.frame_tree_node_id), + browser_context_, signed_exchange_prefetch_metric_recorder_, + std::move(prefetched_signed_exchange_cache), accept_langs_, + base::BindOnce(&PrefetchURLLoaderService::GenerateRecursivePrefetchToken, + base::Unretained(this), + current_context.weak_ptr_factory.GetWeakPtr())); + auto* raw_loader = loader.get(); + prefetch_receivers_.Add(raw_loader, std::move(receiver), std::move(loader)); } PrefetchURLLoaderService::~PrefetchURLLoaderService() = default;
diff --git a/content/browser/loader/prefetch_url_loader_service.h b/content/browser/loader/prefetch_url_loader_service.h index 58492ea..95c7eae 100644 --- a/content/browser/loader/prefetch_url_loader_service.h +++ b/content/browser/loader/prefetch_url_loader_service.h
@@ -34,13 +34,11 @@ // prefetches. The renderer uses it for prefetch requests including <link // rel="prefetch">. class PrefetchURLLoaderService final - : public base::RefCountedThreadSafe< - PrefetchURLLoaderService, - content::BrowserThread::DeleteOnUIThread>, - public blink::mojom::RendererPreferenceWatcher, + : public blink::mojom::RendererPreferenceWatcher, public network::mojom::URLLoaderFactory { public: explicit PrefetchURLLoaderService(BrowserContext* browser_context); + ~PrefetchURLLoaderService() override; PrefetchURLLoaderService(const PrefetchURLLoaderService&) = delete; PrefetchURLLoaderService& operator=(const PrefetchURLLoaderService&) = delete; @@ -69,12 +67,8 @@ } private: - friend class base::DeleteHelper<content::PrefetchURLLoaderService>; - friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; struct BindContext; - ~PrefetchURLLoaderService() override; - // network::mojom::URLLoaderFactory: void CreateLoaderAndStart( mojo::PendingReceiver<network::mojom::URLLoader> receiver, @@ -116,6 +110,9 @@ mojo::ReceiverSet<network::mojom::URLLoaderFactory, std::unique_ptr<BindContext>> loader_factory_receivers_; + mojo::ReceiverSet<network::mojom::URLLoader, + std::unique_ptr<network::mojom::URLLoader>> + prefetch_receivers_; // Used in the IO thread. mojo::Receiver<blink::mojom::RendererPreferenceWatcher> preference_watcher_receiver_{this};
diff --git a/content/browser/locks/lock_manager.cc b/content/browser/locks/lock_manager.cc index 7c544f0..047135f 100644 --- a/content/browser/locks/lock_manager.cc +++ b/content/browser/locks/lock_manager.cc
@@ -317,8 +317,6 @@ LockManager::ReceiverState::~ReceiverState() = default; void LockManager::BindReceiver( - int render_process_id, - int render_frame_id, storage::BucketId bucket_id, mojo::PendingReceiver<blink::mojom::LockManager> receiver) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/browser/locks/lock_manager.h b/content/browser/locks/lock_manager.h index 20b857e..07f98cd 100644 --- a/content/browser/locks/lock_manager.h +++ b/content/browser/locks/lock_manager.h
@@ -34,11 +34,8 @@ LockManager& operator=(const LockManager&) = delete; // Binds |receiver| to this LockManager. |receiver| belongs to a frame or - // worker at |bucket_id| hosted by |render_process_id|. If it belongs to a - // frame, |render_frame_id| identifies it, otherwise it is MSG_ROUTING_NONE. - void BindReceiver(int render_process_id, - int render_frame_id, - storage::BucketId bucket_id, + // worker at |bucket_id|. + void BindReceiver(storage::BucketId bucket_id, mojo::PendingReceiver<blink::mojom::LockManager> receiver); // Request a lock. When the lock is acquired, |callback| will be invoked with
diff --git a/content/browser/locks/lock_manager_unittest.cc b/content/browser/locks/lock_manager_unittest.cc index 1492566..3d7ed9e 100644 --- a/content/browser/locks/lock_manager_unittest.cc +++ b/content/browser/locks/lock_manager_unittest.cc
@@ -21,12 +21,9 @@ void SetUp() override { pending_receiver_ = pending_remote_.InitWithNewPipeAndPassReceiver(); - int render_process_id = 2; - int render_frame_id = 5; storage::BucketId bucket_id = storage::BucketId(); // Invalid BucketId. - lock_manager_.BindReceiver(render_process_id, render_frame_id, bucket_id, - std::move(pending_receiver_)); + lock_manager_.BindReceiver(bucket_id, std::move(pending_receiver_)); remote_.Bind(std::move(pending_remote_)); }
diff --git a/content/browser/media/cdm_storage_impl_unittest.cc b/content/browser/media/cdm_storage_impl_unittest.cc index 610bdb6..99f95f2 100644 --- a/content/browser/media/cdm_storage_impl_unittest.cc +++ b/content/browser/media/cdm_storage_impl_unittest.cc
@@ -11,6 +11,7 @@ #include "base/files/file.h" #include "base/logging.h" #include "base/run_loop.h" +#include "base/test/test_future.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/navigation_simulator.h" @@ -96,27 +97,43 @@ // Open the file |name|. Returns true if the file returned is valid, false // otherwise. On success |cdm_file| is bound to the CdmFileImpl object. bool Open(const std::string& name, - mojo::AssociatedRemote<CdmFile>* cdm_file) { + mojo::AssociatedRemote<CdmFile>& cdm_file) { DVLOG(3) << __func__; - CdmStorage::Status status; - cdm_storage_->Open( - name, base::BindOnce(&CdmStorageTest::OpenDone, base::Unretained(this), - &status, cdm_file)); - RunAndWaitForResult(1); + base::test::TestFuture<CdmStorage::Status, + mojo::PendingAssociatedRemote<CdmFile>> + future; + cdm_storage_->Open(name, future.GetCallback()); + + CdmStorage::Status status = future.Get<0>(); + mojo::PendingAssociatedRemote<CdmFile> actual_file = + std::move(std::get<1>(future.Take())); + if (!actual_file) { + DCHECK_NE(status, CdmStorage::Status::kSuccess); + return false; + } + + // Open() returns a mojo::PendingAssociatedRemote<CdmFile>, so bind it to + // the mojo::AssociatedRemote<CdmFileAssociated> provided. + mojo::AssociatedRemote<CdmFile> cdm_file_remote; + cdm_file_remote.Bind(std::move(actual_file)); + cdm_file = std::move(cdm_file_remote); + return status == CdmStorage::Status::kSuccess; } // Reads the contents of the previously opened |cdm_file|. If successful, // true is returned and |data| is updated with the contents of the file. // If unable to read the file, false is returned. - bool Read(CdmFile* cdm_file, std::vector<uint8_t>* data) { + bool Read(CdmFile* cdm_file, std::vector<uint8_t>& data) { DVLOG(3) << __func__; - CdmFile::Status status; - cdm_file->Read(base::BindOnce(&CdmStorageTest::FileRead, - base::Unretained(this), &status, data)); - RunAndWaitForResult(1); + base::test::TestFuture<CdmFile::Status, std::vector<uint8_t>> future; + cdm_file->Read( + future.GetCallback<CdmFile::Status, const std::vector<uint8_t>&>()); + + CdmFile::Status status = future.Get<0>(); + data = future.Get<1>(); return status == CdmFile::Status::kSuccess; } @@ -142,10 +159,10 @@ bool Write(CdmFile* cdm_file, const std::vector<uint8_t>& data) { DVLOG(3) << __func__; - CdmFile::Status status; - cdm_file->Write(data, base::BindOnce(&CdmStorageTest::FileWritten, - base::Unretained(this), &status)); - RunAndWaitForResult(1); + base::test::TestFuture<CdmFile::Status> future; + cdm_file->Write(data, future.GetCallback()); + + CdmFile::Status status = future.Get(); return status == CdmFile::Status::kSuccess; } @@ -165,25 +182,6 @@ } private: - void OpenDone(CdmStorage::Status* status, - mojo::AssociatedRemote<CdmFile>* cdm_file, - CdmStorage::Status actual_status, - mojo::PendingAssociatedRemote<CdmFile> actual_cdm_file) { - DVLOG(3) << __func__; - *status = actual_status; - - if (!actual_cdm_file) { - run_loop_with_count_->Quit(); - return; - } - // Open() returns a mojo::PendingAssociatedRemote<CdmFile>, so bind it to - // the mojo::AssociatedRemote<CdmFileAssociated> provided. - mojo::AssociatedRemote<CdmFile> cdm_file_remote; - cdm_file_remote.Bind(std::move(actual_cdm_file)); - *cdm_file = std::move(cdm_file_remote); - run_loop_with_count_->Quit(); - } - void FileRead(CdmFile::Status* status, std::vector<uint8_t>* data, CdmFile::Status actual_status, @@ -216,21 +214,21 @@ // Unicode character to the name. const char kFileName[] = "openfile\u1234"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_FALSE(Open(kFileName, &cdm_file)); + EXPECT_FALSE(Open(kFileName, cdm_file)); EXPECT_FALSE(cdm_file.is_bound()); } TEST_F(CdmStorageTest, InvalidFileNameEmpty) { const char kFileName[] = ""; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_FALSE(Open(kFileName, &cdm_file)); + EXPECT_FALSE(Open(kFileName, cdm_file)); EXPECT_FALSE(cdm_file.is_bound()); } TEST_F(CdmStorageTest, InvalidFileNameStartWithUnderscore) { const char kFileName[] = "_invalid"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_FALSE(Open(kFileName, &cdm_file)); + EXPECT_FALSE(Open(kFileName, cdm_file)); EXPECT_FALSE(cdm_file.is_bound()); } @@ -238,57 +236,57 @@ // Limit is 256 characters, so try a file name with 257. const std::string kFileName(257, 'a'); mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_FALSE(Open(kFileName, &cdm_file)); + EXPECT_FALSE(Open(kFileName, cdm_file)); EXPECT_FALSE(cdm_file.is_bound()); } TEST_F(CdmStorageTest, OpenFile) { const char kFileName[] = "test_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_TRUE(Open(kFileName, &cdm_file)); + EXPECT_TRUE(Open(kFileName, cdm_file)); EXPECT_TRUE(cdm_file.is_bound()); } TEST_F(CdmStorageTest, OpenFileLocked) { const char kFileName[] = "test_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file1; - EXPECT_TRUE(Open(kFileName, &cdm_file1)); + EXPECT_TRUE(Open(kFileName, cdm_file1)); EXPECT_TRUE(cdm_file1.is_bound()); // Second attempt on the same file should fail as the file is locked. mojo::AssociatedRemote<CdmFile> cdm_file2; - EXPECT_FALSE(Open(kFileName, &cdm_file2)); + EXPECT_FALSE(Open(kFileName, cdm_file2)); EXPECT_FALSE(cdm_file2.is_bound()); // Now close the first file and try again. It should be free now. cdm_file1.reset(); mojo::AssociatedRemote<CdmFile> cdm_file3; - EXPECT_TRUE(Open(kFileName, &cdm_file3)); + EXPECT_TRUE(Open(kFileName, cdm_file3)); EXPECT_TRUE(cdm_file3.is_bound()); } TEST_F(CdmStorageTest, MultipleFiles) { const char kFileName1[] = "file1"; mojo::AssociatedRemote<CdmFile> cdm_file1; - EXPECT_TRUE(Open(kFileName1, &cdm_file1)); + EXPECT_TRUE(Open(kFileName1, cdm_file1)); EXPECT_TRUE(cdm_file1.is_bound()); const char kFileName2[] = "file2"; mojo::AssociatedRemote<CdmFile> cdm_file2; - EXPECT_TRUE(Open(kFileName2, &cdm_file2)); + EXPECT_TRUE(Open(kFileName2, cdm_file2)); EXPECT_TRUE(cdm_file2.is_bound()); const char kFileName3[] = "file3"; mojo::AssociatedRemote<CdmFile> cdm_file3; - EXPECT_TRUE(Open(kFileName3, &cdm_file3)); + EXPECT_TRUE(Open(kFileName3, cdm_file3)); EXPECT_TRUE(cdm_file3.is_bound()); } TEST_F(CdmStorageTest, WriteThenReadFile) { const char kFileName[] = "test_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_TRUE(Open(kFileName, &cdm_file)); + EXPECT_TRUE(Open(kFileName, cdm_file)); EXPECT_TRUE(cdm_file.is_bound()); // Write several bytes and read them back. @@ -296,33 +294,33 @@ EXPECT_TRUE(Write(cdm_file.get(), kTestData)); std::vector<uint8_t> data_read; - EXPECT_TRUE(Read(cdm_file.get(), &data_read)); + EXPECT_TRUE(Read(cdm_file.get(), data_read)); EXPECT_EQ(kTestData, data_read); } TEST_F(CdmStorageTest, ReadThenWriteEmptyFile) { const char kFileName[] = "empty_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_TRUE(Open(kFileName, &cdm_file)); + EXPECT_TRUE(Open(kFileName, cdm_file)); EXPECT_TRUE(cdm_file.is_bound()); // New file should be empty. std::vector<uint8_t> data_read; - EXPECT_TRUE(Read(cdm_file.get(), &data_read)); + EXPECT_TRUE(Read(cdm_file.get(), data_read)); EXPECT_EQ(0u, data_read.size()); // Write nothing. EXPECT_TRUE(Write(cdm_file.get(), std::vector<uint8_t>())); // Should still be empty. - EXPECT_TRUE(Read(cdm_file.get(), &data_read)); + EXPECT_TRUE(Read(cdm_file.get(), data_read)); EXPECT_EQ(0u, data_read.size()); } TEST_F(CdmStorageTest, ParallelRead) { const char kFileName[] = "duplicate_read_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_TRUE(Open(kFileName, &cdm_file)); + EXPECT_TRUE(Open(kFileName, cdm_file)); EXPECT_TRUE(cdm_file.is_bound()); CdmFile::Status status1; @@ -339,7 +337,7 @@ TEST_F(CdmStorageTest, ParallelWrite) { const char kFileName[] = "duplicate_write_file_name"; mojo::AssociatedRemote<CdmFile> cdm_file; - EXPECT_TRUE(Open(kFileName, &cdm_file)); + EXPECT_TRUE(Open(kFileName, cdm_file)); EXPECT_TRUE(cdm_file.is_bound()); CdmFile::Status status1;
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc index 1679085..5a737d91 100644 --- a/content/browser/network_service_client.cc +++ b/content/browser/network_service_client.cc
@@ -201,10 +201,12 @@ auth_challenge_responder_remote->OnAuthCredentials(absl::nullopt); } -void NetworkServiceClient::OnClearSiteData(const GURL& url, - const std::string& header_value, - int load_flags, - OnClearSiteDataCallback callback) { +void NetworkServiceClient::OnClearSiteData( + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) { std::move(callback).Run(); }
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h index 5390a05..7c94ff78 100644 --- a/content/browser/network_service_client.h +++ b/content/browser/network_service_client.h
@@ -100,10 +100,12 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnClearSiteData(const GURL& url, - const std::string& header_value, - int load_flags, - OnClearSiteDataCallback callback) override; + void OnClearSiteData( + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) override; void OnLoadingStateUpdate(network::mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) override; void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash,
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index d4573419..701da2f 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -3535,12 +3535,12 @@ EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl); } -// Test that WebContentsObserver::DocumentOnLoadCompletedInMainFrame is not -// invoked when the page gets loaded while prerendering but it is deferred and -// invoked on prerender activation. +// Test that WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame is +// not invoked when the page gets loaded while prerendering but it is deferred +// and invoked on prerender activation. IN_PROC_BROWSER_TEST_F( PrerenderBrowserTest, - DocumentOnLoadCompletedInMainFrameInvokedAfterActivation) { + DocumentOnLoadCompletedInPrimaryMainFrameInvokedAfterActivation) { const GURL kInitialUrl = GetUrl("/empty.html"); const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html"); @@ -3548,10 +3548,10 @@ ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); // Initialize a MockWebContentsObserver and ensure that - // DocumentOnLoadCompletedInMainFrame is not invoked while prerendering. + // DocumentOnLoadCompletedInPrimaryMainFrame is not invoked while + // prerendering. testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents()); - EXPECT_CALL(observer, DocumentOnLoadCompletedInMainFrame(testing::_)) - .Times(0); + EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(0); // Start a prerender. int prerender_host_id = AddPrerender(kPrerenderingUrl); @@ -3566,15 +3566,13 @@ testing::InSequence s; // Activate the prerendered page. This should result in invoking - // DocumentOnLoadCompletedInMainFrame only for main RenderFrameHost. + // DocumentOnLoadCompletedInPrimaryMainFrame only for main RenderFrameHost. { // Verify that DidFinishNavigation is invoked before - // DocumentOnLoadCompletedInMainFrame on activation. + // DocumentOnLoadCompletedInPrimaryMainFrame on activation. EXPECT_CALL(observer, DidFinishNavigation(testing::_)); - EXPECT_CALL(observer, - DocumentOnLoadCompletedInMainFrame(prerender_frame_host)) - .Times(1); + EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(1); } NavigatePrimaryPage(kPrerenderingUrl); EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl); @@ -3611,7 +3609,7 @@ testing::InSequence s; // Activate the prerendered page. This should result in invoking - // DocumentOnLoadCompletedInMainFrame only for main RenderFrameHost. + // DocumentOnLoadCompletedInPrimaryMainFrame only for main RenderFrameHost. // Verify that DidFinishNavigation is invoked before // DocumentAvailableInMainFrame on activation. EXPECT_CALL(observer, DidFinishNavigation(testing::_)); @@ -3711,8 +3709,7 @@ EXPECT_CALL(observer, DOMContentLoaded(testing::_)).Times(1); - EXPECT_CALL(observer, DocumentOnLoadCompletedInMainFrame(testing::_)) - .Times(1); + EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(1); EXPECT_CALL(observer, DidFinishLoad(testing::_, testing::_)).Times(1);
diff --git a/content/browser/renderer_host/frame_tree_browsertest.cc b/content/browser/renderer_host/frame_tree_browsertest.cc index 783f3af..42295e8 100644 --- a/content/browser/renderer_host/frame_tree_browsertest.cc +++ b/content/browser/renderer_host/frame_tree_browsertest.cc
@@ -11,6 +11,7 @@ #include "content/browser/fenced_frame/fenced_frame_url_mapping.h" #include "content/browser/renderer_host/frame_tree.h" #include "content/browser/renderer_host/frame_tree_node.h" +#include "content/browser/renderer_host/navigation_request.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -52,6 +53,84 @@ return EvalJs(node, "self.origin"); } +// This method takes in a RenderFrameHostImpl that must be inside a fenced frame +// FrameTree, and returns the FencedFrame* object that represents this inner +// FrameTree from the outer FrameTree. +FencedFrame* GetMatchingFencedFrameInOuterFrameTree(RenderFrameHostImpl* rfh) { + EXPECT_EQ(blink::features::kFencedFramesImplementationTypeParam.Get(), + blink::features::FencedFramesImplementationType::kMPArch); + // `rfh` doesn't always have to be a root frame, since this needs to work + // for arbitrary frames within a fenced frame. + EXPECT_TRUE(rfh->frame_tree_node()->IsInFencedFrameTree()); + + RenderFrameHostImpl* outer_delegate_frame = + rfh->GetMainFrame()->GetParentOrOuterDocument(); + + std::vector<FencedFrame*> fenced_frames = + outer_delegate_frame->GetFencedFrames(); + EXPECT_FALSE(fenced_frames.empty()); + + for (FencedFrame* fenced_frame : fenced_frames) { + if (fenced_frame->GetInnerRoot() == rfh->GetMainFrame()) { + return fenced_frame; + } + } + + NOTREACHED(); + return nullptr; +} + +class FencedFrameNavigationObserver { + public: + explicit FencedFrameNavigationObserver(RenderFrameHostImpl* fenced_frame_rfh) + : frame_tree_node_(fenced_frame_rfh->frame_tree_node()) { + EXPECT_TRUE(frame_tree_node_->IsInFencedFrameTree()); + + if (blink::features::kFencedFramesImplementationTypeParam.Get() == + blink::features::FencedFramesImplementationType::kShadowDOM) { + observer_for_shadow_dom_ = + std::make_unique<TestFrameNavigationObserver>(fenced_frame_rfh); + return; + } + + fenced_frame_for_mparch_ = + GetMatchingFencedFrameInOuterFrameTree(fenced_frame_rfh); + } + + void Wait(net::Error expected_net_error_code) { + if (blink::features::kFencedFramesImplementationTypeParam.Get() == + blink::features::FencedFramesImplementationType::kShadowDOM) { + DCHECK(observer_for_shadow_dom_); + observer_for_shadow_dom_->Wait(); + EXPECT_EQ(observer_for_shadow_dom_->last_net_error_code(), + expected_net_error_code); + return; + } + + DCHECK(fenced_frame_for_mparch_); + fenced_frame_for_mparch_->WaitForDidStopLoadingForTesting(); + + EXPECT_EQ(frame_tree_node_->current_frame_host()->IsErrorDocument(), + expected_net_error_code != net::OK); + } + + private: + FrameTreeNode* frame_tree_node_ = nullptr; + + // For the ShadowDOM version of fenced frames, we can just use a + // `TestFrameNavigationObserver` as normal directly on the frame that is + // navigating. + std::unique_ptr<TestFrameNavigationObserver> observer_for_shadow_dom_; + + // For the MPArch version of fenced frames, rely on + // FencedFrame::WaitForDidStopLoadingForTesting. `TestFrameNavigationObserver` + // does not fully work inside of a fenced frame FrameTree: `WaitForCommit()` + // works, but `Wait()` always times out because it expects to hear the + // DidFinishedLoad event from the outer WebContents, which is not communicated + // by nested FrameTrees. + FencedFrame* fenced_frame_for_mparch_ = nullptr; +}; + } // namespace class FrameTreeBrowserTest : public ContentBrowserTest { @@ -833,7 +912,8 @@ blink::features::FencedFramesImplementationType::kShadowDOM ? "shadow_dom" : "mparch"}}}, - {blink::features::kThirdPartyStoragePartitioning, {}}}, + {blink::features::kThirdPartyStoragePartitioning, {}}, + {net::features::kPartitionedCookies, {}}}, {/* disabled_features */}); } @@ -885,33 +965,9 @@ RenderFrameHostImpl* fenced_frame_rfh, const std::string& script, net::Error expected_net_error_code = net::OK) { - // For the ShadowDOM version of fenced frames, we can just use a - // `TestFrameNavigationObserver` as normal directly on the frame that is - // navigating. - if (GetParam() == - blink::features::FencedFramesImplementationType::kShadowDOM) { - TestFrameNavigationObserver observer(fenced_frame_rfh); - EXPECT_TRUE(ExecJs(target_rfh, script)); - observer.Wait(); - EXPECT_EQ(observer.last_net_error_code(), expected_net_error_code); - return; - } - - FrameTreeNode* frame_tree_node = fenced_frame_rfh->frame_tree_node(); - EXPECT_TRUE(frame_tree_node->IsInFencedFrameTree()); - - // For the MPArch version of fenced frames, `TestFrameNavigationObserver` - // does not fully work inside of a fenced frame FrameTree. `WaitForCommit()` - // works, but `Wait()` always times out because it expects to hear the - // DidFinishedLoad event from the outer WebContents, which is not - // communicated by nested FrameTrees. - FencedFrame* fenced_frame = - GetMatchingFencedFrameInOuterFrameTree(fenced_frame_rfh); + FencedFrameNavigationObserver observer(fenced_frame_rfh); EXPECT_TRUE(ExecJs(target_rfh, script)); - fenced_frame->WaitForDidStopLoadingForTesting(); - // `rfh` might be destroyed and invalid at this point. - EXPECT_EQ(frame_tree_node->current_frame_host()->IsErrorDocument(), - expected_net_error_code != net::OK); + observer.Wait(expected_net_error_code); } void WaitForDidStopLoadingForTesting(RenderFrameHostImpl* fenced_frame_rfh) { @@ -1046,34 +1102,6 @@ } private: - // This method takes in a RenderFrameHostImpl that must be inside a fenced - // frame FrameTree, and returns the FencedFrame* object that represents this - // inner FrameTree from the outer FrameTree. - FencedFrame* GetMatchingFencedFrameInOuterFrameTree( - RenderFrameHostImpl* rfh) { - EXPECT_EQ(GetParam(), - blink::features::FencedFramesImplementationType::kMPArch); - // `rfh` doesn't always have to be a root frame, since this needs to work - // for arbitrary frames within a fenced frame. - EXPECT_TRUE(rfh->frame_tree_node()->IsInFencedFrameTree()); - - RenderFrameHostImpl* outer_delegate_frame = - rfh->GetMainFrame()->GetParentOrOuterDocument(); - - std::vector<FencedFrame*> fenced_frames = - outer_delegate_frame->GetFencedFrames(); - EXPECT_FALSE(fenced_frames.empty()); - - for (FencedFrame* fenced_frame : fenced_frames) { - if (fenced_frame->GetInnerRoot() == rfh->GetMainFrame()) { - return fenced_frame; - } - } - - NOTREACHED(); - return nullptr; - } - base::test::ScopedFeatureList scoped_feature_list_; base::Lock requests_lock_; std::map<std::string, std::string> cookie_headers_map_ @@ -1136,7 +1164,192 @@ EXPECT_EQ(0, EvalJs(root, "window.frames.length")); } -IN_PROC_BROWSER_TEST_P(FencedFrameTreeBrowserTest, CheckFencedFrameNoCookies) { +IN_PROC_BROWSER_TEST_P( + FencedFrameTreeBrowserTest, + FencedFrameNavigationWithPendingMappedUUID_MappingSuccess) { + GURL main_url = https_server()->GetURL("b.test", "/hello.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + { + EXPECT_TRUE(ExecJs(root, + "var f = document.createElement('fencedframe');" + "document.body.appendChild(f);")); + } + EXPECT_EQ(1U, root->child_count()); + FrameTreeNode* fenced_frame_root_node = + GetFencedFrameRootNode(root->child_at(0)); + + EXPECT_TRUE(fenced_frame_root_node->IsFencedFrameRoot()); + EXPECT_TRUE(fenced_frame_root_node->IsInFencedFrameTree()); + + FencedFrameURLMapping& url_mapping = + root->current_frame_host()->GetPage().fenced_frame_urls_map(); + + const GURL urn_uuid = url_mapping.GeneratePendingMappedURN(); + const GURL mapped_url = + https_server()->GetURL("a.test", "/fenced_frames/title1.html"); + std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec()); + + FencedFrameNavigationObserver observer( + fenced_frame_root_node->current_frame_host()); + + EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script)); + + // After the previous EvalJs, the NavigationRequest should have been created, + // but may not have begun. Wait for BeginNavigation() and expect it to be + // deferred on fenced frame url mapping. + NavigationRequest* request = fenced_frame_root_node->navigation_request(); + if (!request->is_deferred_on_fenced_frame_url_mapping_for_testing()) { + base::RunLoop run_loop; + request->set_begin_navigation_callback_for_testing( + run_loop.QuitWhenIdleClosure()); + run_loop.Run(); + + EXPECT_TRUE(request->is_deferred_on_fenced_frame_url_mapping_for_testing()); + } + + EXPECT_TRUE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + // Trigger the mapping to resume the deferred navigation. + url_mapping.OnURNMappingResultDetermined(urn_uuid, mapped_url); + + EXPECT_FALSE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + observer.Wait(net::OK); + + EXPECT_EQ( + mapped_url, + fenced_frame_root_node->current_frame_host()->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_P( + FencedFrameTreeBrowserTest, + FencedFrameNavigationWithPendingMappedUUID_MappingFailure) { + GURL main_url = https_server()->GetURL("b.test", "/hello.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + { + EXPECT_TRUE(ExecJs(root, + "var f = document.createElement('fencedframe');" + "document.body.appendChild(f);")); + } + EXPECT_EQ(1U, root->child_count()); + FrameTreeNode* fenced_frame_root_node = + GetFencedFrameRootNode(root->child_at(0)); + + EXPECT_TRUE(fenced_frame_root_node->IsFencedFrameRoot()); + EXPECT_TRUE(fenced_frame_root_node->IsInFencedFrameTree()); + + FencedFrameURLMapping& url_mapping = + root->current_frame_host()->GetPage().fenced_frame_urls_map(); + + const GURL urn_uuid = url_mapping.GeneratePendingMappedURN(); + std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec()); + + FencedFrameNavigationObserver observer( + fenced_frame_root_node->current_frame_host()); + + EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script)); + + // After the previous EvalJs, the NavigationRequest should have been created, + // but may not have begun. Wait for BeginNavigation() and expect it to be + // deferred on fenced frame url mapping. + NavigationRequest* request = fenced_frame_root_node->navigation_request(); + if (!request->is_deferred_on_fenced_frame_url_mapping_for_testing()) { + base::RunLoop run_loop; + request->set_begin_navigation_callback_for_testing( + run_loop.QuitWhenIdleClosure()); + run_loop.Run(); + + EXPECT_TRUE(request->is_deferred_on_fenced_frame_url_mapping_for_testing()); + } + + EXPECT_TRUE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + // Trigger the mapping to resume the deferred navigation. + url_mapping.OnURNMappingResultDetermined(urn_uuid, absl::nullopt); + + EXPECT_FALSE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + observer.Wait(net::ERR_INVALID_URL); +} + +IN_PROC_BROWSER_TEST_P( + FencedFrameTreeBrowserTest, + FencedFrameNavigationWithPendingMappedUUID_NavigationCanceledDuringDeferring) { + GURL main_url = https_server()->GetURL("b.test", "/hello.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + + { + EXPECT_TRUE(ExecJs(root, + "var f = document.createElement('fencedframe');" + "document.body.appendChild(f);")); + } + EXPECT_EQ(1U, root->child_count()); + FrameTreeNode* fenced_frame_root_node = + GetFencedFrameRootNode(root->child_at(0)); + + EXPECT_TRUE(fenced_frame_root_node->IsFencedFrameRoot()); + EXPECT_TRUE(fenced_frame_root_node->IsInFencedFrameTree()); + + FencedFrameURLMapping& url_mapping = + root->current_frame_host()->GetPage().fenced_frame_urls_map(); + + const GURL urn_uuid = url_mapping.GeneratePendingMappedURN(); + const GURL mapped_url = + https_server()->GetURL("a.test", "/fenced_frames/title1.html"); + std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec()); + + FencedFrameNavigationObserver observer( + fenced_frame_root_node->current_frame_host()); + + EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script)); + + // After the previous EvalJs, the NavigationRequest should have been created, + // but may not have begun. Wait for BeginNavigation() and expect it to be + // deferred on fenced frame url mapping. + NavigationRequest* request = fenced_frame_root_node->navigation_request(); + if (!request->is_deferred_on_fenced_frame_url_mapping_for_testing()) { + base::RunLoop run_loop; + request->set_begin_navigation_callback_for_testing( + run_loop.QuitWhenIdleClosure()); + run_loop.Run(); + + EXPECT_TRUE(request->is_deferred_on_fenced_frame_url_mapping_for_testing()); + } + + EXPECT_TRUE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + // Navigate to a new URL. The previous navigation should have been canceled. + // And `request` should have been removed from `url_mapping`. + const GURL new_url = + https_server()->GetURL("a.test", "/fenced_frames/empty.html"); + EXPECT_EQ(new_url.spec(), + EvalJs(root, JsReplace("f.src = $1;", new_url.spec()))); + + EXPECT_FALSE(url_mapping.HasObserverForTesting(urn_uuid, request)); + + observer.Wait(net::OK); + + EXPECT_EQ( + new_url, + fenced_frame_root_node->current_frame_host()->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_P(FencedFrameTreeBrowserTest, + CheckFencedFrameCookiesNavigation) { // Create an a.test main page and set cookies. Then create a same-origin // fenced frame. Its request should not carry the cookies that were set. GURL main_url = https_server()->GetURL("a.test", "/hello.html"); @@ -1218,6 +1431,101 @@ EXPECT_TRUE(CheckAndClearCookieHeader(image_url, "B=2; C=2")); } +IN_PROC_BROWSER_TEST_P(FencedFrameTreeBrowserTest, + CheckPartitionedCookiesWithNonce) { + // Create an a.test main page and set cookies. Then create a same-origin + // fenced frame. + GURL main_url = https_server()->GetURL("a.test", "/hello.html"); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + RenderFrameHostImpl* root_rfh = + static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root() + ->current_frame_host(); + + // Set SameSite=Lax and SameSite=None cookies and retrieve them. + EXPECT_TRUE(ExecJs(root_rfh, + "document.cookie = 'B=2; SameSite=Lax';" + "document.cookie = 'C=2; SameSite=None; Secure';")); + EXPECT_EQ("B=2; C=2", EvalJs(root_rfh, "document.cookie;")); + + // Add and navigate a fenced frame. + EXPECT_TRUE(ExecJs(root_rfh, + "var f = document.createElement('fencedframe');" + "document.body.appendChild(f);")); + EXPECT_EQ(1U, root_rfh->child_count()); + FrameTreeNode* fenced_frame_root_node = + GetFencedFrameRootNode(root_rfh->child_at(0)); + EXPECT_TRUE(fenced_frame_root_node->IsFencedFrameRoot()); + EXPECT_TRUE(fenced_frame_root_node->IsInFencedFrameTree()); + + GURL https_url( + https_server()->GetURL("a.test", "/fenced_frames/title1.html")); + FencedFrameURLMapping& url_mapping = + root_rfh->GetPage().fenced_frame_urls_map(); + GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url); + EXPECT_TRUE(urn_uuid.is_valid()); + + std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec()); + NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad( + fenced_frame_root_node, urn_uuid, navigate_urn_script); + EXPECT_EQ( + https_url, + fenced_frame_root_node->current_frame_host()->GetLastCommittedURL()); + EXPECT_EQ( + url::Origin::Create(https_url), + fenced_frame_root_node->current_frame_host()->GetLastCommittedOrigin()); + + // Create cookies in the Fenced Frame. + EXPECT_TRUE(ExecJs(fenced_frame_root_node->current_frame_host(), + "document.cookie = 'B=3; SameSite=Lax';" + "document.cookie = 'C=3; SameSite=None; Secure';")); + + const net::IsolationInfo& isolation_info = + fenced_frame_root_node->current_frame_host() + ->GetIsolationInfoForSubresources(); + EXPECT_TRUE(isolation_info.nonce()); + absl::optional<net::CookiePartitionKey> partition_key = + net::CookiePartitionKey::FromNetworkIsolationKey( + isolation_info.network_isolation_key()); + EXPECT_TRUE(partition_key && partition_key->nonce()); + net::CookiePartitionKeyCollection cookie_partition_key_collection = + net::CookiePartitionKeyCollection::FromOptional(partition_key); + + std::vector<net::CanonicalCookie> cookies = + GetCanonicalCookies(shell()->web_contents()->GetBrowserContext(), + https_url, cookie_partition_key_collection); + EXPECT_EQ(2u, cookies.size()); + for (auto cookie : cookies) { + EXPECT_TRUE(cookie.IsPartitioned()); + EXPECT_TRUE(cookie.PartitionKey() && cookie.PartitionKey()->nonce()); + EXPECT_EQ(cookie.PartitionKey()->nonce(), partition_key->nonce()); + EXPECT_EQ("3", cookie.Value()); + } + + // Run the same test for an iframe inside the fenced frame. It should be + // able to access the same cookies. + // Add a nested iframe inside the fenced frame which needs to be a URL that + // also opts in to be allowed to load inside of a fenced frame. + GURL iframe_url( + https_server()->GetURL("a.test", "/fenced_frames/nested.html")); + EXPECT_EQ(0U, fenced_frame_root_node->child_count()); + AddIframeInFencedFrame(fenced_frame_root_node, 0); + NavigateIframeInFencedFrame(fenced_frame_root_node->child_at(0), iframe_url); + + EXPECT_EQ(iframe_url, fenced_frame_root_node->child_at(0) + ->current_frame_host() + ->GetLastCommittedURL()); + EXPECT_EQ(url::Origin::Create(iframe_url), fenced_frame_root_node->child_at(0) + ->current_frame_host() + ->GetLastCommittedOrigin()); + EXPECT_EQ("B=3; C=3", + EvalJs(fenced_frame_root_node->child_at(0)->current_frame_host(), + "document.cookie;")); +} + // Tests when a frame is considered a fenced frame or being inside a fenced // frame tree. IN_PROC_BROWSER_TEST_P(FencedFrameTreeBrowserTest, CheckIsFencedFrame) {
diff --git a/content/browser/renderer_host/frame_tree_node_blame_context_unittest.cc b/content/browser/renderer_host/frame_tree_node_blame_context_unittest.cc index 0f285ba5..8301870b 100644 --- a/content/browser/renderer_host/frame_tree_node_blame_context_unittest.cc +++ b/content/browser/renderer_host/frame_tree_node_blame_context_unittest.cc
@@ -47,26 +47,24 @@ std::string GetParentNodeID(const trace_analyzer::TraceEvent* event) { const base::Value& arg_snapshot = event->arg_values.at("snapshot"); - const base::DictionaryValue* snapshot; - EXPECT_TRUE(arg_snapshot.GetAsDictionary(&snapshot)); - if (!snapshot->HasKey("parent")) + EXPECT_TRUE(arg_snapshot.is_dict()); + const base::Value* parent = arg_snapshot.FindKey("parent"); + if (!parent) return std::string(); - const base::DictionaryValue* parent; - EXPECT_TRUE(snapshot->GetDictionary("parent", &parent)); - std::string parent_id; - EXPECT_TRUE(parent->GetString("id_ref", &parent_id)); - return parent_id; + EXPECT_TRUE(parent->is_dict()); + const std::string* parent_id = parent->FindStringKey("id_ref"); + EXPECT_TRUE(parent_id); + return *parent_id; } std::string GetSnapshotURL(const trace_analyzer::TraceEvent* event) { const base::Value& arg_snapshot = event->arg_values.at("snapshot"); - const base::DictionaryValue* snapshot; - EXPECT_TRUE(arg_snapshot.GetAsDictionary(&snapshot)); - if (!snapshot->HasKey("url")) + EXPECT_TRUE(arg_snapshot.is_dict()); + const base::Value* url = arg_snapshot.FindKey("url"); + if (!url) return std::string(); - std::string url; - EXPECT_TRUE(snapshot->GetString("url", &url)); - return url; + EXPECT_TRUE(url->is_string()); + return url->GetString(); } } // namespace
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 9565646..c3929178 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -1699,6 +1699,11 @@ navigation_handle_proxy_->DidFinish(); #endif + if (is_deferred_on_fenced_frame_url_mapping_) { + CHECK(NeedFencedFrameURLMapping()); + GetFencedFrameURLMap().RemoveObserverForURN(common_params_->url, this); + } + if (IsNavigationStarted()) { GetDelegate()->DidFinishNavigation(this); ProcessOriginAgentClusterEndResult(); @@ -1752,11 +1757,37 @@ DCHECK(!render_frame_host_); ScopedCrashKeys crash_keys(*this); + if (begin_navigation_callback_for_testing_) { + std::move(begin_navigation_callback_for_testing_).Run(); + } + if (MaybeStartPrerenderingActivationChecks()) { // BeginNavigationImpl() will be called after the checks. return; } + MaybeAssignInvalidPrerenderFrameTreeNodeId(); + + // If this is a fenced frame with a urn:uuid, then convert it to a url before + // starting the navigation; otherwise, proceed directly with the navigation. + if (NeedFencedFrameURLMapping()) { + FencedFrameURLMapping& fenced_frame_urls_map = GetFencedFrameURLMap(); + + // If the mapping finishes synchronously, OnFencedFrameURLMappingComplete + // will be synchronously called and will reset + // `is_deferred_on_fenced_frame_url_mapping_` to false. + is_deferred_on_fenced_frame_url_mapping_ = true; + + // OnFencedFrameURLMappingComplete() and BeginNavigationImpl() will be + // invoked after this. + fenced_frame_urls_map.ConvertFencedFrameURNToURL(common_params_->url, + /*observer=*/this); + // DO NOT ADD CODE after this. The previous call to + // ConvertFencedFrameURNToURL may cause the destruction of the + // NavigationRequest. + return; + } + BeginNavigationImpl(); } @@ -1831,46 +1862,53 @@ is_potentially_prerendered_page_activation_for_testing_ = false; commit_deferrer_.reset(); + // We can only activate top-level pages, which can never be at a fenced frame + // URN that needs to be mapped. + CHECK(!NeedFencedFrameURLMapping()); + BeginNavigationImpl(); - // DO NOT ADD CODE after this. The previous call to BeginNavigationImpl may - // cause the destruction of the NavigationRequest. + // DO NOT ADD CODE after this. The previous call to + // BeginNavigationImpl may cause the destruction of the NavigationRequest. } -void NavigationRequest::BeginNavigationImpl() { - base::ElapsedTimer timer; - SetState(WILL_START_NAVIGATION); +FencedFrameURLMapping& NavigationRequest::GetFencedFrameURLMap() { + // `inner_frame_tree` is true for navigations inside the main frame of a + // nested fenced frame's `FrameTree`, and false otherwise. This is only the + // case for the MPArch implementation of fenced frames. + bool is_inner_frame_tree = + frame_tree_node_->frame_tree()->type() == FrameTree::Type::kFencedFrame; + FrameTreeNode* node_to_use = + is_inner_frame_tree + ? frame_tree_node_->render_manager()->GetOuterDelegateNode() + : frame_tree_node_; - bool convert_urn_uuid_urls = frame_tree_node_->IsFencedFrameRoot() || - (!frame_tree_node_->IsMainFrame() && - blink::features::IsAllowURNsInIframeEnabled()); - // If this is a fenced frame or iframe with a urn:uuid then convert it to a - // url before starting the request. - if (convert_urn_uuid_urls && - FencedFrameURLMapping::IsValidUrnUuidURL(common_params_->url)) { - // `inner_frame_tree` is true for navigations inside the main frame of a - // nested fenced frame's `FrameTree`, and false otherwise. This is only the - // case for the MPArch implementation of fenced frames. - bool is_inner_frame_tree = - frame_tree_node_->frame_tree()->type() == FrameTree::Type::kFencedFrame; - FrameTreeNode* node_to_use = - is_inner_frame_tree - ? frame_tree_node_->render_manager()->GetOuterDelegateNode() - : frame_tree_node_; + return node_to_use->current_frame_host()->GetPage().fenced_frame_urls_map(); +} +bool NavigationRequest::NeedFencedFrameURLMapping() { + bool need_convert_urn_uuid_urls = + frame_tree_node_->IsFencedFrameRoot() || + (!frame_tree_node_->IsMainFrame() && + blink::features::IsAllowURNsInIframeEnabled()); + + return need_convert_urn_uuid_urls && + FencedFrameURLMapping::IsValidUrnUuidURL(common_params_->url); +} + +void NavigationRequest::OnFencedFrameURLMappingComplete( + absl::optional<GURL> mapped_url, absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components_map; - absl::optional<GURL> mapped_url = - node_to_use->current_frame_host() - ->GetPage() - .fenced_frame_urls_map() - .ConvertFencedFrameURNToURL(common_params_->url, - pending_ad_components_map); + pending_ad_components_map) { + is_deferred_on_fenced_frame_url_mapping_ = false; - if (mapped_url) { - common_params_->url = *mapped_url; - commit_params_->original_url = *mapped_url; - pending_ad_components_map_ = std::move(pending_ad_components_map); - } else if (frame_tree_node_->IsFencedFrameRoot()) { + if (mapped_url) { + common_params_->url = mapped_url.value(); + commit_params_->original_url = mapped_url.value(); + // TODO(crbug/1281643): move into commit_params_->ad_auction_components + // directly. + pending_ad_components_map_ = std::move(pending_ad_components_map); + } else { + if (frame_tree_node_->IsFencedFrameRoot()) { StartNavigation(); OnRequestFailedInternal( network::URLLoaderCompletionStatus(net::ERR_INVALID_URL), @@ -1880,6 +1918,14 @@ } // else (for iframes) try the urn as-is to maintain existing behavior. } + BeginNavigationImpl(); + // DO NOT ADD CODE after this. The previous call to BeginNavigationImpl may + // cause the destruction of the NavigationRequest. +} + +void NavigationRequest::BeginNavigationImpl() { + base::ElapsedTimer timer; + SetState(WILL_START_NAVIGATION); #if defined(OS_ANDROID) base::WeakPtr<NavigationRequest> this_ptr(weak_factory_.GetWeakPtr()); bool should_override_url_loading = false; @@ -2065,13 +2111,7 @@ is_synchronous_renderer_commit_); FrameTreeNode* frame_tree_node = frame_tree_node_; - if (blink::features::IsPrerender2Enabled() && - !prerender_frame_tree_node_id_.has_value()) { - // This navigation won't activate a prerendered page. Otherwise, - // `prerender_frame_tree_node_id_` should have already been set before this - // in OnPrerenderingActivationChecksComplete(). - prerender_frame_tree_node_id_ = RenderFrameHost::kNoFrameTreeNodeId; - } + MaybeAssignInvalidPrerenderFrameTreeNodeId(); // This is needed to get site URLs and assign the expected RenderProcessHost. // This is not always the same as |source_site_instance_|, as it only depends @@ -3198,11 +3238,35 @@ auto cross_origin_embedder_policy = CoepFromMainResponse(url, response_head_.get()); + // Compute "topLevelCreationURL" for COEP and secure context. + // + // [spec]: https://html.spec.whatwg.org/C/#initialise-the-document-object + // 3. Let creationURL be navigationParams's response's URL. + // 5. If browsingContext is still on its initial about:blank Document [...] + // 6. Otherwise: + // 6.6. Let topLevelCreationURL be creationURL. + // 6.8. If browsingContext is not a top-level browsing context, then: + // 6.8.2. Set topLevelCreationURL to parentEnvironment's top-level creation + // URL. + // + // TODO(arthursonzogni): It would be good clarifying what means + // |topLevelCreationURL| when loading FencedFrame/Portals/GuestView, and how + // it should affects COEP. + // Tracking bug: + // - FencedFrame: https://crbug.com/1277430 + // - Portals: https://crbug.com/1278207 + // - GuestView: XXX or slightly related https://crbug.com/1260747 + const GURL& top_level_creation_url = + IsInMainFrame() ? url + : frame_tree_node_->current_frame_host() + ->GetMainFrame() + ->GetLastCommittedURL(); + // [spec]: https://html.spec.whatwg.org/C/#obtain-an-embedder-policy // // 1. Let policy be a new embedder policy. // 2. If environment is a non-secure context, then return policy. - if (!network::IsUrlPotentiallyTrustworthy(url)) + if (!network::IsUrlPotentiallyTrustworthy(top_level_creation_url)) cross_origin_embedder_policy = network::CrossOriginEmbedderPolicy(); // [spec]: https://html.spec.whatwg.org/C/#process-a-navigate-response @@ -3591,7 +3655,7 @@ // account for clearing the expected process if it clears the speculative // RenderFrameHost. See https://crbug.com/793127. ResetExpectedProcess(); - FALLTHROUGH; + [[fallthrough]]; case ErrorPageProcess::kDestinationProcess: // A same-document navigation would normally attempt to navigate the // current document, but since we will be presenting an error instead and @@ -6660,13 +6724,6 @@ bool NavigationRequest::CheckResponseAdherenceToCoep( network::CrossOriginEmbedderPolicy* coep, const GURL& url) { - // TODO(arthursonzogni): This check looks fishy to me. Consider removing it. - // It was kept during refactoring, in order not to break WPT test: - // web-bundle/subresource-loading/link-coep.https.tentative.html - // This allows non trustworthy URL like urn: URL to bypass COEP check. - if (!network::IsUrlPotentiallyTrustworthy(url)) - return true; - // Fenced Frames should respect the outer frame's COEP. // Note: we only check the outer document for fenced frames, because it's // unclear if other embedded cases like Portals should inherit COEP from @@ -6972,6 +7029,7 @@ }}, {WAITING_FOR_RENDERER_RESPONSE, { WILL_START_NAVIGATION, + WILL_START_REQUEST, }}, {WILL_START_NAVIGATION, { WILL_START_REQUEST, @@ -7262,6 +7320,16 @@ : WebExposedIsolationInfo::CreateIsolated(origin); } +void NavigationRequest::MaybeAssignInvalidPrerenderFrameTreeNodeId() { + if (blink::features::IsPrerender2Enabled() && + !prerender_frame_tree_node_id_.has_value()) { + // This navigation won't activate a prerendered page. Otherwise, + // `prerender_frame_tree_node_id_` should have already been set before this + // in OnPrerenderingActivationChecksComplete(). + prerender_frame_tree_node_id_ = RenderFrameHost::kNoFrameTreeNodeId; + } +} + NavigationRequest::ScopedCrashKeys::ScopedCrashKeys( NavigationRequest& navigation_request) : initiator_origin_(
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 266cfa4..06ffe99 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -112,6 +112,7 @@ public NavigationURLLoaderDelegate, public NavigationThrottleRunner::Delegate, public CommitDeferringConditionRunner::Delegate, + public FencedFrameURLMapping::MappingResultObserver, private RenderProcessHostObserver, private network::mojom::CookieAccessObserver { public: @@ -612,6 +613,10 @@ // navigation being committed (e.g. canceled navigations). virtual bool DidEncounterError() const; + void set_begin_navigation_callback_for_testing(base::OnceClosure callback) { + begin_navigation_callback_for_testing_ = std::move(callback); + } + void set_complete_callback_for_testing( ThrottleChecksFinishedCallback callback) { complete_callback_for_testing_ = std::move(callback); @@ -874,6 +879,10 @@ void AddDeferredConsoleMessage(blink::mojom::ConsoleMessageLevel level, std::string message); + bool is_deferred_on_fenced_frame_url_mapping_for_testing() const { + return is_deferred_on_fenced_frame_url_mapping_; + } + base::WeakPtr<NavigationRequest> GetWeakPtr(); bool is_potentially_prerendered_page_activation_for_testing() const { @@ -966,7 +975,22 @@ CommitDeferringCondition::NavigationType navigation_type, absl::optional<int> candidate_prerender_frame_tree_node_id); - // Called from BeginNavigation() or OnPrerenderingActivationChecksComplete(). + // Get the `FencedFrameURLMapping` associated with the current page. + FencedFrameURLMapping& GetFencedFrameURLMap(); + + // True if this is a fenced frame navigation to an urn:uuid. + bool NeedFencedFrameURLMapping(); + + // FencedFrameURLMapping::MappingResultObserver implementation. + // Called from `FencedFrameURLMapping` when the mapping decision is made, and + // resume the deferred navigation. + void OnFencedFrameURLMappingComplete( + absl::optional<GURL> mapped_url, + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> + pending_ad_components_map) override; + + // Called from BeginNavigation(), OnPrerenderingActivationChecksComplete(), + // or OnFencedFrameURLMappingComplete(). void BeginNavigationImpl(); // Checks if the response requests an isolated origin via the @@ -1450,6 +1474,13 @@ // a network response yet, or when going to an "about:blank" page. absl::optional<WebExposedIsolationInfo> ComputeWebExposedIsolationInfo(); + // Assign an invalid frame tree node id to `prerender_frame_tree_node_id_`. + // Called as soon as when we are certain that this navigation won't activate a + // prerendered page. This is needed because `IsPrerenderedPageActivation()`, + // which may be called at any point after BeginNavigation(), will assume that + // 'prerender_frame_tree_node_id_' has an value assigned. + void MaybeAssignInvalidPrerenderFrameTreeNodeId(); + // Never null. The pointee node owns this navigation request instance. FrameTreeNode* const frame_tree_node_; @@ -1682,6 +1713,9 @@ // with this html as content and |net_error| as the network error. std::string post_commit_error_page_html_; + // This test-only callback will be run when BeginNavigation() is called. + base::OnceClosure begin_navigation_callback_for_testing_; + // This test-only callback will be run when all throttle checks have been // performed. If the callback returns true, On*ChecksComplete functions are // skipped, and only the test callback is being performed. @@ -1869,6 +1903,12 @@ // running. bool is_potentially_prerendered_page_activation_for_testing_ = false; + // Set to true before the fenced frame url mapping. Reset to false when the + // mapping finishes. If the initial mapping state of the urn:uuid is pending, + // the mapping will finish asynchronously; otherwise, the mapping will finish + // synchronously. + bool is_deferred_on_fenced_frame_url_mapping_ = false; + // The root frame tree node id of the prerendered page. This will be a valid // FrameTreeNode id when this navigation will activate a prerendered page. // For all other navigations this will be
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc index efb3437..2cafff47 100644 --- a/content/browser/renderer_host/navigation_request_unittest.cc +++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/i18n/number_formatting.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/ssl_status.h" @@ -214,6 +215,23 @@ GetNavigationRequest()->StartNavigation(); } + FrameTreeNode* AddFrame(FrameTree& frame_tree, + RenderFrameHostImpl* parent, + int process_id, + int new_routing_id, + const blink::FramePolicy& frame_policy, + blink::FrameOwnerElementType owner_type) { + return frame_tree.AddFrame( + parent, process_id, new_routing_id, + TestRenderFrameHost::CreateStubFrameRemote(), + TestRenderFrameHost::CreateStubBrowserInterfaceBrokerReceiver(), + TestRenderFrameHost::CreateStubPolicyContainerBindParams(), + blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0", + false, blink::LocalFrameToken(), base::UnguessableToken::Create(), + frame_policy, blink::mojom::FrameOwnerProperties(), false, owner_type, + /*is_dummy_frame_for_inner_tree=*/false); + } + private: // The callback provided to NavigationRequest::WillStartRequest, // NavigationRequest::WillRedirectRequest, and @@ -301,6 +319,65 @@ navigation->GetNavigationHandle()->GetNetErrorCode()); } +TEST_F(NavigationRequestTest, FencedFrameNavigationToPendingMappedURN) { + // Note that we only run this test for the ShadowDOM implementation of fenced + // frames, due to how they add subframes in a way that is very specific to the + // ShadowDOM implementation, and not suitable for the MPArch implementation. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeatureWithParameters( + blink::features::kFencedFrames, {{"implementation_type", "shadow_dom"}}); + + FrameTree& frame_tree = contents()->GetPrimaryFrameTree(); + FrameTreeNode* root = frame_tree.root(); + int process_id = root->current_frame_host()->GetProcess()->GetID(); + + // Add a fenced frame. + constexpr auto kFencedframeOwnerType = + blink::FrameOwnerElementType::kFencedframe; + blink::FramePolicy policy; + policy.is_fenced = true; + AddFrame(frame_tree, root->current_frame_host(), process_id, 15, policy, + kFencedframeOwnerType); + + FrameTreeNode* fenced_frame_tree_node = root->child_at(0); + EXPECT_TRUE(fenced_frame_tree_node->IsFencedFrameRoot()); + EXPECT_TRUE(fenced_frame_tree_node->IsInFencedFrameTree()); + + FencedFrameURLMapping& fenced_frame_urls_map = + main_test_rfh()->GetPage().fenced_frame_urls_map(); + + const GURL urn_uuid = fenced_frame_urls_map.GeneratePendingMappedURN(); + const GURL mapped_url = GURL("http://chromium.org"); + + auto navigation_simulator = NavigationSimulatorImpl::CreateRendererInitiated( + urn_uuid, fenced_frame_tree_node->current_frame_host()); + + auto response_headers = + base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK"); + response_headers->SetHeader("Supports-Loading-Mode", "fenced-frame"); + + navigation_simulator->SetAutoAdvance(false); + navigation_simulator->SetResponseHeaders(response_headers); + navigation_simulator->SetTransition(ui::PAGE_TRANSITION_AUTO_SUBFRAME); + + navigation_simulator->Start(); + + EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), urn_uuid); + + fenced_frame_urls_map.OnURNMappingResultDetermined(urn_uuid, mapped_url); + + // Expect that the url in the NavigationRequest is already mapped. + EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), mapped_url); + + navigation_simulator->Wait(); + + navigation_simulator->SetAutoAdvance(true); + navigation_simulator->ReadyToCommit(); + navigation_simulator->Commit(); + + EXPECT_EQ(fenced_frame_tree_node->current_url(), mapped_url); +} + // Checks that a navigation deferred during WillStartRequest can be properly // cancelled. TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index fd44af9..0d42081 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5752,13 +5752,13 @@ GetPage().set_is_on_load_completed_in_main_document(true); - // Don't dispatch DocumentOnLoadCompletedInMainFrame for non-primary main - // frames. As most of the observers are interested only in the onload + // Don't dispatch DocumentOnLoadCompletedInPrimaryMainFrame for non-primary + // main frames. As most of the observers are interested only in the onload // completion of the current document in the primary main frame. Since the // WebContents could be hosting more than one main frame (e.g., fenced frames, // prerender pages or pending delete RFHs), return early for other cases. In - // case of prerendering, we dispatch DocumentOnLoadCompletedInMainFrame on - // activation. + // case of prerendering, we dispatch DocumentOnLoadCompletedInPrimaryMainFrame + // on activation. if (!IsInPrimaryMainFrame()) return; @@ -8085,7 +8085,9 @@ GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( - GetProcess()->GetID(), routing_id_, &non_network_factories); + GetProcess()->GetID(), routing_id_, + subresource_loader_factories_config.origin(), + &non_network_factories); for (auto& factory : non_network_factories) { mojo::PendingRemote<network::mojom::URLLoaderFactory> @@ -9587,6 +9589,16 @@ return; } + // Powerful features like Serial API for FencedFrames are blocked by + // PermissionsPolicy. But as the interface is still exposed to the renderer, + // still good to have a secondary check per-API basis to handle compromised + // renderers. Ignore the request and mark it as bad to kill the initiating + // renderer if it happened for some reason. + if (IsNestedWithinFencedFrame()) { + mojo::ReportBadMessage("Web Serial is not allowed in fences frames."); + return; + } + SerialService::GetOrCreateForCurrentDocument(this)->Bind(std::move(receiver)); } @@ -9806,8 +9818,7 @@ void RenderFrameHostImpl::CreateLockManager( mojo::PendingReceiver<blink::mojom::LockManager> receiver) { - GetProcess()->CreateLockManager(GetRoutingID(), GetLastCommittedOrigin(), - std::move(receiver)); + GetProcess()->CreateLockManager(storage_key(), std::move(receiver)); } void RenderFrameHostImpl::CreateIDBFactory( @@ -12528,7 +12539,7 @@ GetPeerConnectionTrackerHost().StopEventLog(lid); } -bool RenderFrameHostImpl::IsDocumentOnLoadCompletedInMainFrame() { +bool RenderFrameHostImpl::IsDocumentOnLoadCompletedInPrimaryMainFrame() { return GetPage().is_on_load_completed_in_main_document(); }
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 2660196..553a02f4 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2323,7 +2323,7 @@ mojo::PendingReceiver<blink::mojom::PeerConnectionTrackerHost> receiver); void EnableWebRtcEventLogOutput(int lid, int output_period_ms) override; void DisableWebRtcEventLogOutput(int lid) override; - bool IsDocumentOnLoadCompletedInMainFrame() override; + bool IsDocumentOnLoadCompletedInPrimaryMainFrame() override; const std::vector<blink::mojom::FaviconURLPtr>& FaviconURLs() override; #if BUILDFLAG(ENABLE_MDNS)
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 372bd7d..1356a72 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -4720,10 +4720,7 @@ protected: // WebContentsObserver: - void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) override { - callback_.Run(); - } + void DocumentOnLoadCompletedInPrimaryMainFrame() override { callback_.Run(); } private: base::RepeatingClosure callback_; @@ -4750,7 +4747,7 @@ shell()->LoadURL(main_document_url); EXPECT_FALSE(rfhi->IsDOMContentLoaded()); - EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); main_document_response.WaitForRequest(); main_document_response.Send( @@ -4762,7 +4759,7 @@ load_observer.WaitForNavigationFinished(); EXPECT_FALSE(rfhi->IsDOMContentLoaded()); - EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); main_document_response.Done(); @@ -4771,7 +4768,7 @@ loop_until_dcl.Run(); EXPECT_TRUE(rfhi->is_loading()); EXPECT_TRUE(rfhi->IsDOMContentLoaded()); - EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); base::RunLoop loop_until_onload; DocumentOnLoadObserver onload_observer(web_contents, @@ -4783,7 +4780,7 @@ // And now onload() should be reached. loop_until_onload.Run(); EXPECT_TRUE(rfhi->IsDOMContentLoaded()); - EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); } IN_PROC_BROWSER_TEST_F(ContentBrowserTest, LoadingStateResetOnNavigation) { @@ -4804,7 +4801,7 @@ EXPECT_TRUE(static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame()) ->IsDOMContentLoaded()); - EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); // Expect that the loading state will be reset after a navigation. @@ -4818,7 +4815,7 @@ "\r\n"); navigation_observer.WaitForNavigationFinished(); EXPECT_FALSE(web_contents->GetMainFrame()->IsDOMContentLoaded()); - EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_FALSE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); } IN_PROC_BROWSER_TEST_F(ContentBrowserTest, @@ -4841,7 +4838,7 @@ loop_until_onload.Run(); EXPECT_TRUE(rfhi->IsDOMContentLoaded()); - EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); // Expect that the loading state will NOT be reset after a cancelled // navigation. @@ -4859,7 +4856,7 @@ navigation_manager.WaitForNavigationFinished(); EXPECT_TRUE(rfhi->IsDOMContentLoaded()); - EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInMainFrame()); + EXPECT_TRUE(web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()); } IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, GetUkmSourceIds) {
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 46970f7..eaaedc0 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h
@@ -14,6 +14,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner_helpers.h" +#include "base/threading/platform_thread.h" #include "build/build_config.h" #include "content/common/render_message_filter.mojom.h" #include "content/public/browser/browser_associated_interface.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 71d29f9..ca8535d 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2076,26 +2076,21 @@ } void RenderProcessHostImpl::CreateLockManager( - int render_frame_id, - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::LockManager> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::UI); storage_partition_impl_->GetQuotaManager()->proxy()->GetOrCreateBucket( - blink::StorageKey(origin), storage::kDefaultBucketName, - GetUIThreadTaskRunner({}), + storage_key, storage::kDefaultBucketName, GetUIThreadTaskRunner({}), base::BindOnce(&RenderProcessHostImpl::CreateLockManagerWithBucketInfo, - weak_factory_.GetWeakPtr(), render_frame_id, - std::move(receiver))); + weak_factory_.GetWeakPtr(), std::move(receiver))); } void RenderProcessHostImpl::CreateLockManagerWithBucketInfo( - int render_frame_id, mojo::PendingReceiver<blink::mojom::LockManager> receiver, storage::QuotaErrorOr<storage::BucketInfo> bucket) { storage_partition_impl_->GetLockManager()->BindReceiver( - GetID(), render_frame_id, bucket.ok() ? bucket->id : storage::BucketId(), - std::move(receiver)); + bucket.ok() ? bucket->id : storage::BucketId(), std::move(receiver)); } void RenderProcessHostImpl::CreatePermissionService( @@ -3345,7 +3340,6 @@ switches::kEnableLCDText, switches::kEnableLogging, switches::kEnableNetworkInformationDownlinkMax, - switches::kEnableOopRasterization, switches::kEnablePluginPlaceholderTesting, switches::kEnablePreciseMemoryInfo, switches::kEnableSkiaBenchmarking,
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 88d1379..b911dd9b 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -616,14 +616,12 @@ mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) override; // Binds |receiver| to the LockManager owned by |storage_partition_impl_|. - // |receiver| belongs to a frame or worker at |origin| hosted by this process. - // If it belongs to a frame, |render_frame_id| identifies it, otherwise it is - // MSG_ROUTING_NONE. + // |receiver| belongs to a frame or worker with |storage_key| hosted by this + // process. // // Used by frames and workers via BrowserInterfaceBroker. void CreateLockManager( - int render_frame_id, - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::LockManager> receiver) override; // Binds |receiver| to the PermissionService instance owned by @@ -865,7 +863,6 @@ // Helper method for CreateLockManager() which facilitates use of |bucket| // instead of |origin| for binding |receiver| void CreateLockManagerWithBucketInfo( - int render_frame_id, mojo::PendingReceiver<blink::mojom::LockManager> receiver, storage::QuotaErrorOr<storage::BucketInfo> bucket);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index d295a11..b7084cb 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -71,6 +71,7 @@ #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_tree_host.h" +#include "ui/aura_extra/window_position_in_root_monitor.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" @@ -241,57 +242,6 @@ raw_ptr<RenderWidgetHostViewAura> view_; }; -// This class provides functionality to observe the ancestors of the RWHVA for -// bounds changes. This is done to snap the RWHVA window to a pixel boundary, -// which could change when the bounds relative to the root changes. -// An example where this happens is below:- -// The fast resize code path for bookmarks where in the parent of RWHVA which -// is WCV has its bounds changed before the bookmark is hidden. This results in -// the traditional bounds change notification for the WCV reporting the old -// bounds as the bookmark is still around. Observing all the ancestors of the -// RWHVA window enables us to know when the bounds of the window relative to -// root changes and allows us to snap accordingly. -class RenderWidgetHostViewAura::WindowAncestorObserver - : public aura::WindowObserver { - public: - explicit WindowAncestorObserver(RenderWidgetHostViewAura* view) - : view_(view) { - aura::Window* parent = view_->window_->parent(); - while (parent) { - parent->AddObserver(this); - ancestors_.insert(parent); - parent = parent->parent(); - } - } - - WindowAncestorObserver(const WindowAncestorObserver&) = delete; - WindowAncestorObserver& operator=(const WindowAncestorObserver&) = delete; - - ~WindowAncestorObserver() override { - RemoveAncestorObservers(); - } - - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) override { - DCHECK(ancestors_.find(window) != ancestors_.end()); - if (new_bounds.origin() != old_bounds.origin()) - view_->HandleParentBoundsChanged(); - } - - private: - void RemoveAncestorObservers() { - for (auto* ancestor : ancestors_) - ancestor->RemoveObserver(this); - ancestors_.clear(); - } - - raw_ptr<RenderWidgetHostViewAura> view_; - std::set<aura::Window*> ancestors_; -}; - - //////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewAura, public: @@ -501,7 +451,7 @@ return focused_frame->current_frame_host(); } -void RenderWidgetHostViewAura::HandleParentBoundsChanged() { +void RenderWidgetHostViewAura::HandleBoundsInRootChanged() { #if defined(OS_WIN) if (legacy_render_widget_host_HWND_) { legacy_render_widget_host_HWND_->SetBounds( @@ -521,9 +471,27 @@ } void RenderWidgetHostViewAura::ParentHierarchyChanged() { - ancestor_window_observer_ = std::make_unique<WindowAncestorObserver>(this); + if (window_->parent()) { + // Track changes of the window relative to the root. This is done to snap + // `window_` to a pixel boundary, which could change when the bounds + // relative to the root changes. An example where this happens: + // The fast resize code path for bookmarks where in the parent of RWHVA + // which is WCV has its bounds changed before the bookmark is hidden. This + // results in the traditional bounds change notification for the WCV + // reporting the old bounds as the bookmark is still around. Observing all + // the ancestors of the RWHVA window enables us to know when the bounds of + // the window relative to root changes and allows us to snap accordingly. + position_in_root_observer_ = + std::make_unique<aura_extra::WindowPositionInRootMonitor>( + window_->parent(), + base::BindRepeating( + &RenderWidgetHostViewAura::HandleBoundsInRootChanged, + base::Unretained(this))); + } else { + position_in_root_observer_.reset(); + } // Snap when we receive a hierarchy changed. http://crbug.com/388908. - HandleParentBoundsChanged(); + HandleBoundsInRootChanged(); } void RenderWidgetHostViewAura::Focus() {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index c560d1c..fb7269c 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -50,6 +50,10 @@ #include "ui/gfx/selection_bound.h" #include "ui/wm/public/activation_delegate.h" +namespace aura_extra { +class WindowPositionInRootMonitor; +} + namespace wm { class ScopedTooltipDisabler; } @@ -511,8 +515,6 @@ class WindowObserver; friend class WindowObserver; - class WindowAncestorObserver; - friend class WindowAncestorObserver; friend void VerifyStaleContentOnFrameEviction( RenderWidgetHostView* render_widget_host_view); @@ -594,8 +596,8 @@ // Converts |rect| from screen coordinate to window coordinate. gfx::Rect ConvertRectFromScreen(const gfx::Rect& rect) const; - // Called when the parent window bounds change. - void HandleParentBoundsChanged(); + // Called when the bounds of `window_` relative to the root change. + void HandleBoundsInRootChanged(); // Called when the parent window hierarchy for our window changes. void ParentHierarchyChanged(); @@ -637,7 +639,8 @@ std::unique_ptr<WindowObserver> window_observer_; // Tracks the ancestors of the RWHVA window for window location changes. - std::unique_ptr<WindowAncestorObserver> ancestor_window_observer_; + std::unique_ptr<aura_extra::WindowPositionInRootMonitor> + position_in_root_observer_; // Are we in the process of closing? Tracked so we don't try to shutdown // again while inside shutdown, causing a double-free.
diff --git a/content/browser/renderer_host/text_input_client_mac.mm b/content/browser/renderer_host/text_input_client_mac.mm index 2b06f179c..bab23d5 100644 --- a/content/browser/renderer_host/text_input_client_mac.mm +++ b/content/browser/renderer_host/text_input_client_mac.mm
@@ -113,7 +113,11 @@ UMA_HISTOGRAM_LONG_TIMES("TextInputClient.FirstRect", delta * base::Time::kMicrosecondsPerMillisecond); - return first_rect_; + // `first_rect_` is in (child) frame coordinate and needs to be transformed to + // the root frame coordinate. + return gfx::Rect( + rwh->GetView()->TransformPointToRootCoordSpace(first_rect_.origin()), + first_rect_.size()); } void TextInputClientMac::SetCharacterIndexAndSignal(uint32_t index) {
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 4e649f2..80250a4 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -815,7 +815,7 @@ GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( - rph->GetID(), MSG_ROUTING_NONE, &non_network_factories); + rph->GetID(), MSG_ROUTING_NONE, origin, &non_network_factories); for (auto& pair : non_network_factories) { const std::string& scheme = pair.first;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 19c1d9d02..008c0207 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -1741,8 +1741,15 @@ void ServiceWorkerVersion::CountFeature(blink::mojom::WebFeature feature) { if (!used_features_.insert(feature).second) return; - for (auto container_host_by_uuid : controllee_map_) - container_host_by_uuid.second->CountFeature(feature); + for (auto container_host_by_uuid : controllee_map_) { + const base::WeakPtr<ServiceWorkerContainerHost>& container_host = + container_host_by_uuid.second; + // TODO(crbug.com/1253581 crbug.com/1021718): controllee_map_ should be only + // containing live container hosts. The below "if" check is a workaround for + // unmatched AddControllee / RemoveControllee calls. + if (container_host) + container_host->CountFeature(feature); + } } void ServiceWorkerVersion::set_cross_origin_embedder_policy(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index f267d0a7..b116b1f7 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1293,7 +1293,7 @@ blob_context, filesystem_context_, fallback_blob_registry); prefetch_url_loader_service_ = - base::MakeRefCounted<PrefetchURLLoaderService>(browser_context_); + std::make_unique<PrefetchURLLoaderService>(browser_context_); cookie_store_manager_ = std::make_unique<CookieStoreManager>(service_worker_context_); @@ -2022,18 +2022,21 @@ blink::mojom::PermissionStatus::GRANTED); } -void StoragePartitionImpl::OnClearSiteData(const GURL& url, - const std::string& header_value, - int load_flags, - OnClearSiteDataCallback callback) { +void StoragePartitionImpl::OnClearSiteData( + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) { DCHECK(initialized_); auto browser_context_getter = base::BindRepeating( GetBrowserContextFromStoragePartition, weak_factory_.GetWeakPtr()); auto web_contents_getter = base::BindRepeating( GetWebContents, url_loader_network_observers_.current_context()); - ClearSiteDataHandler::HandleHeader(browser_context_getter, - web_contents_getter, url, header_value, - load_flags, std::move(callback)); + + ClearSiteDataHandler::HandleHeader( + browser_context_getter, web_contents_getter, url, header_value, + load_flags, cookie_partition_key, std::move(callback)); } #if defined(OS_ANDROID)
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index e6fa2566..5838473 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -305,10 +305,12 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnClearSiteData(const GURL& url, - const std::string& header_value, - int load_flags, - OnClearSiteDataCallback callback) override; + void OnClearSiteData( + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) override; void OnLoadingStateUpdate(network::mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) override; void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, @@ -606,7 +608,7 @@ std::unique_ptr<BroadcastChannelService> broadcast_channel_service_; std::unique_ptr<BluetoothAllowedDevicesMap> bluetooth_allowed_devices_map_; scoped_refptr<BlobRegistryWrapper> blob_registry_; - scoped_refptr<PrefetchURLLoaderService> prefetch_url_loader_service_; + std::unique_ptr<PrefetchURLLoaderService> prefetch_url_loader_service_; std::unique_ptr<CookieStoreManager> cookie_store_manager_; scoped_refptr<BucketContext> bucket_context_; scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index f8894ca..e6d5b77 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -170,6 +170,7 @@ #include "ui/gfx/animation/animation.h" #if defined(OS_WIN) +#include "base/threading/thread_restrictions.h" #include "content/browser/renderer_host/dip_util.h" #include "ui/gfx/geometry/dip_util.h" #endif @@ -1934,7 +1935,7 @@ return IsLoading() && should_show_loading_ui_; } -bool WebContentsImpl::IsDocumentOnLoadCompletedInMainFrame() { +bool WebContentsImpl::IsDocumentOnLoadCompletedInPrimaryMainFrame() { // TODO(mparch): This should be moved to Page, and callers should use it // directly. return GetPrimaryPage().is_on_load_completed_in_main_document(); @@ -2829,7 +2830,7 @@ switches::kTouchEventFeatureDetectionEnabled); std::tie(prefs->available_pointer_types, prefs->available_hover_types) = - ui::GetAvailablePointerAndHoverTypes(); + GetAvailablePointerAndHoverTypes(); prefs->primary_pointer_type = static_cast<blink::mojom::PointerType>( ui::GetPrimaryPointerType(prefs->available_pointer_types)); prefs->primary_hover_type = static_cast<blink::mojom::HoverType>( @@ -7445,8 +7446,7 @@ ShowInsecureLocalhostWarningIfNeeded(render_frame_host->GetPage()); observers_.NotifyObservers( - &WebContentsObserver::DocumentOnLoadCompletedInMainFrame, - render_frame_host); + &WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame); // TODO(avi): Remove. http://crbug.com/170921 NotificationService::current()->Notify(NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, @@ -9249,4 +9249,16 @@ return nullptr; } +// static +std::pair<int, int> WebContentsImpl::GetAvailablePointerAndHoverTypes() { + // On Windows we have to temporarily allow blocking calls since + // ui::GetAvailablePointerAndHoverTypes needs to call some in order to + // figure out tablet device details in base::win::IsDeviceUsedAsATablet, + // see https://crbug.com/1262162. +#if defined(OS_WIN) + base::ScopedAllowBlocking scoped_allow_blocking; +#endif + return ui::GetAvailablePointerAndHoverTypes(); +} + } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 8845a16..2633685 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -378,7 +378,7 @@ bool IsLoading() override; double GetLoadProgress() override; bool ShouldShowLoadingUI() override; - bool IsDocumentOnLoadCompletedInMainFrame() override; + bool IsDocumentOnLoadCompletedInPrimaryMainFrame() override; bool IsWaitingForResponse() override; const net::LoadStateWithParam& GetLoadState() override; const std::u16string& GetLoadStateHost() override; @@ -1841,6 +1841,10 @@ // this WebContents (i.e. for WebContents::GetTitle()). NavigationEntry* GetNavigationEntryForTitle(); + // Wrapper for ui::GetAvailablePointerAndHoverTypes which temporarily allows + // blocking calls required on Windows when running on touch enabled devices. + static std::pair<int, int> GetAvailablePointerAndHoverTypes(); + // Data for core operation --------------------------------------------------- // Delegate for notifying our owner about stuff. Not owned by us.
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 63a531a..8bd037d8 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -4377,9 +4377,8 @@ events_.push_back("DocumentAvailableInMainFrame"); } - void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) override { - events_.push_back("DocumentOnLoadCompletedInMainFrame"); + void DocumentOnLoadCompletedInPrimaryMainFrame() override { + events_.push_back("DocumentOnLoadCompletedInPrimaryMainFrame"); } void DOMContentLoaded(RenderFrameHost* render_frame_host) override { @@ -4423,12 +4422,13 @@ EXPECT_TRUE(NavigateToURL(shell(), url)); loading_observer.Wait(); - EXPECT_THAT(loading_observer.GetEvents(), - testing::ElementsAre( - "DidStartLoading", "DidStartNavigation", - "DidFinishNavigation", "DocumentAvailableInMainFrame", - "DOMContentLoaded", "DocumentOnLoadCompletedInMainFrame", - "DidFinishLoad", "DidStopLoading")); + EXPECT_THAT( + loading_observer.GetEvents(), + testing::ElementsAre("DidStartLoading", "DidStartNavigation", + "DidFinishNavigation", + "DocumentAvailableInMainFrame", "DOMContentLoaded", + "DocumentOnLoadCompletedInPrimaryMainFrame", + "DidFinishLoad", "DidStopLoading")); } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, @@ -4496,12 +4496,13 @@ loading_observer.Wait(); - EXPECT_THAT(loading_observer.GetEvents(), - testing::ElementsAre( - "DidStartLoading", "DidStartNavigation", - "DidFinishNavigation", "DocumentAvailableInMainFrame", - "DOMContentLoaded", "DocumentOnLoadCompletedInMainFrame", - "DidFinishLoad", "DidStopLoading")); + EXPECT_THAT( + loading_observer.GetEvents(), + testing::ElementsAre("DidStartLoading", "DidStartNavigation", + "DidFinishNavigation", + "DocumentAvailableInMainFrame", "DOMContentLoaded", + "DocumentOnLoadCompletedInPrimaryMainFrame", + "DidFinishLoad", "DidStopLoading")); } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, @@ -4522,12 +4523,13 @@ response.Done(); loading_observer.Wait(); - EXPECT_THAT(loading_observer.GetEvents(), - testing::ElementsAre( - "DidStartLoading", "DidStartNavigation", - "DidFinishNavigation", "DocumentAvailableInMainFrame", - "DOMContentLoaded", "DocumentOnLoadCompletedInMainFrame", - "DidFinishLoad", "DidStopLoading")); + EXPECT_THAT( + loading_observer.GetEvents(), + testing::ElementsAre("DidStartLoading", "DidStartNavigation", + "DidFinishNavigation", + "DocumentAvailableInMainFrame", "DOMContentLoaded", + "DocumentOnLoadCompletedInPrimaryMainFrame", + "DidFinishLoad", "DidStopLoading")); } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
diff --git a/content/browser/web_contents/web_contents_view_mac_unittest.mm b/content/browser/web_contents/web_contents_view_mac_unittest.mm index acb3365..843333b0 100644 --- a/content/browser/web_contents/web_contents_view_mac_unittest.mm +++ b/content/browser/web_contents/web_contents_view_mac_unittest.mm
@@ -60,14 +60,28 @@ } // namespace TEST_F(WebContentsViewMacTest, ShowHideParent) { - EXPECT_EQ(Visibility::VISIBLE, web_contents()->GetVisibility()); + // A web contents that has never become visible starts off with a VISIBLE + // visibility state. Until it's made visible for the first time the flag + // `did_first_set_visible_` remains false, causing it to ignore all visibility + // state changes other than VISIBLE. This means if we don't order the window + // front before starting our test the web contents will report VISIBLE at all + // three checks. + [window_ orderFront:nil]; + EXPECT_EQ(content::Visibility::VISIBLE, web_contents()->GetVisibility()); [[window_ contentView] setHidden:YES]; - EXPECT_EQ(Visibility::HIDDEN, web_contents()->GetVisibility()); + EXPECT_EQ(content::Visibility::HIDDEN, web_contents()->GetVisibility()); [[window_ contentView] setHidden:NO]; - EXPECT_EQ(Visibility::VISIBLE, web_contents()->GetVisibility()); + EXPECT_EQ(content::Visibility::VISIBLE, web_contents()->GetVisibility()); } TEST_F(WebContentsViewMacTest, OccludeView) { + // A web contents that has never become visible starts off with a VISIBLE + // visibility state. Until it's made visible for the first time the flag + // `did_first_set_visible_` remains false, causing it to ignore all visibility + // state changes other than VISIBLE. This means if we don't order the window + // front before starting our test the web contents will report VISIBLE at all + // three checks. + [window_ orderFront:nil]; EXPECT_EQ(Visibility::VISIBLE, web_contents()->GetVisibility()); [window_ setPretendIsOccluded:YES]; EXPECT_EQ(Visibility::OCCLUDED, web_contents()->GetVisibility());
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc index f2a25d96..a4cb8fb 100644 --- a/content/browser/webauth/authenticator_common.cc +++ b/content/browser/webauth/authenticator_common.cc
@@ -979,14 +979,8 @@ ClientDataRequestType::kU2fSign, options->relying_party_id, options->challenge, /*is_cross_origin=*/false); } else if (payment) { - auto* web_contents = WebContents::FromRenderFrameHost(GetRenderFrameHost()); - if (!web_contents) { - CompleteGetAssertionRequest( - blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR); - return; - } url::Origin top_origin = - web_contents->GetMainFrame()->GetLastCommittedOrigin(); + GetRenderFrameHost()->GetOutermostMainFrame()->GetLastCommittedOrigin(); client_data_json_ = BuildClientDataJson( ClientDataRequestType::kPaymentGet, caller_origin_.Serialize(), options->challenge, is_cross_origin, std::move(payment),
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 17efaa66..ba648f7 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -354,39 +354,17 @@ void FederatedAuthRequestImpl::OnClientIdMetadataResponseReceived( IdpNetworkRequestManager::FetchStatus status, IdpNetworkRequestManager::ClientIdMetadata data) { - switch (status) { - case IdpNetworkRequestManager::FetchStatus::kHttpNotFoundError: { - CompleteRequest( - RequestIdTokenStatus::kErrorFetchingClientIdMetadataHttpNotFound, ""); - return; - } - case IdpNetworkRequestManager::FetchStatus::kNoResponseError: { - CompleteRequest( - RequestIdTokenStatus::kErrorFetchingClientIdMetadataNoResponse, ""); - return; - } - case IdpNetworkRequestManager::FetchStatus::kInvalidResponseError: { - CompleteRequest( - RequestIdTokenStatus::kErrorFetchingClientIdMetadataInvalidResponse, - ""); - return; - } - case IdpNetworkRequestManager::FetchStatus::kInvalidRequestError: { - NOTREACHED(); - return; - } - case IdpNetworkRequestManager::FetchStatus::kSuccess: { - client_id_metadata_ = data; - network_manager_->SendAccountsRequest( - endpoints_.accounts, - request_dialog_controller_->GetBrandIconIdealSize(), - request_dialog_controller_->GetBrandIconMinimumSize(), - base::BindOnce(&FederatedAuthRequestImpl::DownloadBitmap, - weak_ptr_factory_.GetWeakPtr()), - base::BindOnce(&FederatedAuthRequestImpl::OnAccountsResponseReceived, - weak_ptr_factory_.GetWeakPtr())); - } - } + // TODO(cbiesinger): we currently do not send referer to IDP when fetching the + // client metadata so we cannot get any response. Making client metadata + // optional until the fix is in place. https://crbug.com/1284781. + client_id_metadata_ = data; + network_manager_->SendAccountsRequest( + endpoints_.accounts, request_dialog_controller_->GetBrandIconIdealSize(), + request_dialog_controller_->GetBrandIconMinimumSize(), + base::BindOnce(&FederatedAuthRequestImpl::DownloadBitmap, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&FederatedAuthRequestImpl::OnAccountsResponseReceived, + weak_ptr_factory_.GetWeakPtr())); } void FederatedAuthRequestImpl::OnSigninApproved(
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 48a487be..b24e927 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -38,6 +38,7 @@ const std::set<int> GetContentResourceIds() { return std::set<int>{ IDR_GEOMETRY_MOJOM_WEBUI_JS, + IDR_IMAGE_MOJOM_WEBUI_JS, IDR_ORIGIN_MOJO_HTML, IDR_ORIGIN_MOJO_JS, IDR_ORIGIN_MOJO_WEBUI_JS,
diff --git a/content/browser/worker_host/worker_script_fetcher.cc b/content/browser/worker_host/worker_script_fetcher.cc index 8af7f8c..99831e64 100644 --- a/content/browser/worker_host/worker_script_fetcher.cc +++ b/content/browser/worker_host/worker_script_fetcher.cc
@@ -475,7 +475,8 @@ GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( - worker_process_id, MSG_ROUTING_NONE, &non_network_factories); + worker_process_id, MSG_ROUTING_NONE, + request_initiator_storage_key.origin(), &non_network_factories); break; }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index bd53185..70f47028 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -381,6 +381,7 @@ {"PartitionedCookies", net::features::kPartitionedCookies}, {"PrefersColorSchemeClientHintHeader", blink::features::kPrefersColorSchemeClientHintHeader}, + {"FirstPartySets", net::features::kFirstPartySets}, {"SanitizerAPI", blink::features::kSanitizerAPI}, {"StorageAccessAPI", blink::features::kStorageAccessAPI}, {"TargetBlankImpliesNoOpener",
diff --git a/content/common/url_schemes.h b/content/common/url_schemes.h index 3d3c663..ebdce86 100644 --- a/content/common/url_schemes.h +++ b/content/common/url_schemes.h
@@ -26,8 +26,8 @@ // See comment in ContentClient::AddAdditionalSchemes for explanations. These // getters can be invoked on any thread. -const std::vector<std::string>& GetSavableSchemes(); -const std::vector<std::string>& GetServiceWorkerSchemes(); +CONTENT_EXPORT const std::vector<std::string>& GetSavableSchemes(); +CONTENT_EXPORT const std::vector<std::string>& GetServiceWorkerSchemes(); } // namespace content
diff --git a/content/content_resources.grd b/content/content_resources.grd index 5a005f48..bf9d451 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd
@@ -25,6 +25,7 @@ <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON" file="browser/resources/devtools/devtools_touch_cursor.png" type="BINDATA" /> <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X" file="browser/resources/devtools/devtools_touch_cursor_2x.png" type="BINDATA" /> <include name="IDR_GEOMETRY_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/ui/gfx/geometry/mojom/geometry.mojom-webui.js" resource_path="mojo/ui/gfx/geometry/mojom/geometry.mojom-webui.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_IMAGE_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/ui/gfx/image/mojom/image.mojom-webui.js" resource_path="mojo/ui/gfx/image/mojom/image.mojom-webui.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_HISTOGRAMS_INTERNALS_HTML" file="browser/resources/histograms/histograms_internals.html" type="BINDATA" /> <include name="IDR_HISTOGRAMS_INTERNALS_JS" file="browser/resources/histograms/histograms_internals.js" type="BINDATA" /> <include name="IDR_HISTOGRAMS_INTERNALS_CSS" file="browser/resources/histograms/histograms_internals.css" type="BINDATA" />
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 0181724..12dad43 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -239,9 +239,6 @@ "java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java", "java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityState.java", "java/src/org/chromium/content/browser/accessibility/OViewStructureBuilder.java", - "java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java", - "java/src/org/chromium/content/browser/accessibility/PieWebContentsAccessibility.java", - "java/src/org/chromium/content/browser/accessibility/RWebContentsAccessibility.java", "java/src/org/chromium/content/browser/accessibility/ViewStructureBuilder.java", "java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityDelegate.java", "java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java index f87f596..95b5ea9 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java
@@ -6,7 +6,6 @@ import android.os.Bundle; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; import java.util.LinkedList; @@ -81,7 +80,7 @@ */ private String actionToString(int action, Bundle arguments) { StringBuilder builder = new StringBuilder(); - builder.append(actionIntToString(action)); + builder.append(AccessibilityNodeInfoUtils.toString(action)); // If we have non-null arguments, add them to our String for this action. if (arguments != null) { @@ -180,96 +179,4 @@ // Return generated String. return builder.toString(); } - - /** - * Helper method to convert given int action into a readable String. - * @param action int action - * @return String action text - */ - public static String actionIntToString(int action) { - switch (action) { - case AccessibilityNodeInfo.ACTION_FOCUS: - return "ACTION_FOCUS"; - case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: - return "ACTION_CLEAR_FOCUS"; - case AccessibilityNodeInfo.ACTION_SELECT: - return "ACTION_SELECT"; - case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: - return "ACTION_CLEAR_SELECTION"; - case AccessibilityNodeInfo.ACTION_CLICK: - return "ACTION_CLICK"; - case AccessibilityNodeInfo.ACTION_LONG_CLICK: - return "ACTION_LONG_CLICK"; - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - return "ACTION_ACCESSIBILITY_FOCUS"; - case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - return "ACTION_CLEAR_ACCESSIBILITY_FOCUS"; - case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: - return "ACTION_NEXT_AT_MOVEMENT_GRANULARITY"; - case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: - return "ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY"; - case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT: - return "ACTION_NEXT_HTML_ELEMENT"; - case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT: - return "ACTION_PREVIOUS_HTML_ELEMENT"; - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: - return "ACTION_SCROLL_FORWARD"; - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: - return "ACTION_SCROLL_BACKWARD"; - case AccessibilityNodeInfo.ACTION_CUT: - return "ACTION_CUT"; - case AccessibilityNodeInfo.ACTION_COPY: - return "ACTION_COPY"; - case AccessibilityNodeInfo.ACTION_PASTE: - return "ACTION_PASTE"; - case AccessibilityNodeInfo.ACTION_SET_SELECTION: - return "ACTION_SET_SELECTION"; - case AccessibilityNodeInfo.ACTION_EXPAND: - return "ACTION_EXPAND"; - case AccessibilityNodeInfo.ACTION_COLLAPSE: - return "ACTION_COLLAPSE"; - case AccessibilityNodeInfo.ACTION_DISMISS: - return "ACTION_DISMISS"; - case AccessibilityNodeInfo.ACTION_SET_TEXT: - return "ACTION_SET_TEXT"; - - // These come from WebContentsAccessibilityImpl to support earlier Android versions. - case WebContentsAccessibilityImpl.ACTION_SHOW_ON_SCREEN: - return "ACTION_SHOW_ON_SCREEN"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_TO_POSITION: - return "ACTION_SCROLL_TO_POSITION"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_UP: - return "ACTION_SCROLL_UP"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_LEFT: - return "ACTION_SCROLL_LEFT"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_DOWN: - return "ACTION_SCROLL_DOWN"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_RIGHT: - return "ACTION_SCROLL_RIGHT"; - case WebContentsAccessibilityImpl.ACTION_PAGE_DOWN: - return "ACTION_PAGE_DOWN"; - case WebContentsAccessibilityImpl.ACTION_PAGE_UP: - return "ACTION_PAGE_UP"; - case WebContentsAccessibilityImpl.ACTION_PAGE_LEFT: - return "ACTION_PAGE_LEFT"; - case WebContentsAccessibilityImpl.ACTION_PAGE_RIGHT: - return "ACTION_PAGE_RIGHT"; - case WebContentsAccessibilityImpl.ACTION_SET_PROGRESS: - return "ACTION_SET_PROGRESS"; - case WebContentsAccessibilityImpl.ACTION_CONTEXT_CLICK: - return "ACTION_CONTEXT_CLICK"; - case WebContentsAccessibilityImpl.ACTION_SHOW_TOOLTIP: - return "ACTION_SHOW_TOOLTIP"; - case WebContentsAccessibilityImpl.ACTION_HIDE_TOOLTIP: - return "ACTION_HIDE_TOOLTIP"; - case WebContentsAccessibilityImpl.ACTION_PRESS_AND_HOLD: - return "ACTION_PRESS_AND_HOLD"; - case WebContentsAccessibilityImpl.ACTION_IME_ENTER: - return "ACTION_IME_ENTER"; - case WebContentsAccessibilityImpl.ACTION_MOVE_WINDOW: - return "ACTION_MOVE_WINDOW"; - default: - return "ACTION_UNKNOWN"; - } - } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java index f387091..b3eb99b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java
@@ -4,6 +4,37 @@ package org.chromium.content.browser.accessibility; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COLLAPSE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CONTEXT_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COPY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CUT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_EXPAND; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_IME_ENTER; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_DOWN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_LEFT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_RIGHT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PASTE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_DOWN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_LEFT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_RIGHT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_TEXT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SHOW_ON_SCREEN; + import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_OFFSCREEN; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_SUPPORTED_ELEMENTS; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_UNCLIPPED_BOTTOM; @@ -14,7 +45,8 @@ import android.os.Bundle; import android.text.InputType; import android.text.TextUtils; -import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import java.util.ArrayList; import java.util.Collections; @@ -30,8 +62,7 @@ * @param node Object to create a toString for * @return String Custom toString result for the given object */ - public static String toString(AccessibilityNodeInfo node) { - // Guard against null inputs. + public static String toString(AccessibilityNodeInfoCompat node) { if (node == null) return ""; StringBuilder builder = new StringBuilder(); @@ -145,7 +176,7 @@ } // Various helper methods to print custom toStrings for objects. - private static String toString(AccessibilityNodeInfo.CollectionInfo info) { + private static String toString(AccessibilityNodeInfoCompat.CollectionInfoCompat info) { // Only include the isHierarchical boolean if true, since it is more often false, and // ignore selection mode, which is not set by Chrome. String prefix = "["; @@ -156,7 +187,7 @@ "%srows=%s, cols=%s]", prefix, info.getRowCount(), info.getColumnCount()); } - private static String toString(AccessibilityNodeInfo.CollectionItemInfo info) { + private static String toString(AccessibilityNodeInfoCompat.CollectionItemInfoCompat info) { // Only include isHeading and isSelected if true, since both are more often false. String prefix = "["; if (info.isHeading()) { @@ -169,25 +200,26 @@ info.getRowIndex(), info.getRowSpan(), info.getColumnIndex(), info.getColumnSpan()); } - private static String toString(AccessibilityNodeInfo.RangeInfo info) { + private static String toString(AccessibilityNodeInfoCompat.RangeInfoCompat info) { // Chrome always uses the float range type, so only print values of RangeInfo. return String.format( "[current=%s, min=%s, max=%s]", info.getCurrent(), info.getMin(), info.getMax()); } - private static String toString(List<AccessibilityNodeInfo.AccessibilityAction> actionList) { + private static String toString( + List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> actionList) { // Sort actions list to ensure consistent output of tests. Collections.sort(actionList, (a1, b2) -> Integer.compare(a1.getId(), b2.getId())); List<String> actionStrings = new ArrayList<String>(); StringBuilder builder = new StringBuilder(); builder.append("["); - for (AccessibilityNodeInfo.AccessibilityAction action : actionList) { + for (AccessibilityNodeInfoCompat.AccessibilityActionCompat action : actionList) { // 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() == WebContentsAccessibilityImpl.ACTION_SHOW_ON_SCREEN - || action.getId() == WebContentsAccessibilityImpl.ACTION_CONTEXT_CLICK) { + if (action.equals(ACTION_NEXT_HTML_ELEMENT) + || action.equals(ACTION_PREVIOUS_HTML_ELEMENT) + || action.equals(ACTION_SHOW_ON_SCREEN) + || action.equals(ACTION_CONTEXT_CLICK)) { continue; } @@ -198,76 +230,68 @@ return builder.toString(); } - private static String toString(int action) { - switch (action) { - // These could potentially be added to any given node. - case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: - return "NEXT"; - case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: - return "PREVIOUS"; - case AccessibilityNodeInfo.ACTION_SET_TEXT: - return "SET_TEXT"; - case AccessibilityNodeInfo.ACTION_PASTE: - return "PASTE"; - case WebContentsAccessibilityImpl.ACTION_IME_ENTER: - return "IME_ENTER"; - case AccessibilityNodeInfo.ACTION_SET_SELECTION: - return "SET_SELECTION"; - case AccessibilityNodeInfo.ACTION_CUT: - return "CUT"; - case AccessibilityNodeInfo.ACTION_COPY: - return "COPY"; - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: - return "SCROLL_FORWARD"; - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: - return "SCROLL_BACKWARD"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_UP: - return "SCROLL_UP"; - case WebContentsAccessibilityImpl.ACTION_PAGE_UP: - return "PAGE_UP"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_DOWN: - return "SCROLL_DOWN"; - case WebContentsAccessibilityImpl.ACTION_PAGE_DOWN: - return "PAGE_DOWN"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_LEFT: - return "SCROLL_LEFT"; - case WebContentsAccessibilityImpl.ACTION_PAGE_LEFT: - return "PAGE_LEFT"; - case WebContentsAccessibilityImpl.ACTION_SCROLL_RIGHT: - return "SCROLL_RIGHT"; - case WebContentsAccessibilityImpl.ACTION_PAGE_RIGHT: - return "PAGE_RIGHT"; - case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: - return "CLEAR_FOCUS"; - case AccessibilityNodeInfo.ACTION_FOCUS: - return "FOCUS"; - case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - return "CLEAR_AX_FOCUS"; - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - return "AX_FOCUS"; - case AccessibilityNodeInfo.ACTION_CLICK: - return "CLICK"; - case AccessibilityNodeInfo.ACTION_EXPAND: - return "EXPAND"; - case AccessibilityNodeInfo.ACTION_COLLAPSE: - return "COLLAPSE"; - case WebContentsAccessibilityImpl.ACTION_SET_PROGRESS: - return "SET_PROGRESS"; - - // The long click action is deliberately never be added to a node. - case AccessibilityNodeInfo.ACTION_LONG_CLICK: - // These are the remaining potential actions which Chrome does not implement. - case AccessibilityNodeInfo.ACTION_DISMISS: - case AccessibilityNodeInfo.ACTION_SELECT: - case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: - case WebContentsAccessibilityImpl.ACTION_SCROLL_TO_POSITION: - case WebContentsAccessibilityImpl.ACTION_MOVE_WINDOW: - case WebContentsAccessibilityImpl.ACTION_SHOW_TOOLTIP: - case WebContentsAccessibilityImpl.ACTION_HIDE_TOOLTIP: - case WebContentsAccessibilityImpl.ACTION_PRESS_AND_HOLD: - default: - return "NOT_IMPLEMENTED"; + public static String toString(int action) { + if (action == ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId()) { + return "NEXT"; + } else if (action == ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId()) { + return "PREVIOUS"; + } else if (action == ACTION_SET_TEXT.getId()) { + return "SET_TEXT"; + } else if (action == ACTION_PASTE.getId()) { + return "PASTE"; + } else if (action == ACTION_IME_ENTER.getId()) { + return "IME_ENTER"; + } else if (action == ACTION_SET_SELECTION.getId()) { + return "SET_SELECTION"; + } else if (action == ACTION_CUT.getId()) { + return "CUT"; + } else if (action == ACTION_COPY.getId()) { + return "COPY"; + } else if (action == ACTION_SCROLL_FORWARD.getId()) { + return "SCROLL_FORWARD"; + } else if (action == ACTION_SCROLL_BACKWARD.getId()) { + return "SCROLL_BACKWARD"; + } else if (action == ACTION_SCROLL_UP.getId()) { + return "SCROLL_UP"; + } else if (action == ACTION_PAGE_UP.getId()) { + return "PAGE_UP"; + } else if (action == ACTION_SCROLL_DOWN.getId()) { + return "SCROLL_DOWN"; + } else if (action == ACTION_PAGE_DOWN.getId()) { + return "PAGE_DOWN"; + } else if (action == ACTION_SCROLL_LEFT.getId()) { + return "SCROLL_LEFT"; + } else if (action == ACTION_PAGE_LEFT.getId()) { + return "PAGE_LEFT"; + } else if (action == ACTION_SCROLL_RIGHT.getId()) { + return "SCROLL_RIGHT"; + } else if (action == ACTION_PAGE_RIGHT.getId()) { + return "PAGE_RIGHT"; + } else if (action == ACTION_CLEAR_FOCUS.getId()) { + return "CLEAR_FOCUS"; + } else if (action == ACTION_FOCUS.getId()) { + return "FOCUS"; + } else if (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS.getId()) { + return "CLEAR_AX_FOCUS"; + } else if (action == ACTION_ACCESSIBILITY_FOCUS.getId()) { + return "AX_FOCUS"; + } else if (action == ACTION_CLICK.getId()) { + return "CLICK"; + } else if (action == ACTION_EXPAND.getId()) { + return "EXPAND"; + } else if (action == ACTION_COLLAPSE.getId()) { + return "COLLAPSE"; + } else if (action == ACTION_SET_PROGRESS.getId()) { + return "SET_PROGRESS"; + } else { + return "NOT_IMPLEMENTED"; } + /* + * The ACTION_LONG_CLICK click action is deliberately never be added to a node. + * These are the remaining potential actions which Chrome does not implement: + * ACTION_DISMISS, ACTION_SELECT, ACTION_CLEAR_SELECTION, ACTION_SCROLL_TO_POSITION, + * ACTION_MOVE_WINDOW, ACTION_SHOW_TOOLTIP, ACTION_HIDE_TOOLTIP, ACTION_PRESS_AND_HOLD + */ } private static String toString(Bundle extras) { @@ -303,6 +327,12 @@ continue; } + // The AccessibilityNodeInfoCompat class uses the extras for backwards compatibility, + // so exclude anything that contains the classname in the key. + if (key.contains("AccessibilityNodeInfoCompat")) { + continue; + } + // Simplify the key String before printing to make test outputs easier to read. bundleStrings.add(key.replace("AccessibilityNodeInfo.", "") + "=\"" + extras.get(key).toString() + "\"");
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java deleted file mode 100644 index f843b5d..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2017 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 android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH; -import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX; -import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; - -import android.annotation.TargetApi; -import android.graphics.Rect; -import android.graphics.RectF; -import android.os.Build; -import android.os.Bundle; -import android.view.accessibility.AccessibilityNodeInfo; - -import org.chromium.base.annotations.JNINamespace; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Subclass of WebContentsAccessibility for O - */ -@JNINamespace("content") -@TargetApi(Build.VERSION_CODES.O) -public class OWebContentsAccessibility extends WebContentsAccessibilityImpl { - // static instances of the two types of actions that can be added to nodes as the array is not - // node-specific and this will save on recreation of many lists per page. - private static List<String> sTextCharacterLocation = - Arrays.asList(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY); - - private static List<String> sRequestImageData = - Arrays.asList(EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY); - - // Set of all nodes that have received a request to populate image data. The request only needs - // to be run once per node, and it completes asynchronously. We track which nodes have already - // started the async request so that if downstream apps request the same node multiple times - // we can avoid doing the extra work. - private final Set<Integer> mImageDataRequestedNodes = new HashSet<Integer>(); - - OWebContentsAccessibility(AccessibilityDelegate delegate) { - super(delegate); - } - - @Override - public void clearNodeInfoCacheForGivenId(int virtualViewId) { - if (mImageDataRequestedNodes != null) { - mImageDataRequestedNodes.remove(virtualViewId); - } - super.clearNodeInfoCacheForGivenId(virtualViewId); - } - - @Override - protected void setAccessibilityNodeInfoOAttributes(AccessibilityNodeInfo node, - boolean hasCharacterLocations, boolean hasImage, String hint) { - node.setHintText(hint); - - if (hasCharacterLocations) { - node.setAvailableExtraData(sTextCharacterLocation); - } else if (hasImage) { - node.setAvailableExtraData(sRequestImageData); - } - } - - @Override - public void addExtraDataToAccessibilityNodeInfo( - int virtualViewId, AccessibilityNodeInfo info, String extraDataKey, Bundle arguments) { - switch (extraDataKey) { - case EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY: - getExtraDataTextCharacterLocations(virtualViewId, info, arguments); - break; - case EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY: - getImageData(virtualViewId, info); - break; - } - } - - private void getExtraDataTextCharacterLocations( - int virtualViewId, AccessibilityNodeInfo info, Bundle arguments) { - if (!areInlineTextBoxesLoaded(virtualViewId)) { - loadInlineTextBoxes(virtualViewId); - } - - int positionInfoStartIndex = - arguments.getInt(EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX, -1); - int positionInfoLength = - arguments.getInt(EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH, -1); - if (positionInfoLength <= 0 || positionInfoStartIndex < 0) return; - - int[] coords = getCharacterBoundingBoxes( - virtualViewId, positionInfoStartIndex, positionInfoLength); - if (coords == null) return; - assert coords.length == positionInfoLength * 4; - - RectF[] boundingRects = new RectF[positionInfoLength]; - for (int i = 0; i < positionInfoLength; i++) { - Rect rect = new Rect( - coords[4 * i + 0], coords[4 * i + 1], coords[4 * i + 2], coords[4 * i + 3]); - convertWebRectToAndroidCoordinates(rect, info.getExtras()); - boundingRects[i] = new RectF(rect); - } - - info.getExtras().putParcelableArray(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY, boundingRects); - } - - private void getImageData(int virtualViewId, AccessibilityNodeInfo info) { - boolean hasSentPreviousRequest = mImageDataRequestedNodes.contains(virtualViewId); - // If the below call returns true, then image data has been set on the node. - if (!WebContentsAccessibilityImplJni.get().getImageData(mNativeObj, - OWebContentsAccessibility.this, info, virtualViewId, hasSentPreviousRequest)) { - // If the above call returns false, then the data was missing. The native-side code - // will have started the asynchronous process to populate the image data if no previous - // request has been sent. Add this |virtualViewId| to the list of requested nodes. - mImageDataRequestedNodes.add(virtualViewId); - } - } -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/PieWebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/PieWebContentsAccessibility.java deleted file mode 100644 index ab744ffe..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/PieWebContentsAccessibility.java +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content.browser.accessibility; - -import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_APPEARED; - -import android.annotation.TargetApi; -import android.os.Build; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import android.view.autofill.AutofillManager; - -import org.chromium.base.annotations.JNINamespace; - -/** - * Subclass of WebContentsAccessibility for P - */ -@JNINamespace("content") -@TargetApi(Build.VERSION_CODES.P) -public class PieWebContentsAccessibility extends OWebContentsAccessibility { - PieWebContentsAccessibility(AccessibilityDelegate delegate) { - super(delegate); - AutofillManager autofillManager = mContext.getSystemService(AutofillManager.class); - if (autofillManager != null && autofillManager.isEnabled()) { - // Native accessibility is usually initialized when getAccessibilityNodeProvider is - // called, but the Autofill compatibility bridge only calls that method after it has - // received the first accessibility events. To solve the chicken-and-egg problem, - // always initialize the native parts when the user has an Autofill service enabled. - refreshState(); - getAccessibilityNodeProvider(); - } - } - - @Override - protected void handleDialogModalOpened(int virtualViewId) { - if (isAccessibilityEnabled()) { - AccessibilityEvent event = - AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - if (event == null) return; - - event.setContentChangeTypes(CONTENT_CHANGE_TYPE_PANE_APPEARED); - event.setSource(mView, virtualViewId); - super.requestSendAccessibilityEvent(event); - } - } - - @Override - protected void setAccessibilityNodeInfoPaneTitle(AccessibilityNodeInfo node, String title) { - node.setPaneTitle(title); - } -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/RWebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/RWebContentsAccessibility.java deleted file mode 100644 index b0350b1..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/RWebContentsAccessibility.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content.browser.accessibility; - -import android.annotation.TargetApi; -import android.os.Build; -import android.view.accessibility.AccessibilityNodeInfo; - -import org.chromium.base.annotations.JNINamespace; - -/** - * Subclass of WebContentsAccessibility for R - */ -@JNINamespace("content") -@TargetApi(Build.VERSION_CODES.R) -public class RWebContentsAccessibility extends PieWebContentsAccessibility { - RWebContentsAccessibility(AccessibilityDelegate delegate) { - super(delegate); - } - - @Override - protected void setAccessibilityNodeInfoText(AccessibilityNodeInfo node, String text, - boolean annotateAsLink, boolean isEditableText, String language, int[] suggestionStarts, - int[] suggestionEnds, String[] suggestions, String stateDescription) { - super.setAccessibilityNodeInfoText(node, text, annotateAsLink, isEditableText, language, - suggestionStarts, suggestionEnds, suggestions, stateDescription); - - // For Android R and higher, we will not rely on concatenating text and stateDescription, - // and will instead revert text to original content and set stateDescription separately. - if (stateDescription != null && !stateDescription.isEmpty()) { - CharSequence computedText = computeText( - text, annotateAsLink, language, suggestionStarts, suggestionEnds, suggestions); - - node.setText(computedText); - node.setStateDescription(stateDescription); - } - } -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index 76c0cc5..c99cef7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -4,6 +4,48 @@ package org.chromium.content.browser.accessibility; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COLLAPSE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CONTEXT_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COPY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CUT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_EXPAND; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_IME_ENTER; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_DOWN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_LEFT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_RIGHT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PASTE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_DOWN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_LEFT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_RIGHT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_TEXT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SHOW_ON_SCREEN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.BroadcastReceiver; @@ -13,6 +55,7 @@ import android.content.IntentFilter; import android.content.ReceiverCallNotAllowedException; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Build; import android.os.Bundle; import android.provider.Settings; @@ -29,11 +72,13 @@ import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityNodeProvider; +import android.view.autofill.AutofillManager; import android.view.inputmethod.EditorInfo; import androidx.annotation.VisibleForTesting; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeProviderCompat; import org.chromium.base.ContextUtils; import org.chromium.base.UserData; @@ -55,6 +100,7 @@ import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -66,56 +112,25 @@ * Implementation of {@link WebContentsAccessibility} interface. * Native accessibility for a {@link WebContents}. Actual native instance is * created lazily upon the first request from Android framework on - *{@link AccessibilityNodeProvider}, and shares the lifetime with {@link WebContents}. + * {@link AccessibilityNodeProvider}, and shares the lifetime with {@link WebContents}. + * Internally this class uses the {@link AccessibilityNodeProviderCompat} interface, and uses + * the {@link AccessibilityNodeInfoCompat} object for the virtual tree, but will unwrap and surface + * the non-Compat versions of these for any clients. */ @JNINamespace("content") -public class WebContentsAccessibilityImpl extends AccessibilityNodeProvider +public class WebContentsAccessibilityImpl extends AccessibilityNodeProviderCompat implements AccessibilityStateChangeListener, WebContentsAccessibility, WindowEventObserver, UserData, BrowserAccessibilityState.Listener { // The following constants have been hard coded so we can support actions newer than our // minimum SDK without having to break methods into a series of subclasses. - // Constants defined by AccessibilityNodeInfo per SDK - // source: https://developer.android.com/reference/android/R.id.html - - // Constants defined in the K SDK. (API Level 19, Android 4) - private static final int ACTION_COLLAPSE = 0x00080000; - private static final int ACTION_EXPAND = 0x00040000; - - // Constants defined in the L SDK. (API Level 21+22, Android 5) - private static final int ACTION_SET_TEXT = 0x00200000; - private static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = - "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE"; - - // Constants defined in the M SDK. (API Level 23, Android 6) - public static final int ACTION_CONTEXT_CLICK = 0x0102003c; - public static final int ACTION_SHOW_ON_SCREEN = 0x01020036; - public static final int ACTION_SCROLL_UP = 0x01020038; - public static final int ACTION_SCROLL_DOWN = 0x0102003a; - public static final int ACTION_SCROLL_LEFT = 0x01020039; - public static final int ACTION_SCROLL_RIGHT = 0x0102003b; - public static final int ACTION_SCROLL_TO_POSITION = 0x01020037; - - // Constants defined in the N SDK. (API Level 24+25, Android 7) - public static final int ACTION_SET_PROGRESS = 0x0102003d; - public static final String ACTION_ARGUMENT_PROGRESS_VALUE = - "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE"; - - // Constants defined in the O SDK. (API Level 26+27, Android 8) - public static final int ACTION_MOVE_WINDOW = 0x01020042; - - // Constants defined in the P SDK. (API Level 28, Android 9) - public static final int ACTION_SHOW_TOOLTIP = 0x01020044; - public static final int ACTION_HIDE_TOOLTIP = 0x01020045; - - // Constants defined in the Q SDK. (API Level 29, Android 10) - public static final int ACTION_PAGE_UP = 0x01020046; - public static final int ACTION_PAGE_DOWN = 0x01020047; - public static final int ACTION_PAGE_LEFT = 0x01020048; - public static final int ACTION_PAGE_RIGHT = 0x01020049; - - // Constants defined in the R SDK. (API Level 30, Android 11) - public static final int ACTION_IME_ENTER = 0x01020054; - public static final int ACTION_PRESS_AND_HOLD = 0x0102004a; + // TODO(mschillaci): Remove these once they are added to the AccessibilityNodeInfoCompat class. + public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = + "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY"; + public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = + "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX"; + public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = + "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH"; + public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 0x00000010; // Constants defined for AccessibilityNodeInfo Bundle extras keys. public static final String EXTRAS_KEY_CHROME_ROLE = "AccessibilityNodeInfo.chromeRole"; @@ -163,8 +178,12 @@ private static final int EVENTS_DROPPED_HISTOGRAM_MAX_BUCKET = 10000; private static final int EVENTS_DROPPED_HISTOGRAM_BUCKET_COUNT = 100; - private static SparseArray<AccessibilityAction> sAccessibilityActionMap = - new SparseArray<AccessibilityAction>(); + // Static instances of the two types of extra data keys that can be added to nodes. + private static final List<String> sTextCharacterLocation = + Collections.singletonList(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY); + + private static final List<String> sRequestImageData = + Collections.singletonList(EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY); private final AccessibilityDelegate mDelegate; protected AccessibilityManager mAccessibilityManager; @@ -217,9 +236,9 @@ // Accessibility touch exploration state. private boolean mTouchExplorationEnabled; - // This array maps a given virtualViewId to an |AccessibilityNodeInfo| for that view. We use - // this to update a node quickly rather than building from one scratch each time. - private SparseArray<AccessibilityNodeInfo> mNodeInfoCache = new SparseArray<>(); + // This array maps a given virtualViewId to an |AccessibilityNodeInfoCompat| for that view. We + // use this to update a node quickly rather than building from one scratch each time. + private SparseArray<AccessibilityNodeInfoCompat> mNodeInfoCache = new SparseArray<>(); // This handles the dispatching of accessibility events. It acts as an intermediary where we can // apply throttling rules, delay event construction, etc. @@ -237,6 +256,12 @@ private int mTotalEnqueuedEvents; private int mTotalDispatchedEvents; + // Set of all nodes that have received a request to populate image data. The request only needs + // to be run once per node, and it completes asynchronously. We track which nodes have already + // started the async request so that if downstream apps request the same node multiple times + // we can avoid doing the extra work. + private final Set<Integer> mImageDataRequestedNodes = new HashSet<Integer>(); + /** * Create a WebContentsAccessibilityImpl object. */ @@ -264,13 +289,6 @@ } private static WebContentsAccessibilityImpl createForDelegate(AccessibilityDelegate delegate) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - return new RWebContentsAccessibility(delegate); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - return new PieWebContentsAccessibility(delegate); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - return new OWebContentsAccessibility(delegate); - } return new WebContentsAccessibilityImpl(delegate); } @@ -350,6 +368,18 @@ } // If the AXTree is not provided, native is initialized lazily, when node provider is // actually requested. + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + AutofillManager autofillManager = mContext.getSystemService(AutofillManager.class); + if (autofillManager != null && autofillManager.isEnabled()) { + // Native accessibility is usually initialized when getAccessibilityNodeProvider is + // called, but the Autofill compatibility bridge only calls that method after it has + // received the first accessibility events. To solve the chicken-and-egg problem, + // always initialize the native parts when the user has an Autofill service enabled. + refreshState(); + getAccessibilityNodeProvider(); + } + } } /** @@ -558,6 +588,22 @@ @Override public AccessibilityNodeProvider getAccessibilityNodeProvider() { + // The |WebContentsAccessibilityImpl| class will rely on the Compat library, but we will + // not require other parts of Chrome to do the same for simplicity, so unwrap the + // |AccessibilityNodeProvider| object before returning. + AccessibilityNodeProviderCompat anpc = getAccessibilityNodeProviderCompat(); + if (anpc == null) return null; + + return (AccessibilityNodeProvider) anpc.getProvider(); + } + + /** + * Allows clients to get an |AccessibilityNodeProviderCompat| instance if they do not want + * the unwrapped version that is available with getAccessibilityNodeProvider above. + * + * @return AccessibilityNodeProviderCompat (this) + */ + public AccessibilityNodeProviderCompat getAccessibilityNodeProviderCompat() { if (mIsObscuredByAnotherView) return null; if (!isNativeInitialized()) { @@ -576,6 +622,7 @@ mNativeObj, WebContentsAccessibilityImpl.this, screenReaderMode); return null; } + return this; } @@ -589,8 +636,8 @@ @CalledByNative public String generateAccessibilityNodeInfoString(int virtualViewId) { - // If accessibility isn't enabled, all the AccessibilityNodeInfo objects will be null, so - // temporarily set the |mAccessibilityEnabledOverride| flag to true, then disable it. + // If accessibility isn't enabled, all the AccessibilityNodeInfoCompat objects will be null, + // so temporarily set the |mAccessibilityEnabledOverride| flag to true, then disable it. mAccessibilityEnabledOverride = true; String returnString = AccessibilityNodeInfoUtils.toString(createAccessibilityNodeInfo(virtualViewId)); @@ -605,10 +652,12 @@ mNodeInfoCache.get(virtualViewId).recycle(); mNodeInfoCache.remove(virtualViewId); } + // Remove this node from requested image data nodes in case data changed with update. + mImageDataRequestedNodes.remove(virtualViewId); } @Override - public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { + public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { if (!isAccessibilityEnabled()) { return null; } @@ -623,12 +672,12 @@ return null; } - // We need to create an |AccessibilityNodeInfo| object for this |virtualViewId|. If we have - // one in our cache, then communicate this so web_contents_accessibility_android.cc + // We need to create an |AccessibilityNodeInfoCompat| object for this |virtualViewId|. If we + // have one in our cache, then communicate this so web_contents_accessibility_android.cc // will update a fraction of the object and for the rest leverage what is already there. if (mNodeInfoCache.get(virtualViewId) != null) { - AccessibilityNodeInfo cachedNode = - AccessibilityNodeInfo.obtain(mNodeInfoCache.get(virtualViewId)); + AccessibilityNodeInfoCompat cachedNode = + AccessibilityNodeInfoCompat.obtain(mNodeInfoCache.get(virtualViewId)); if (WebContentsAccessibilityImplJni.get().updateCachedAccessibilityNodeInfo( mNativeObj, WebContentsAccessibilityImpl.this, cachedNode, virtualViewId)) { @@ -638,12 +687,11 @@ cachedNode.setAccessibilityFocused(mAccessibilityFocusId == virtualViewId); if (mAccessibilityFocusId == virtualViewId) { - addAction(cachedNode, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); - removeAction(cachedNode, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + cachedNode.addAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS); + cachedNode.removeAction(ACTION_ACCESSIBILITY_FOCUS); } else { - removeAction( - cachedNode, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); - addAction(cachedNode, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + cachedNode.removeAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS); + cachedNode.addAction(ACTION_ACCESSIBILITY_FOCUS); } return cachedNode; @@ -656,7 +704,7 @@ } else { // If we have no copy of this node in our cache, build a new one from scratch. - final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(mView); + final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(mView); info.setPackageName(mContext.getPackageName()); info.setSource(mView, virtualViewId); @@ -667,7 +715,7 @@ if (WebContentsAccessibilityImplJni.get().populateAccessibilityNodeInfo( mNativeObj, WebContentsAccessibilityImpl.this, info, virtualViewId)) { // After successfully populating this node, add it to our cache then return. - mNodeInfoCache.put(virtualViewId, AccessibilityNodeInfo.obtain(info)); + mNodeInfoCache.put(virtualViewId, AccessibilityNodeInfoCompat.obtain(info)); return info; } else { info.recycle(); @@ -677,16 +725,16 @@ } @Override - public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText( + public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText( String text, int virtualViewId) { - return new ArrayList<AccessibilityNodeInfo>(); + return new ArrayList<AccessibilityNodeInfoCompat>(); } private static boolean isValidMovementGranularity(int granularity) { switch (granularity) { - case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: - case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: - case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE: + case MOVEMENT_GRANULARITY_CHARACTER: + case MOVEMENT_GRANULARITY_WORD: + case MOVEMENT_GRANULARITY_LINE: return true; } return false; @@ -822,193 +870,176 @@ if (mTracker != null) mTracker.addAction(action, arguments); - switch (action) { - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - if (!moveAccessibilityFocusToId(virtualViewId)) return true; - if (!mIsHovering) { - scrollToMakeNodeVisible(mAccessibilityFocusId); - } else { - mPendingScrollToMakeNodeVisible = true; - } - return true; - case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - // ALWAYS respond with TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED whether we thought - // it had focus or not, so that the Android framework cache is correct. - sendAccessibilityEvent( - virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); - if (mAccessibilityFocusId == virtualViewId) { - WebContentsAccessibilityImplJni.get().moveAccessibilityFocus(mNativeObj, - WebContentsAccessibilityImpl.this, mAccessibilityFocusId, View.NO_ID); - mAccessibilityFocusId = View.NO_ID; - mAccessibilityFocusRect = null; - } - if (mLastHoverId == virtualViewId) { - sendAccessibilityEvent(mLastHoverId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); - mLastHoverId = View.NO_ID; - } - return true; - case AccessibilityNodeInfo.ACTION_CLICK: - if (!mView.hasFocus()) mView.requestFocus(); - performClick(virtualViewId); - return true; - case AccessibilityNodeInfo.ACTION_FOCUS: - if (!mView.hasFocus()) mView.requestFocus(); - WebContentsAccessibilityImplJni.get().focus( - mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId); - return true; - case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: - WebContentsAccessibilityImplJni.get().blur( - mNativeObj, WebContentsAccessibilityImpl.this); - return true; - case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT: { - if (arguments == null) return false; - String elementType = arguments.getString( - AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING); - if (elementType == null) return false; - elementType = elementType.toUpperCase(Locale.US); - return jumpToElementType( - virtualViewId, elementType, /*forwards*/ true, /*canWrap*/ false); + // Constant expressions are required for switches. To avoid duplicating aspects of the + // framework, or adding an enum or IntDef to the codebase, we opt for an if/else-if + // approach. The benefits of using the Compat library makes up for the messier code. + if (action == ACTION_ACCESSIBILITY_FOCUS.getId()) { + if (!moveAccessibilityFocusToId(virtualViewId)) return true; + if (!mIsHovering) { + scrollToMakeNodeVisible(mAccessibilityFocusId); + } else { + mPendingScrollToMakeNodeVisible = true; } - case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT: { - if (arguments == null) return false; - String elementType = arguments.getString( - AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING); - if (elementType == null) return false; - elementType = elementType.toUpperCase(Locale.US); - return jumpToElementType(virtualViewId, elementType, /*forwards*/ false, - /*canWrap*/ virtualViewId == mCurrentRootId); + return true; + } else if (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS.getId()) { + // ALWAYS respond with TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED whether we thought + // it had focus or not, so that the Android framework cache is correct. + sendAccessibilityEvent( + virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + if (mAccessibilityFocusId == virtualViewId) { + WebContentsAccessibilityImplJni.get().moveAccessibilityFocus(mNativeObj, + WebContentsAccessibilityImpl.this, mAccessibilityFocusId, View.NO_ID); + mAccessibilityFocusId = View.NO_ID; + mAccessibilityFocusRect = null; } - case ACTION_SET_TEXT: { - if (!WebContentsAccessibilityImplJni.get().isEditableText( - mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId)) { - return false; - } - if (arguments == null) return false; - CharSequence bundleText = - arguments.getCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE); - if (bundleText == null) return false; - String newText = bundleText.toString(); - WebContentsAccessibilityImplJni.get().setTextFieldValue( - mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId, newText); - // Match Android framework and set the cursor to the end of the text field. - WebContentsAccessibilityImplJni.get().setSelection(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, newText.length(), - newText.length()); - return true; + if (mLastHoverId == virtualViewId) { + sendAccessibilityEvent(mLastHoverId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); + mLastHoverId = View.NO_ID; } - case AccessibilityNodeInfo.ACTION_SET_SELECTION: { - if (!WebContentsAccessibilityImplJni.get().isEditableText( - mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId)) { - return false; - } - int selectionStart = 0; - int selectionEnd = 0; - if (arguments != null) { - selectionStart = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT); - selectionEnd = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT); - } - WebContentsAccessibilityImplJni.get().setSelection(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, selectionStart, - selectionEnd); - return true; - } - case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: { - if (arguments == null) return false; - int granularity = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT); - boolean extend = arguments.getBoolean( - AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN); - if (!isValidMovementGranularity(granularity)) { - return false; - } - return nextAtGranularity(granularity, extend, virtualViewId); - } - case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: { - if (arguments == null) return false; - int granularity = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT); - boolean extend = arguments.getBoolean( - AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN); - if (!isValidMovementGranularity(granularity)) { - return false; - } - return previousAtGranularity(granularity, extend, virtualViewId); - } - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: - return scrollForward(virtualViewId); - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: - return scrollBackward(virtualViewId); - case AccessibilityNodeInfo.ACTION_CUT: - if (mDelegate.getWebContents() != null) { - ((WebContentsImpl) mDelegate.getWebContents()).cut(); - return true; - } + return true; + } else if (action == ACTION_CLICK.getId()) { + if (!mView.hasFocus()) mView.requestFocus(); + performClick(virtualViewId); + return true; + } else if (action == ACTION_FOCUS.getId()) { + if (!mView.hasFocus()) mView.requestFocus(); + WebContentsAccessibilityImplJni.get().focus( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId); + return true; + } else if (action == ACTION_CLEAR_FOCUS.getId()) { + WebContentsAccessibilityImplJni.get().blur( + mNativeObj, WebContentsAccessibilityImpl.this); + return true; + } else if (action == ACTION_NEXT_HTML_ELEMENT.getId()) { + if (arguments == null) return false; + String elementType = arguments.getString(ACTION_ARGUMENT_HTML_ELEMENT_STRING); + if (elementType == null) return false; + elementType = elementType.toUpperCase(Locale.US); + return jumpToElementType( + virtualViewId, elementType, /*forwards*/ true, /*canWrap*/ false); + } else if (action == ACTION_PREVIOUS_HTML_ELEMENT.getId()) { + if (arguments == null) return false; + String elementType = arguments.getString(ACTION_ARGUMENT_HTML_ELEMENT_STRING); + if (elementType == null) return false; + elementType = elementType.toUpperCase(Locale.US); + return jumpToElementType(virtualViewId, elementType, /*forwards*/ false, + /*canWrap*/ virtualViewId == mCurrentRootId); + } else if (action == ACTION_SET_TEXT.getId()) { + if (!WebContentsAccessibilityImplJni.get().isEditableText( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId)) { return false; - case AccessibilityNodeInfo.ACTION_COPY: - if (mDelegate.getWebContents() != null) { - ((WebContentsImpl) mDelegate.getWebContents()).copy(); - return true; - } + } + if (arguments == null) return false; + CharSequence bundleText = + arguments.getCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE); + if (bundleText == null) return false; + String newText = bundleText.toString(); + WebContentsAccessibilityImplJni.get().setTextFieldValue( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId, newText); + // Match Android framework and set the cursor to the end of the text field. + WebContentsAccessibilityImplJni.get().setSelection(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, newText.length(), + newText.length()); + return true; + } else if (action == ACTION_SET_SELECTION.getId()) { + if (!WebContentsAccessibilityImplJni.get().isEditableText( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId)) { return false; - case AccessibilityNodeInfo.ACTION_PASTE: - if (mDelegate.getWebContents() != null) { - ((WebContentsImpl) mDelegate.getWebContents()).paste(); - return true; - } + } + int selectionStart = 0; + int selectionEnd = 0; + if (arguments != null) { + selectionStart = arguments.getInt(ACTION_ARGUMENT_SELECTION_START_INT); + selectionEnd = arguments.getInt(ACTION_ARGUMENT_SELECTION_END_INT); + } + WebContentsAccessibilityImplJni.get().setSelection(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, selectionStart, selectionEnd); + return true; + } else if (action == ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId()) { + if (arguments == null) return false; + int granularity = arguments.getInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT); + boolean extend = arguments.getBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN); + if (!isValidMovementGranularity(granularity)) { return false; - case AccessibilityNodeInfo.ACTION_COLLAPSE: - case AccessibilityNodeInfo.ACTION_EXPAND: - // If something is collapsible or expandable, just activate it to toggle. - performClick(virtualViewId); - return true; - case ACTION_SHOW_ON_SCREEN: - scrollToMakeNodeVisible(virtualViewId); - return true; - case ACTION_CONTEXT_CLICK: - case AccessibilityNodeInfo.ACTION_LONG_CLICK: - WebContentsAccessibilityImplJni.get().showContextMenu( - mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId); - return true; - case ACTION_SCROLL_UP: - case ACTION_PAGE_UP: - return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.UP, - action == ACTION_PAGE_UP); - case ACTION_SCROLL_DOWN: - case ACTION_PAGE_DOWN: - return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.DOWN, - action == ACTION_PAGE_DOWN); - case ACTION_SCROLL_LEFT: - case ACTION_PAGE_LEFT: - return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.LEFT, - action == ACTION_PAGE_LEFT); - case ACTION_SCROLL_RIGHT: - case ACTION_PAGE_RIGHT: - return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.RIGHT, - action == ACTION_PAGE_RIGHT); - case ACTION_SET_PROGRESS: - if (arguments == null) return false; - if (!arguments.containsKey(ACTION_ARGUMENT_PROGRESS_VALUE)) return false; - return WebContentsAccessibilityImplJni.get().setRangeValue(mNativeObj, - WebContentsAccessibilityImpl.this, virtualViewId, - arguments.getFloat(ACTION_ARGUMENT_PROGRESS_VALUE)); - case ACTION_IME_ENTER: - if (mDelegate.getWebContents() != null) { - if (ImeAdapterImpl.fromWebContents(mDelegate.getWebContents()) != null) { - // We send an unspecified action to ensure Enter key is hit - return ImeAdapterImpl.fromWebContents(mDelegate.getWebContents()) - .performEditorAction(EditorInfo.IME_ACTION_UNSPECIFIED); - } - } + } + return nextAtGranularity(granularity, extend, virtualViewId); + } else if (action == ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId()) { + if (arguments == null) return false; + int granularity = arguments.getInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT); + boolean extend = arguments.getBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN); + if (!isValidMovementGranularity(granularity)) { return false; - default: - break; + } + return previousAtGranularity(granularity, extend, virtualViewId); + } else if (action == ACTION_SCROLL_FORWARD.getId()) { + return scrollForward(virtualViewId); + } else if (action == ACTION_SCROLL_BACKWARD.getId()) { + return scrollBackward(virtualViewId); + } else if (action == ACTION_CUT.getId()) { + if (mDelegate.getWebContents() != null) { + ((WebContentsImpl) mDelegate.getWebContents()).cut(); + return true; + } + return false; + } else if (action == ACTION_COPY.getId()) { + if (mDelegate.getWebContents() != null) { + ((WebContentsImpl) mDelegate.getWebContents()).copy(); + return true; + } + return false; + } else if (action == ACTION_PASTE.getId()) { + if (mDelegate.getWebContents() != null) { + ((WebContentsImpl) mDelegate.getWebContents()).paste(); + return true; + } + return false; + } else if (action == ACTION_COLLAPSE.getId() || action == ACTION_EXPAND.getId()) { + // If something is collapsible or expandable, just activate it to toggle. + performClick(virtualViewId); + return true; + } else if (action == ACTION_SHOW_ON_SCREEN.getId()) { + scrollToMakeNodeVisible(virtualViewId); + return true; + } else if (action == ACTION_CONTEXT_CLICK.getId() || action == ACTION_LONG_CLICK.getId()) { + WebContentsAccessibilityImplJni.get().showContextMenu( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId); + return true; + } else if (action == ACTION_SCROLL_UP.getId() || action == ACTION_PAGE_UP.getId()) { + return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.UP, + action == ACTION_PAGE_UP.getId()); + } else if (action == ACTION_SCROLL_DOWN.getId() || action == ACTION_PAGE_DOWN.getId()) { + return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.DOWN, + action == ACTION_PAGE_DOWN.getId()); + } else if (action == ACTION_SCROLL_LEFT.getId() || action == ACTION_PAGE_LEFT.getId()) { + return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.LEFT, + action == ACTION_PAGE_LEFT.getId()); + } else if (action == ACTION_SCROLL_RIGHT.getId() || action == ACTION_PAGE_RIGHT.getId()) { + return WebContentsAccessibilityImplJni.get().scroll(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, ScrollDirection.RIGHT, + action == ACTION_PAGE_RIGHT.getId()); + } else if (action == ACTION_SET_PROGRESS.getId()) { + if (arguments == null) return false; + if (!arguments.containsKey(ACTION_ARGUMENT_PROGRESS_VALUE)) return false; + return WebContentsAccessibilityImplJni.get().setRangeValue(mNativeObj, + WebContentsAccessibilityImpl.this, virtualViewId, + arguments.getFloat(ACTION_ARGUMENT_PROGRESS_VALUE)); + } else if (action == ACTION_IME_ENTER.getId()) { + if (mDelegate.getWebContents() != null) { + if (ImeAdapterImpl.fromWebContents(mDelegate.getWebContents()) != null) { + // We send an unspecified action to ensure Enter key is hit + return ImeAdapterImpl.fromWebContents(mDelegate.getWebContents()) + .performEditorAction(EditorInfo.IME_ACTION_UNSPECIFIED); + } + } + return false; + } else { + // This should never be hit, so do the equivalent of NOTREACHED; + assert false : "AccessibilityNodeProvider called performAction with unexpected action."; } + return false; } @@ -1085,7 +1116,7 @@ sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); // (Re-) focus focused element, since we weren't able to create an - // AccessibilityNodeInfo for this element before. + // AccessibilityNodeInfoCompat for this element before. if (!mShouldFocusOnPageLoad) return; if (mAccessibilityFocusId != View.NO_ID) { moveAccessibilityFocusToIdAndRefocusIfNeeded(mAccessibilityFocusId); @@ -1202,7 +1233,7 @@ traverseEvent.setItemCount(text.length()); traverseEvent.setMovementGranularity(mSelectionGranularity); traverseEvent.setContentDescription(text); - traverseEvent.setAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); + traverseEvent.setAction(ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId()); requestSendAccessibilityEvent(selectionEvent); requestSendAccessibilityEvent(traverseEvent); @@ -1260,7 +1291,7 @@ traverseEvent.setItemCount(text.length()); traverseEvent.setMovementGranularity(mSelectionGranularity); traverseEvent.setContentDescription(text); - traverseEvent.setAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); + traverseEvent.setAction(ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId()); requestSendAccessibilityEvent(selectionEvent); requestSendAccessibilityEvent(traverseEvent); @@ -1418,10 +1449,12 @@ && (mAccessibilityEnabledOverride || mAccessibilityManager.isEnabled()); } - private AccessibilityNodeInfo createNodeForHost(int rootId) { + private AccessibilityNodeInfoCompat createNodeForHost(int rootId) { // Since we don't want the parent to be focusable, but we can't remove // actions from a node, copy over the necessary fields. - final AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(mView); + final AccessibilityNodeInfoCompat result = AccessibilityNodeInfoCompat.obtain(mView); + // mView requires an |AccessibilityNodeInfo| object here, so we keep the |source| as the + // non-Compat type rather than unwrapping an |AccessibilityNodeInfoCompat| object. final AccessibilityNodeInfo source = AccessibilityNodeInfo.obtain(mView); mView.onInitializeAccessibilityNodeInfo(source); @@ -1575,8 +1608,17 @@ } @CalledByNative + @SuppressLint("WrongConstant") protected void handleDialogModalOpened(int virtualViewId) { - // Requires P or higher. + if (isAccessibilityEnabled()) { + AccessibilityEvent event = + AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + if (event == null) return; + + event.setContentChangeTypes(CONTENT_CHANGE_TYPE_PANE_APPEARED); + event.setSource(mView, virtualViewId); + requestSendAccessibilityEvent(event); + } } @CalledByNative @@ -1593,19 +1635,20 @@ } @CalledByNative - private void setAccessibilityNodeInfoParent(AccessibilityNodeInfo node, int parentId) { + private void setAccessibilityNodeInfoParent(AccessibilityNodeInfoCompat node, int parentId) { node.setParent(mView, parentId); } @CalledByNative - private void addAccessibilityNodeInfoChildren(AccessibilityNodeInfo node, int[] childIds) { + private void addAccessibilityNodeInfoChildren( + AccessibilityNodeInfoCompat node, int[] childIds) { for (int childId : childIds) { node.addChild(mView, childId); } } @CalledByNative - private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node, + private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfoCompat node, int virtualViewId, boolean checkable, boolean checked, boolean clickable, boolean contentInvalid, boolean enabled, boolean focusable, boolean focused, boolean hasImage, boolean password, boolean scrollable, boolean selected, @@ -1650,132 +1693,109 @@ bundle.putCharSequence(EXTRAS_KEY_HAS_IMAGE, "true"); } - node.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER - | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD - | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE); + node.setMovementGranularities(MOVEMENT_GRANULARITY_CHARACTER | MOVEMENT_GRANULARITY_WORD + | MOVEMENT_GRANULARITY_LINE); node.setAccessibilityFocused(mAccessibilityFocusId == virtualViewId); } - // The Android SDK requires us to call AccessibilityNodeInfo.addAction and - // AccessibilityNodeInfo.removeAction with an AccessibilityAction argument, but to simplify - // things, we just cache a set of AccessibilityActions mapped by their ID. - protected void addAction(AccessibilityNodeInfo node, int actionId) { - AccessibilityAction action = sAccessibilityActionMap.get(actionId); - if (action == null) { - action = new AccessibilityAction(actionId, null); - sAccessibilityActionMap.put(actionId, action); - } - node.addAction(action); - } - - protected void removeAction(AccessibilityNodeInfo node, int actionId) { - AccessibilityAction action = sAccessibilityActionMap.get(actionId); - if (action == null) { - action = new AccessibilityAction(actionId, null); - sAccessibilityActionMap.put(actionId, action); - } - node.removeAction(action); - } - @CalledByNative - private void addAccessibilityNodeInfoActions(AccessibilityNodeInfo node, int virtualViewId, - boolean canScrollForward, boolean canScrollBackward, boolean canScrollUp, - boolean canScrollDown, boolean canScrollLeft, boolean canScrollRight, boolean clickable, - boolean editableText, boolean enabled, boolean focusable, boolean focused, - boolean isCollapsed, boolean isExpanded, boolean hasNonEmptyValue, - boolean hasNonEmptyInnerText, boolean isSeekControl, boolean isForm) { - addAction(node, AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT); - addAction(node, AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT); - addAction(node, ACTION_SHOW_ON_SCREEN); - addAction(node, ACTION_CONTEXT_CLICK); - + private void addAccessibilityNodeInfoActions(AccessibilityNodeInfoCompat node, + int virtualViewId, boolean canScrollForward, boolean canScrollBackward, + boolean canScrollUp, boolean canScrollDown, boolean canScrollLeft, + boolean canScrollRight, boolean clickable, boolean editableText, boolean enabled, + boolean focusable, boolean focused, boolean isCollapsed, boolean isExpanded, + boolean hasNonEmptyValue, boolean hasNonEmptyInnerText, boolean isSeekControl, + boolean isForm) { + node.addAction(ACTION_NEXT_HTML_ELEMENT); + node.addAction(ACTION_PREVIOUS_HTML_ELEMENT); + node.addAction(ACTION_SHOW_ON_SCREEN); + node.addAction(ACTION_CONTEXT_CLICK); // We choose to not add ACTION_LONG_CLICK to nodes to prevent verbose utterances. - // addAction(node, AccessibilityNodeInfo.ACTION_LONG_CLICK); if (hasNonEmptyInnerText) { - addAction(node, AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); - addAction(node, AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); + node.addAction(ACTION_NEXT_AT_MOVEMENT_GRANULARITY); + node.addAction(ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); } if (editableText && enabled) { // TODO: don't support actions that modify it if it's read-only (but // SET_SELECTION and COPY are okay). - addAction(node, ACTION_SET_TEXT); - addAction(node, AccessibilityNodeInfo.ACTION_PASTE); - addAction(node, ACTION_IME_ENTER); + node.addAction(ACTION_SET_TEXT); + node.addAction(ACTION_PASTE); + node.addAction(ACTION_IME_ENTER); if (hasNonEmptyValue) { - addAction(node, AccessibilityNodeInfo.ACTION_SET_SELECTION); - addAction(node, AccessibilityNodeInfo.ACTION_CUT); - addAction(node, AccessibilityNodeInfo.ACTION_COPY); + node.addAction(ACTION_SET_SELECTION); + node.addAction(ACTION_CUT); + node.addAction(ACTION_COPY); } } if (canScrollForward) { - addAction(node, AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + node.addAction(ACTION_SCROLL_FORWARD); } if (canScrollBackward) { - addAction(node, AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + node.addAction(ACTION_SCROLL_BACKWARD); } if (canScrollUp) { - addAction(node, ACTION_SCROLL_UP); - addAction(node, ACTION_PAGE_UP); + node.addAction(ACTION_SCROLL_UP); + node.addAction(ACTION_PAGE_UP); } if (canScrollDown) { - addAction(node, ACTION_SCROLL_DOWN); - addAction(node, ACTION_PAGE_DOWN); + node.addAction(ACTION_SCROLL_DOWN); + node.addAction(ACTION_PAGE_DOWN); } if (canScrollLeft) { - addAction(node, ACTION_SCROLL_LEFT); - addAction(node, ACTION_PAGE_LEFT); + node.addAction(ACTION_SCROLL_LEFT); + node.addAction(ACTION_PAGE_LEFT); } if (canScrollRight) { - addAction(node, ACTION_SCROLL_RIGHT); - addAction(node, ACTION_PAGE_RIGHT); + node.addAction(ACTION_SCROLL_RIGHT); + node.addAction(ACTION_PAGE_RIGHT); } if (focusable) { if (focused) { - addAction(node, AccessibilityNodeInfo.ACTION_CLEAR_FOCUS); + node.addAction(ACTION_CLEAR_FOCUS); } else { - addAction(node, AccessibilityNodeInfo.ACTION_FOCUS); + node.addAction(ACTION_FOCUS); } } if (mAccessibilityFocusId == virtualViewId) { - addAction(node, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + node.addAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS); } else { - addAction(node, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + node.addAction(ACTION_ACCESSIBILITY_FOCUS); } if (clickable) { - addAction(node, AccessibilityNodeInfo.ACTION_CLICK); + node.addAction(ACTION_CLICK); } if (isCollapsed) { - addAction(node, ACTION_EXPAND); + node.addAction(ACTION_EXPAND); } if (isExpanded) { - addAction(node, ACTION_COLLAPSE); + node.addAction(ACTION_COLLAPSE); } if (isSeekControl) { - addAction(node, ACTION_SET_PROGRESS); + node.addAction(ACTION_SET_PROGRESS); } } @CalledByNative - private void setAccessibilityNodeInfoBaseAttributes(AccessibilityNodeInfo node, boolean isRoot, - String className, String role, String roleDescription, String hint, String targetUrl, - boolean canOpenPopup, boolean dismissable, boolean multiLine, int inputType, - int liveRegion, String errorMessage, int clickableScore) { + private void setAccessibilityNodeInfoBaseAttributes(AccessibilityNodeInfoCompat node, + boolean isRoot, String className, String role, String roleDescription, String hint, + String targetUrl, boolean canOpenPopup, boolean dismissable, boolean multiLine, + int inputType, int liveRegion, String errorMessage, int clickableScore) { node.setClassName(className); Bundle bundle = node.getExtras(); @@ -1813,7 +1833,7 @@ @SuppressLint("NewApi") @CalledByNative - protected void setAccessibilityNodeInfoText(AccessibilityNodeInfo node, String text, + protected void setAccessibilityNodeInfoText(AccessibilityNodeInfoCompat node, String text, boolean annotateAsLink, boolean isEditableText, String language, int[] suggestionStarts, int[] suggestionEnds, String[] suggestions, String stateDescription) { CharSequence computedText = computeText( @@ -1831,6 +1851,20 @@ } else { node.setText(computedText); } + + // TODO(mschillaci): In a follow-up CL, match these across Android versions and fix tests. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // For Android R and higher, we will not rely on concatenating text and + // stateDescription, and will instead revert text to original content and set + // stateDescription separately. + if (stateDescription != null && !stateDescription.isEmpty()) { + CharSequence originalText = computeText(text, annotateAsLink, language, + suggestionStarts, suggestionEnds, suggestions); + + node.setText(originalText); + node.setStateDescription(stateDescription); + } + } } protected boolean areInlineTextBoxesLoaded(int virtualViewId) { @@ -1964,7 +1998,7 @@ } @CalledByNative - protected void setAccessibilityNodeInfoLocation(AccessibilityNodeInfo node, + protected void setAccessibilityNodeInfoLocation(AccessibilityNodeInfoCompat node, final int virtualViewId, int absoluteLeft, int absoluteTop, int parentRelativeLeft, int parentRelativeTop, int width, int height, boolean isRootNode, boolean isOffscreen) { // First set the bounds in parent. @@ -1997,50 +2031,65 @@ @CalledByNative protected void setAccessibilityNodeInfoCollectionInfo( - AccessibilityNodeInfo node, int rowCount, int columnCount, boolean hierarchical) { - node.setCollectionInfo( - AccessibilityNodeInfo.CollectionInfo.obtain(rowCount, columnCount, hierarchical)); + AccessibilityNodeInfoCompat node, int rowCount, int columnCount, boolean hierarchical) { + node.setCollectionInfo(AccessibilityNodeInfoCompat.CollectionInfoCompat.obtain( + rowCount, columnCount, hierarchical)); } @CalledByNative - protected void setAccessibilityNodeInfoCollectionItemInfo(AccessibilityNodeInfo node, + protected void setAccessibilityNodeInfoCollectionItemInfo(AccessibilityNodeInfoCompat node, int rowIndex, int rowSpan, int columnIndex, int columnSpan, boolean heading) { - node.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain( + node.setCollectionItemInfo(AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain( rowIndex, rowSpan, columnIndex, columnSpan, heading)); } @CalledByNative protected void setAccessibilityNodeInfoRangeInfo( - AccessibilityNodeInfo node, int rangeType, float min, float max, float current) { - node.setRangeInfo(AccessibilityNodeInfo.RangeInfo.obtain(rangeType, min, max, current)); + AccessibilityNodeInfoCompat node, int rangeType, float min, float max, float current) { + node.setRangeInfo( + AccessibilityNodeInfoCompat.RangeInfoCompat.obtain(rangeType, min, max, current)); } @CalledByNative protected void setAccessibilityNodeInfoViewIdResourceName( - AccessibilityNodeInfo node, String viewIdResourceName) { + AccessibilityNodeInfoCompat node, String viewIdResourceName) { node.setViewIdResourceName(viewIdResourceName); } @CalledByNative - protected void setAccessibilityNodeInfoOAttributes(AccessibilityNodeInfo node, + protected void setAccessibilityNodeInfoOAttributes(AccessibilityNodeInfoCompat node, boolean hasCharacterLocations, boolean hasImage, String hint) { - // Requires O or higher. + node.setHintText(hint); + + // Work-around a gap in the Android API, that |AccessibilityNodeInfoCompat| class does not + // have the setAvailableExtraData method, so unwrap the node and call it directly. + // TODO(mschillaci): Remove unwrapping and SDK version req once Android API is updated. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (hasCharacterLocations) { + ((AccessibilityNodeInfo) node.getInfo()) + .setAvailableExtraData(sTextCharacterLocation); + } else if (hasImage) { + ((AccessibilityNodeInfo) node.getInfo()).setAvailableExtraData(sRequestImageData); + } + } } @CalledByNative - protected void setAccessibilityNodeInfoPaneTitle(AccessibilityNodeInfo node, String title) { - // Requires P or higher. + protected void setAccessibilityNodeInfoPaneTitle( + AccessibilityNodeInfoCompat node, String title) { + node.setPaneTitle(title); } @CalledByNative protected void setAccessibilityNodeInfoSelectionAttrs( - AccessibilityNodeInfo node, int startIndex, int endIndex) { + AccessibilityNodeInfoCompat node, int startIndex, int endIndex) { node.setEditable(true); node.setTextSelection(startIndex, endIndex); } @CalledByNative - protected void setAccessibilityNodeInfoImageData(AccessibilityNodeInfo info, byte[] imageData) { + protected void setAccessibilityNodeInfoImageData( + AccessibilityNodeInfoCompat info, byte[] imageData) { info.getExtras().putByteArray(EXTRAS_KEY_IMAGE_DATA, imageData); } @@ -2081,6 +2130,60 @@ event.getText().add(text); } + @Override + public void addExtraDataToAccessibilityNodeInfo(int virtualViewId, + AccessibilityNodeInfoCompat info, String extraDataKey, Bundle arguments) { + switch (extraDataKey) { + case EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY: + getExtraDataTextCharacterLocations(virtualViewId, info, arguments); + break; + case EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY: + getImageData(virtualViewId, info); + break; + } + } + + private void getExtraDataTextCharacterLocations( + int virtualViewId, AccessibilityNodeInfoCompat info, Bundle arguments) { + if (!areInlineTextBoxesLoaded(virtualViewId)) { + loadInlineTextBoxes(virtualViewId); + } + + int positionInfoStartIndex = + arguments.getInt(EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX, -1); + int positionInfoLength = + arguments.getInt(EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH, -1); + if (positionInfoLength <= 0 || positionInfoStartIndex < 0) return; + + int[] coords = getCharacterBoundingBoxes( + virtualViewId, positionInfoStartIndex, positionInfoLength); + if (coords == null) return; + assert coords.length == positionInfoLength * 4; + + RectF[] boundingRects = new RectF[positionInfoLength]; + for (int i = 0; i < positionInfoLength; i++) { + Rect rect = new Rect( + coords[4 * i + 0], coords[4 * i + 1], coords[4 * i + 2], coords[4 * i + 3]); + convertWebRectToAndroidCoordinates(rect, info.getExtras()); + boundingRects[i] = new RectF(rect); + } + + info.getExtras().putParcelableArray(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY, boundingRects); + } + + private void getImageData(int virtualViewId, AccessibilityNodeInfoCompat info) { + boolean hasSentPreviousRequest = mImageDataRequestedNodes.contains(virtualViewId); + // If the below call returns true, then image data has been set on the node. + if (!WebContentsAccessibilityImplJni.get().getImageData(mNativeObj, + WebContentsAccessibilityImpl.this, info, virtualViewId, + hasSentPreviousRequest)) { + // If the above call returns false, then the data was missing. The native-side code + // will have started the asynchronous process to populate the image data if no previous + // request has been sent. Add this |virtualViewId| to the list of requested nodes. + mImageDataRequestedNodes.add(virtualViewId); + } + } + boolean isCompatAutofillOnlyPossibleAccessibilityConsumer() { // Compatibility Autofill is only available on Android P+. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { @@ -2177,9 +2280,9 @@ int[] getAbsolutePositionForNode(long nativeWebContentsAccessibilityAndroid, WebContentsAccessibilityImpl caller, int id); boolean updateCachedAccessibilityNodeInfo(long nativeWebContentsAccessibilityAndroid, - WebContentsAccessibilityImpl caller, AccessibilityNodeInfo info, int id); + WebContentsAccessibilityImpl caller, AccessibilityNodeInfoCompat info, int id); boolean populateAccessibilityNodeInfo(long nativeWebContentsAccessibilityAndroid, - WebContentsAccessibilityImpl caller, AccessibilityNodeInfo info, int id); + WebContentsAccessibilityImpl caller, AccessibilityNodeInfoCompat info, int id); boolean populateAccessibilityEvent(long nativeWebContentsAccessibilityAndroid, WebContentsAccessibilityImpl caller, AccessibilityEvent event, int id, int eventType); @@ -2242,7 +2345,7 @@ boolean onHoverEventNoRenderer(long nativeWebContentsAccessibilityAndroid, WebContentsAccessibilityImpl caller, float x, float y); boolean getImageData(long nativeWebContentsAccessibilityAndroid, - WebContentsAccessibilityImpl caller, AccessibilityNodeInfo info, int id, + WebContentsAccessibilityImpl caller, AccessibilityNodeInfoCompat info, int id, boolean hasSentPreviousRequest); } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java b/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java index 5d0bfa1..6b061a7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java
@@ -289,7 +289,9 @@ logFetchFontResult(FetchFontResult.SUCCESS); return fileDescriptor; - } catch (NameNotFoundException | IOException | OutOfMemoryError e) { + } catch (NameNotFoundException | IOException | OutOfMemoryError | RuntimeException e) { + // We sometimes get CursorWindowAllocationException, but it's a hidden class. So, we + // catch RuntimeException. Log.d(TAG, "Failed to get font with: %s", e.toString()); logFetchFontResult(FetchFontResult.FAILED_EXCEPTION); return null;
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 c099a54..143f22e0 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
@@ -16,7 +16,9 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.accessibility.AccessibilityNodeProvider; + +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeProviderCompat; import org.hamcrest.Matchers; import org.junit.After; @@ -55,7 +57,7 @@ // 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 AccessibilityNodeProviderCompat mNodeProvider; public WebContentsAccessibilityImpl mWcax; // Tracker for all events and actions performed during a given test. @@ -124,27 +126,32 @@ * Returns the current |AccessibilityNodeProvider| from the WebContentsAccessibilityImpl * instance. Use polling to ensure a non-null value before returning. */ - private AccessibilityNodeProvider getAccessibilityNodeProvider() { - CriteriaHelper.pollUiThread(() -> mWcax.getAccessibilityNodeProvider() != null, ANP_ERROR); - return mWcax.getAccessibilityNodeProvider(); + private AccessibilityNodeProviderCompat getAccessibilityNodeProvider() { + CriteriaHelper.pollUiThread( + () -> mWcax.getAccessibilityNodeProviderCompat() != null, ANP_ERROR); + return mWcax.getAccessibilityNodeProviderCompat(); } /** * Helper method to call AccessibilityNodeInfo.getChildId and convert to a virtual * view ID using reflection, since the needed methods are hidden. */ - protected int getChildId(AccessibilityNodeInfo node, int index) { + protected int getChildId(AccessibilityNodeInfoCompat node, int index) { try { + // The methods found through reflection are only available in |AccessibilityNodeInfo|, + // so we will unwrap |node| to perform the calls. + AccessibilityNodeInfo nodeInfo = (AccessibilityNodeInfo) node.getInfo(); Method getChildIdMethod = AccessibilityNodeInfo.class.getMethod("getChildId", int.class); - long childId = (long) getChildIdMethod.invoke(node, Integer.valueOf(index)); + long childId = (long) getChildIdMethod.invoke(nodeInfo, Integer.valueOf(index)); Method getVirtualDescendantIdMethod = AccessibilityNodeInfo.class.getMethod("getVirtualDescendantId", long.class); int virtualViewId = (int) getVirtualDescendantIdMethod.invoke(null, Long.valueOf(childId)); return virtualViewId; } catch (Exception ex) { - Assert.fail("Unable to call hidden AccessibilityNodeInfo method: " + ex.toString()); + Assert.fail( + "Unable to call hidden AccessibilityNodeInfoCompat method: " + ex.toString()); return 0; } } @@ -156,14 +163,14 @@ */ private <T> int findNodeMatching(int virtualViewId, AccessibilityContentShellTestUtils.AccessibilityNodeInfoMatcher<T> matcher, T element) { - AccessibilityNodeInfo node = mNodeProvider.createAccessibilityNodeInfo(virtualViewId); + AccessibilityNodeInfoCompat node = mNodeProvider.createAccessibilityNodeInfo(virtualViewId); Assert.assertNotEquals(node, null); if (matcher.matches(node, element)) return virtualViewId; for (int i = 0; i < node.getChildCount(); i++) { int childId = getChildId(node, i); - AccessibilityNodeInfo child = mNodeProvider.createAccessibilityNodeInfo(childId); + AccessibilityNodeInfoCompat child = mNodeProvider.createAccessibilityNodeInfo(childId); if (child != null) { int result = findNodeMatching(childId, matcher, element); if (result != View.NO_ID) return result; @@ -241,10 +248,10 @@ */ public void focusNode(int virtualViewId) throws Throwable { // Focus given node, assert actions were performed, then poll until node is updated. - Assert.assertTrue( - performActionOnUiThread(virtualViewId, AccessibilityNodeInfo.ACTION_FOCUS, null)); Assert.assertTrue(performActionOnUiThread( - virtualViewId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)); + virtualViewId, AccessibilityNodeInfoCompat.ACTION_FOCUS, null)); + Assert.assertTrue(performActionOnUiThread( + virtualViewId, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null)); TestThreadUtils.runOnUiThreadBlocking( () -> mNodeProvider.createAccessibilityNodeInfo(virtualViewId));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestUtils.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestUtils.java index 2a83c2d..fd4f6cc9 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestUtils.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestUtils.java
@@ -7,7 +7,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; /** * Helper class with various testing util methods for content shell accessibility tests. @@ -36,7 +37,7 @@ * @param element The element and type we are matching against * @return True/false for whether or not the node is a match */ - boolean matches(AccessibilityNodeInfo node, T element); + boolean matches(AccessibilityNodeInfoCompat node, T element); } // Helper methods for common matching conditions for AccessibilityNodeInfo objects.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java index 6fc798c..cf09483f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -5,27 +5,39 @@ package org.chromium.content.browser.accessibility; import static android.content.Context.CLIPBOARD_SERVICE; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_COPY; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CUT; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_PASTE; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_LEFT; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_RIGHT; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT; -import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH; -import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX; -import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; + +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COPY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CUT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_FOCUS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PASTE; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_DOWN; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_LEFT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_RIGHT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_TEXT; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER; +import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD; import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.NODE_TIMEOUT_ERROR; import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sClassNameMatcher; @@ -34,8 +46,6 @@ import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sTextMatcher; import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sTextOrContentDescriptionMatcher; import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sViewIdResourceNameMatcher; -import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.ACTION_ARGUMENT_PROGRESS_VALUE; -import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.ACTION_SET_PROGRESS; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EVENTS_DROPPED_HISTOGRAM; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_CHROME_ROLE; @@ -43,6 +53,9 @@ import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_OFFSCREEN; 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 static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.ONE_HUNDRED_PERCENT_HISTOGRAM; import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.PERCENTAGE_DROPPED_HISTOGRAM; @@ -58,8 +71,8 @@ import android.text.Spannable; import android.text.style.SuggestionSpan; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.test.filters.LargeTest; import androidx.test.filters.SmallTest; @@ -143,7 +156,7 @@ // Constant values for unit tests private static final int UNSUPPRESSED_EXPECTED_COUNT = 15; - private AccessibilityNodeInfo mNodeInfo; + private AccessibilityNodeInfoCompat mNodeInfo; private AccessibilityContentShellTestData mTestData; @Rule @@ -195,14 +208,16 @@ return mActivityTestRule.waitForNodeMatching(matcher, element); } - private boolean performActionOnUiThread(int viewId, int action, Bundle args) + private boolean performActionOnUiThread( + int viewId, AccessibilityNodeInfoCompat.AccessibilityActionCompat action, Bundle args) throws ExecutionException { - return mActivityTestRule.performActionOnUiThread(viewId, action, args); + return mActivityTestRule.performActionOnUiThread(viewId, action.getId(), args); } - private boolean performActionOnUiThread(int viewId, int action, Bundle args, + private boolean performActionOnUiThread(int viewId, + AccessibilityNodeInfoCompat.AccessibilityActionCompat action, Bundle args, Callable<Boolean> criteria) throws ExecutionException, Throwable { - return mActivityTestRule.performActionOnUiThread(viewId, action, args, criteria); + return mActivityTestRule.performActionOnUiThread(viewId, action.getId(), args, criteria); } private void executeJS(String method) { @@ -213,7 +228,7 @@ mActivityTestRule.focusNode(virtualViewId); } - public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { + public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { return mActivityTestRule.mNodeProvider.createAccessibilityNodeInfo(virtualViewId); } @@ -222,18 +237,19 @@ * selection and traversal events have been dispatched before continuing with test. * * @param viewId int virtualViewId of the text field - * @param action int action to perform + * @param action AccessibilityActionCompat action to perform * @param args Bundle optional arguments * @throws ExecutionException Error */ - private void performTextActionOnUiThread(int viewId, int action, Bundle args) + private void performTextActionOnUiThread( + int viewId, AccessibilityNodeInfoCompat.AccessibilityActionCompat action, Bundle args) throws ExecutionException { // Reset values for traversal and selection events. mTestData.setReceivedTraversalEvent(false); mTestData.setReceivedSelectionEvent(false); // Perform our text selection/traversal action. - mActivityTestRule.performActionOnUiThread(viewId, action, args); + mActivityTestRule.performActionOnUiThread(viewId, action.getId(), args); // Poll until both events have been confirmed as received CriteriaHelper.pollUiThread(() -> { @@ -261,8 +277,7 @@ // Perform a series of slider increments and check results. for (int i = 1; i <= 10; i++) { // Increment our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_FORWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -280,8 +295,7 @@ // Perform a series of slider decrements and check results. for (int i = 1; i <= 20; i++) { // Decrement our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_BACKWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -318,8 +332,7 @@ int[] expectedVals = new int[] {84, 96, 108, 120, 132, 144}; for (int expectedVal : expectedVals) { // Increment our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_FORWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -338,8 +351,7 @@ expectedVals = new int[] {132, 120, 108, 96, 84, 72, 60, 48, 36, 24, 12, 0}; for (int expectedVal : expectedVals) { // Decrement our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_BACKWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -375,8 +387,7 @@ // Perform a series of slider increments and check results. for (int i = 1; i <= 10; i++) { // Increment our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_FORWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -394,8 +405,7 @@ // Perform a series of slider decrements and check results. for (int i = 1; i <= 20; i++) { // Decrement our slider using action, and poll until we receive the scroll event. - performActionOnUiThread(inputNodeVirtualViewId, - AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, new Bundle()); + performActionOnUiThread(inputNodeVirtualViewId, ACTION_SCROLL_BACKWARD, new Bundle()); CriteriaHelper.pollUiThread( () -> mTestData.hasReceivedEvent(), INPUT_RANGE_EVENT_ERROR); @@ -426,8 +436,8 @@ int vvIdInput1 = waitForNodeMatching(sViewIdResourceNameMatcher, "in1"); int vvIdInput2 = waitForNodeMatching(sViewIdResourceNameMatcher, "in2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvIdInput1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvIdInput2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvIdInput1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvIdInput2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); @@ -651,14 +661,13 @@ // Set granularity to CHARACTER, with selection FALSE Bundle args = new Bundle(); - args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, - AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER); - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); + args.putInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, MOVEMENT_GRANULARITY_CHARACTER); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); // Simulate swiping left (backward) for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i - 1, mTestData.getTraverseFromIndex()); Assert.assertEquals(i, mTestData.getTraverseToIndex()); @@ -668,8 +677,8 @@ // Simulate swiping right (forward) for (int i = 0; i < 7; i++) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i, mTestData.getTraverseFromIndex()); Assert.assertEquals(i + 1, mTestData.getTraverseToIndex()); @@ -698,14 +707,13 @@ // Set granularity to CHARACTER, with selection TRUE Bundle args = new Bundle(); - args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, - AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER); - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, MOVEMENT_GRANULARITY_CHARACTER); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); // Simulate swiping left (backward) (adds to selections) for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i - 1, mTestData.getTraverseFromIndex()); Assert.assertEquals(i, mTestData.getTraverseToIndex()); @@ -715,8 +723,8 @@ // Simulate swiping right (forward) (removes from selection) for (int i = 0; i < 7; i++) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i, mTestData.getTraverseFromIndex()); Assert.assertEquals(i + 1, mTestData.getTraverseToIndex()); @@ -725,19 +733,19 @@ } // Turn selection mode off and traverse to beginning so we can select forwards - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); } // Turn selection mode on - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); // Simulate swiping right (forward) (adds to selection) for (int i = 0; i < 7; i++) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i, mTestData.getTraverseFromIndex()); Assert.assertEquals(i + 1, mTestData.getTraverseToIndex()); @@ -747,8 +755,8 @@ // Simulate swiping left (backward) (removes from selections) for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i - 1, mTestData.getTraverseFromIndex()); Assert.assertEquals(i, mTestData.getTraverseToIndex()); @@ -778,17 +786,16 @@ // Set granularity to WORD, with selection FALSE Bundle args = new Bundle(); - args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, - AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD); - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); + args.putInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, MOVEMENT_GRANULARITY_WORD); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); int[] wordStarts = new int[] {0, 8, 13, 20, 23}; int[] wordEnds = new int[] {7, 12, 19, 22, 30}; // Simulate swiping left (backward) through all 5 words, check indices along the way for (int i = 4; i >= 0; --i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -798,8 +805,8 @@ // Simulate swiping right (forward) through all 5 words, check indices along the way for (int i = 0; i < 5; ++i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -828,17 +835,16 @@ // Set granularity to WORD, with selection TRUE Bundle args = new Bundle(); - args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, - AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD); - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, MOVEMENT_GRANULARITY_WORD); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); int[] wordStarts = new int[] {0, 8, 13, 20, 23}; int[] wordEnds = new int[] {7, 12, 19, 22, 30}; // Simulate swiping left (backward, adds to selection) through all 5 words, check indices for (int i = 4; i >= 0; --i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -848,8 +854,8 @@ // Simulate swiping right (forward, removes selection) through all 5 words, check indices for (int i = 0; i < 5; ++i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -858,19 +864,19 @@ } // Turn selection mode off and traverse to beginning so we can select forwards - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); for (int i = 4; i >= 0; i--) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); } // Turn selection mode on - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); // Simulate swiping right (forward) (adds to selection) for (int i = 0; i < 5; ++i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -880,8 +886,8 @@ // Simulate swiping left (backward) (removes from selections) for (int i = 4; i >= 0; --i) { - performTextActionOnUiThread(editTextVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + editTextVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(wordStarts[i], mTestData.getTraverseFromIndex()); Assert.assertEquals(wordEnds[i], mTestData.getTraverseToIndex()); @@ -914,14 +920,13 @@ // Set granularity to CHARACTER, with selection TRUE Bundle args = new Bundle(); - args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, - AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER); - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putInt(ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, MOVEMENT_GRANULARITY_CHARACTER); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); // Simulate swiping right (forward) (adds to selection) for (int i = 0; i < 7; i++) { - performTextActionOnUiThread(contentEditableVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + contentEditableVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i, mTestData.getTraverseFromIndex()); Assert.assertEquals(i + 1, mTestData.getTraverseToIndex()); @@ -931,8 +936,8 @@ // Simulate swiping left (backward) (removes from selections) for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(contentEditableVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + contentEditableVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i - 1, mTestData.getTraverseFromIndex()); Assert.assertEquals(i, mTestData.getTraverseToIndex()); @@ -941,19 +946,19 @@ } // Turn selection mode off and traverse to end so we can select backwards - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(contentEditableVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + contentEditableVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); } // Turn selection mode on - args.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); + args.putBoolean(ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); // Simulate swiping left (backward) (adds to selections) for (int i = 7; i > 0; i--) { - performTextActionOnUiThread(contentEditableVirtualViewId, - AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + contentEditableVirtualViewId, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i - 1, mTestData.getTraverseFromIndex()); Assert.assertEquals(i, mTestData.getTraverseToIndex()); @@ -963,8 +968,8 @@ // Simulate swiping right (forward) (removes from selection) for (int i = 0; i < 7; i++) { - performTextActionOnUiThread(contentEditableVirtualViewId, - AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); + performTextActionOnUiThread( + contentEditableVirtualViewId, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, args); Assert.assertEquals(i, mTestData.getTraverseFromIndex()); Assert.assertEquals(i + 1, mTestData.getTraverseToIndex()); @@ -1140,7 +1145,8 @@ // The data needed for text character locations loads asynchronously. Block until // it successfully returns the character bounds. CriteriaHelper.pollUiThread(() -> { - AccessibilityNodeInfo textNode = createAccessibilityNodeInfo(textNodeVirtualViewId); + AccessibilityNodeInfoCompat textNode = + createAccessibilityNodeInfo(textNodeVirtualViewId); mActivityTestRule.mNodeProvider.addExtraDataToAccessibilityNodeInfo( textNodeVirtualViewId, textNode, EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY, arguments); @@ -1237,7 +1243,7 @@ focusNode(vvIdDiv); // Send a scroll event so some elements will be offscreen and poll for results. - performActionOnUiThread(vvIdDiv, WebContentsAccessibilityImpl.ACTION_PAGE_UP, null, () -> { + performActionOnUiThread(vvIdDiv, ACTION_PAGE_UP, null, () -> { return createAccessibilityNodeInfo(vvIdDiv).getExtras() != null && createAccessibilityNodeInfo(vvIdDiv).getExtras().getInt( EXTRAS_KEY_UNCLIPPED_TOP, 1) @@ -1316,9 +1322,9 @@ int vvIdP2 = waitForNodeMatching(sTextMatcher, "Example Paragraph 2"); // Get the |AccessibilityNodeInfo| objects for our nodes. - AccessibilityNodeInfo nodeInfoDiv = createAccessibilityNodeInfo(vvIdDiv); - AccessibilityNodeInfo nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); - AccessibilityNodeInfo nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); + AccessibilityNodeInfoCompat nodeInfoDiv = createAccessibilityNodeInfo(vvIdDiv); + AccessibilityNodeInfoCompat nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); + AccessibilityNodeInfoCompat nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); // Assert we have the correct nodes. Assert.assertNotNull(NODE_TIMEOUT_ERROR, nodeInfoDiv); @@ -1362,9 +1368,9 @@ int vvIdP2 = waitForNodeMatching(sTextMatcher, "Example Paragraph 2"); // Get the |AccessibilityNodeInfo| objects for our nodes. - AccessibilityNodeInfo nodeInfoDiv = createAccessibilityNodeInfo(vvIdDiv); - AccessibilityNodeInfo nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); - AccessibilityNodeInfo nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); + AccessibilityNodeInfoCompat nodeInfoDiv = createAccessibilityNodeInfo(vvIdDiv); + AccessibilityNodeInfoCompat nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); + AccessibilityNodeInfoCompat nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); // Assert we have the correct nodes. Assert.assertNotNull(NODE_TIMEOUT_ERROR, nodeInfoDiv); @@ -1409,9 +1415,9 @@ int vvIdP1 = waitForNodeMatching(sTextMatcher, "Example Paragraph 1"); int vvIdP2 = waitForNodeMatching(sTextMatcher, "Example Paragraph 2"); - // Get the |AccessibilityNodeInfo| objects for our nodes. - AccessibilityNodeInfo nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); - AccessibilityNodeInfo nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); + // Get the |AccessibilityNodeInfoCompat| objects for our nodes. + AccessibilityNodeInfoCompat nodeInfoP1 = createAccessibilityNodeInfo(vvIdP1); + AccessibilityNodeInfoCompat nodeInfoP2 = createAccessibilityNodeInfo(vvIdP2); // Assert we have the correct nodes. Assert.assertNotNull(NODE_TIMEOUT_ERROR, nodeInfoP1); @@ -1575,9 +1581,9 @@ int vvId1 = waitForNodeMatching(sTextMatcher, "This is a test 1"); int vvId2 = waitForNodeMatching(sTextMatcher, "This is a test 2"); int vvId3 = waitForNodeMatching(sTextMatcher, "This is a test 3"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvId1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvId2); - AccessibilityNodeInfo mNodeInfo3 = createAccessibilityNodeInfo(vvId3); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvId1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvId2); + AccessibilityNodeInfoCompat mNodeInfo3 = createAccessibilityNodeInfo(vvId3); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo3); @@ -1620,9 +1626,9 @@ int vvId1 = waitForNodeMatching(sTextMatcher, "This is a test 1"); int vvId2 = waitForNodeMatching(sTextMatcher, "This is a test 2"); int vvId3 = waitForNodeMatching(sTextMatcher, "This is a test 3"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvId1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvId2); - AccessibilityNodeInfo mNodeInfo3 = createAccessibilityNodeInfo(vvId3); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvId1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvId2); + AccessibilityNodeInfoCompat mNodeInfo3 = createAccessibilityNodeInfo(vvId3); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo3); @@ -1660,9 +1666,9 @@ int vvIdText1 = waitForNodeMatching(sTextMatcher, "1"); int vvIdText2 = waitForNodeMatching(sTextMatcher, "6"); int vvIdText3 = waitForNodeMatching(sTextMatcher, "9"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvIdText1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvIdText2); - AccessibilityNodeInfo mNodeInfo3 = createAccessibilityNodeInfo(vvIdText3); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvIdText1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvIdText2); + AccessibilityNodeInfoCompat mNodeInfo3 = createAccessibilityNodeInfo(vvIdText3); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo3); @@ -1702,23 +1708,20 @@ mNodeInfo = createAccessibilityNodeInfo(vvid); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo); int vvidButton = waitForNodeMatching(sTextMatcher, "Button"); - AccessibilityNodeInfo buttonNodeInfo = createAccessibilityNodeInfo(vvidButton); + AccessibilityNodeInfoCompat buttonNodeInfo = createAccessibilityNodeInfo(vvidButton); Assert.assertNotNull(NODE_TIMEOUT_ERROR, buttonNodeInfo); // Verify that bad requests have no effect. - Assert.assertFalse( - performActionOnUiThread(vvidButton, AccessibilityNodeInfo.ACTION_SET_TEXT, null)); - Assert.assertFalse( - performActionOnUiThread(vvid, AccessibilityNodeInfo.ACTION_SET_TEXT, null)); + Assert.assertFalse(performActionOnUiThread(vvidButton, ACTION_SET_TEXT, null)); + Assert.assertFalse(performActionOnUiThread(vvid, ACTION_SET_TEXT, null)); Bundle bundle = new Bundle(); bundle.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, null); - Assert.assertFalse( - performActionOnUiThread(vvid, AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)); + Assert.assertFalse(performActionOnUiThread(vvid, ACTION_SET_TEXT, bundle)); // Send a proper action and poll for update. bundle.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "new text"); - Assert.assertTrue(performActionOnUiThread(vvid, AccessibilityNodeInfo.ACTION_SET_TEXT, - bundle, () -> !createAccessibilityNodeInfo(vvid).getText().toString().isEmpty())); + Assert.assertTrue(performActionOnUiThread(vvid, ACTION_SET_TEXT, bundle, + () -> !createAccessibilityNodeInfo(vvid).getText().toString().isEmpty())); // Send of test signal and update node. mActivityTestRule.sendEndOfTestSignal(); @@ -1742,22 +1745,20 @@ mNodeInfo = createAccessibilityNodeInfo(vvid); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo); int vvidButton = waitForNodeMatching(sTextMatcher, "Button"); - AccessibilityNodeInfo buttonNodeInfo = createAccessibilityNodeInfo(vvidButton); + AccessibilityNodeInfoCompat buttonNodeInfo = createAccessibilityNodeInfo(vvidButton); Assert.assertNotNull(NODE_TIMEOUT_ERROR, buttonNodeInfo); // Verify that a bad request has no effect. - Assert.assertFalse(performActionOnUiThread( - vvidButton, AccessibilityNodeInfo.ACTION_SET_SELECTION, null)); + Assert.assertFalse(performActionOnUiThread(vvidButton, ACTION_SET_SELECTION, null)); // Send a proper action and poll for update. Bundle bundle = new Bundle(); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 2); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 5); - Assert.assertTrue(performActionOnUiThread( - vvid, AccessibilityNodeInfo.ACTION_SET_SELECTION, bundle, () -> { - return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 - && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; - })); + bundle.putInt(ACTION_ARGUMENT_SELECTION_START_INT, 2); + bundle.putInt(ACTION_ARGUMENT_SELECTION_END_INT, 5); + Assert.assertTrue(performActionOnUiThread(vvid, ACTION_SET_SELECTION, bundle, () -> { + return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 + && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; + })); // Send of test signal and update node. mActivityTestRule.sendEndOfTestSignal(); @@ -1784,13 +1785,12 @@ // Select a given portion of the text. Bundle bundle = new Bundle(); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 2); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 7); - Assert.assertTrue(performActionOnUiThread( - vvid, AccessibilityNodeInfo.ACTION_SET_SELECTION, bundle, () -> { - return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 - && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; - })); + bundle.putInt(ACTION_ARGUMENT_SELECTION_START_INT, 2); + bundle.putInt(ACTION_ARGUMENT_SELECTION_END_INT, 7); + Assert.assertTrue(performActionOnUiThread(vvid, ACTION_SET_SELECTION, bundle, () -> { + return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 + && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; + })); // Perform the "cut" action, and poll for clipboard to be non-null. ClipboardManager clipboardManager = TestThreadUtils.runOnUiThreadBlockingNoException(() -> { @@ -1831,13 +1831,12 @@ // Select a given portion of the text. Bundle bundle = new Bundle(); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 2); - bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 7); - Assert.assertTrue(performActionOnUiThread( - vvid, AccessibilityNodeInfo.ACTION_SET_SELECTION, bundle, () -> { - return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 - && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; - })); + bundle.putInt(ACTION_ARGUMENT_SELECTION_START_INT, 2); + bundle.putInt(ACTION_ARGUMENT_SELECTION_END_INT, 7); + Assert.assertTrue(performActionOnUiThread(vvid, ACTION_SET_SELECTION, bundle, () -> { + return createAccessibilityNodeInfo(vvid).getTextSelectionStart() > 0 + && createAccessibilityNodeInfo(vvid).getTextSelectionEnd() > 0; + })); // Perform the "copy" action, and poll for clipboard to be non-null. ClipboardManager clipboardManager = TestThreadUtils.runOnUiThreadBlockingNoException(() -> { @@ -1987,8 +1986,8 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); @@ -2030,8 +2029,8 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); @@ -2073,15 +2072,14 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); // Send an action and poll for update. - Assert.assertTrue( - performActionOnUiThread(vvid1, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, - null, () -> createAccessibilityNodeInfo(vvid1).isAccessibilityFocused())); + Assert.assertTrue(performActionOnUiThread(vvid1, ACTION_ACCESSIBILITY_FOCUS, null, + () -> createAccessibilityNodeInfo(vvid1).isAccessibilityFocused())); // Update nodes and verify results. mNodeInfo1 = createAccessibilityNodeInfo(vvid1); @@ -2103,15 +2101,14 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); // Send an action and poll for update. - Assert.assertTrue( - performActionOnUiThread(vvid1, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, - null, () -> createAccessibilityNodeInfo(vvid1).isAccessibilityFocused())); + Assert.assertTrue(performActionOnUiThread(vvid1, ACTION_ACCESSIBILITY_FOCUS, null, + () -> createAccessibilityNodeInfo(vvid1).isAccessibilityFocused())); // Update nodes and verify results. mNodeInfo1 = createAccessibilityNodeInfo(vvid1); @@ -2120,8 +2117,7 @@ Assert.assertFalse(PERFORM_ACTION_ERROR, mNodeInfo2.isAccessibilityFocused()); // Clear accessibility focus from the node and verify. - Assert.assertTrue(performActionOnUiThread(vvid1, - AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null, + Assert.assertTrue(performActionOnUiThread(vvid1, ACTION_CLEAR_ACCESSIBILITY_FOCUS, null, () -> !createAccessibilityNodeInfo(vvid1).isAccessibilityFocused())); mNodeInfo1 = createAccessibilityNodeInfo(vvid1); @@ -2142,14 +2138,14 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); // Send an action and poll for update. - Assert.assertTrue(performActionOnUiThread(vvid1, AccessibilityNodeInfo.ACTION_FOCUS, null, - () -> createAccessibilityNodeInfo(vvid1).isFocused())); + Assert.assertTrue(performActionOnUiThread( + vvid1, ACTION_FOCUS, null, () -> createAccessibilityNodeInfo(vvid1).isFocused())); // Update nodes and verify results. mNodeInfo1 = createAccessibilityNodeInfo(vvid1); @@ -2170,14 +2166,14 @@ // Find the relevant nodes. int vvid1 = waitForNodeMatching(sViewIdResourceNameMatcher, "id1"); int vvid2 = waitForNodeMatching(sViewIdResourceNameMatcher, "id2"); - AccessibilityNodeInfo mNodeInfo1 = createAccessibilityNodeInfo(vvid1); - AccessibilityNodeInfo mNodeInfo2 = createAccessibilityNodeInfo(vvid2); + AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvid1); + AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvid2); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1); Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2); // Send an action and poll for update. - Assert.assertTrue(performActionOnUiThread(vvid1, AccessibilityNodeInfo.ACTION_FOCUS, null, - () -> createAccessibilityNodeInfo(vvid1).isFocused())); + Assert.assertTrue(performActionOnUiThread( + vvid1, ACTION_FOCUS, null, () -> createAccessibilityNodeInfo(vvid1).isFocused())); // Update nodes and verify results. mNodeInfo1 = createAccessibilityNodeInfo(vvid1); @@ -2186,8 +2182,8 @@ Assert.assertFalse(PERFORM_ACTION_ERROR, mNodeInfo2.isFocused()); // Clear focus from the node and verify. - Assert.assertTrue(performActionOnUiThread(vvid1, AccessibilityNodeInfo.ACTION_CLEAR_FOCUS, - null, () -> !createAccessibilityNodeInfo(vvid1).isFocused())); + Assert.assertTrue(performActionOnUiThread(vvid1, ACTION_CLEAR_FOCUS, null, + () -> !createAccessibilityNodeInfo(vvid1).isFocused())); mNodeInfo1 = createAccessibilityNodeInfo(vvid1); mNodeInfo2 = createAccessibilityNodeInfo(vvid2); @@ -2196,7 +2192,7 @@ } @MinAndroidSdkLevel(Build.VERSION_CODES.M) - private void assertActionsContainNoScrolls(AccessibilityNodeInfo nodeInfo) { + private void assertActionsContainNoScrolls(AccessibilityNodeInfoCompat nodeInfo) { Assert.assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_FORWARD)); Assert.assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_BACKWARD)); Assert.assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_UP));
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 index a08c5d7..c1c8e798 100644 --- 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
@@ -11,8 +11,8 @@ import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.os.Build; -import android.view.accessibility.AccessibilityNodeInfo; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.test.filters.SmallTest; import org.junit.Assert; @@ -114,13 +114,13 @@ // Find the root node and generate its string. int rootNodevvId = mActivityTestRule.waitForNodeMatching(sClassNameMatcher, "android.webkit.WebView"); - AccessibilityNodeInfo nodeInfo = createAccessibilityNodeInfo(rootNodevvId); + AccessibilityNodeInfoCompat nodeInfo = createAccessibilityNodeInfo(rootNodevvId); builder.append(AccessibilityNodeInfoUtils.toString(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); + AccessibilityNodeInfoCompat childNodeInfo = createAccessibilityNodeInfo(childId); recursivelyFormatTree(childNodeInfo, builder, "++"); } @@ -135,17 +135,17 @@ * @param indent prefix to indent each generation, e.g. "++" */ private void recursivelyFormatTree( - AccessibilityNodeInfo node, StringBuilder builder, String indent) { + AccessibilityNodeInfoCompat node, StringBuilder builder, String indent) { builder.append("\n").append(indent).append(AccessibilityNodeInfoUtils.toString(node)); for (int j = 0; j < node.getChildCount(); ++j) { int childId = mActivityTestRule.getChildId(node, j); - AccessibilityNodeInfo childNodeInfo = createAccessibilityNodeInfo(childId); + AccessibilityNodeInfoCompat childNodeInfo = createAccessibilityNodeInfo(childId); recursivelyFormatTree(childNodeInfo, builder, indent + "++"); } } // Helper method to create an AccessibilityNodeInfo object. - private AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { + private AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { return mActivityTestRule.mNodeProvider.createAccessibilityNodeInfo(virtualViewId); }
diff --git a/content/public/browser/browsing_data_filter_builder.h b/content/public/browser/browsing_data_filter_builder.h index 7ca68745..dd10c0f1 100644 --- a/content/public/browser/browsing_data_filter_builder.h +++ b/content/public/browser/browsing_data_filter_builder.h
@@ -13,6 +13,7 @@ #include "base/callback_forward.h" #include "content/common/content_export.h" +#include "net/cookies/cookie_partition_key_collection.h" #include "services/network/public/mojom/network_service.mojom.h" class GURL; @@ -59,6 +60,18 @@ // to accept it. virtual void AddRegisterableDomain(const std::string& registrable_domain) = 0; + // Set the CookiePartitionKeyCollection for a CookieDeletionFilter. + // Partitioned cookies will be not be deleted if their partition key is not in + // the keychain. If this method is not invoked, then by default this clears + // all partitioned cookies that match the other criteria. + virtual void SetCookiePartitionKeyCollection( + const net::CookiePartitionKeyCollection& + cookie_partition_key_collection) = 0; + + // Returns true if this filter is handling a Clear-Site-Data header sent in a + // cross-site context. + virtual bool IsCrossSiteClearSiteData() const = 0; + // Returns true if we're an empty preserve list, where we delete everything. virtual bool MatchesAllOriginsAndDomains() = 0;
diff --git a/content/public/browser/clear_site_data_utils.h b/content/public/browser/clear_site_data_utils.h index 8bb4f85..e837fc6 100644 --- a/content/public/browser/clear_site_data_utils.h +++ b/content/public/browser/clear_site_data_utils.h
@@ -7,6 +7,7 @@ #include "base/callback_forward.h" #include "content/common/content_export.h" +#include "net/cookies/cookie_partition_key.h" namespace url { class Origin; @@ -26,6 +27,7 @@ bool clear_storage, bool clear_cache, bool avoid_closing_connections, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, base::OnceClosure callback); } // namespace content
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 833a121..f2048ed 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -792,6 +792,7 @@ void ContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) {} bool ContentBrowserClient::WillCreateURLLoaderFactory(
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 1b5a39a..c767099e 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1358,6 +1358,7 @@ virtual void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories); // Describes the purpose of the factory in WillCreateURLLoaderFactory(). @@ -1791,8 +1792,8 @@ // the url was made, e.g. by launching an app. Note that this does not // guarantee that the app successfully handled it. // If this is a navigation request, then |child_id| will be - // ChildProcessHost::kInvalidUniqueID and |navigation_ui_data| will valid. - // Otherwise child_id will be the process id and |navigation_ui_data| will be + // ChildProcessHost::kInvalidUniqueID and |navigation_ui| will be valid. + // Otherwise |child_id| will be the process id and |navigation_data| will be // nullptr. // // |initiating_origin| is the origin of the last redirecting server (falling
diff --git a/content/public/browser/gpu_utils.cc b/content/public/browser/gpu_utils.cc index 534ef6a..31c72b5 100644 --- a/content/public/browser/gpu_utils.cc +++ b/content/public/browser/gpu_utils.cc
@@ -88,8 +88,6 @@ gpu_preferences.gpu_sandbox_start_early = command_line->HasSwitch(switches::kGpuSandboxStartEarly); - gpu_preferences.enable_oop_rasterization = - command_line->HasSwitch(switches::kEnableOopRasterization); gpu_preferences.disable_oop_rasterization = command_line->HasSwitch(switches::kDisableOopRasterization);
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h index 792b67d5..32b4bb166 100644 --- a/content/public/browser/notification_types.h +++ b/content/public/browser/notification_types.h
@@ -41,9 +41,9 @@ // Other load-related (not from NavigationController) ---------------------- - // Corresponds to ViewHostMsg_DocumentOnLoadCompletedInMainFrame. The source - // is the WebContents. - // DEPRECATED: Use WebContentsObserver::DocumentOnLoadCompletedInMainFrame() + // DEPRECATED: Use + // WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame() when this + // is fired. // TODO(https://crbug.com/1174761): Remove. NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 3472819..b7883f3 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -998,7 +998,7 @@ virtual void DisableWebRtcEventLogOutput(int lid) = 0; // Return true if onload has been executed in the renderer in the main frame. - virtual bool IsDocumentOnLoadCompletedInMainFrame() = 0; + virtual bool IsDocumentOnLoadCompletedInPrimaryMainFrame() = 0; // Returns the raw list of favicon candidates as reported to observers via // since the last navigation start. If called on a subframe, returns the
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 214d17b..700091a 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -585,8 +585,7 @@ const url::Origin& origin, mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) = 0; virtual void CreateLockManager( - int render_frame_id, - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::LockManager> receiver) = 0; virtual void CreatePermissionService( const url::Origin& origin,
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index ccbad7b..3e209a6 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -592,12 +592,9 @@ // Returns whether the current primary main document has reached and finished // executing its onload() handler. Corresponds to - // WebContentsObserver::DocumentOnLoadCompletedInMainFrame() and see comments - // there for more details. - // - // TODO(crbug.com/1257140): Rename IsDocumentOnLoadCompletedInMainFrame to - // IsDocumentOnLoadCompletedInPrimaryMainFrame to capture the new behaviour. - virtual bool IsDocumentOnLoadCompletedInMainFrame() = 0; + // WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame() and see + // comments there for more details. + virtual bool IsDocumentOnLoadCompletedInPrimaryMainFrame() = 0; // Returns whether this WebContents is waiting for a first-response for the // main resource of the page.
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index 66e8be1e..c193932e 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -363,26 +363,19 @@ // current document (i.e., |render_frame_host|) has completed. This happens // when the primary main document has finished running onload events after // loading all content (images, scripts, etc). Prefer using - // WebContents::IsDocumentOnLoadCompletedInMainFrame instead of saving this - // state in your component. + // WebContents::IsDocumentOnLoadCompletedInPrimaryMainFrame instead of saving + // this state in your component. // - // For prerendering we dispatch DocumentOnLoadCompletedInMainFrame on + // For prerendering we dispatch DocumentOnLoadCompletedInPrimaryMainFrame on // activation whereas for BackForwardCache restores we don't dispatch - // DocumentOnLoadCompletedInMainFrame. + // DocumentOnLoadCompletedInPrimaryMainFrame. // - // DocumentOnLoadCompletedInMainFrame is typically used by the embedders to - // perform actions on a loaded page, for example showing load completion - // bubbles, injecting scripts which take page snapshots. Note, however, that - // some web pages might still be loading (i.e. if they dynamically inject - // content). - // - // TODO(crbug.com/1257140): Rename DocumentOnLoadCompletedInMainFrame to - // DocumentOnLoadCompletedInPrimaryMainFrame to capture the new behavior. - // TODO(crbug.com/1271481): Remove RenderFrameHost* argument from - // DocumentOnLoadCompletedInMainFrame and directly rely on - // WebContents::GetPrimaryMainFrame(). - virtual void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) {} + // DocumentOnLoadCompletedInPrimaryMainFrame is typically used by the + // embedders to perform actions on a loaded page, for example showing load + // completion bubbles, injecting scripts which take page snapshots. Note, + // however, that some web pages might still be loading (i.e. if they + // dynamically inject content). + virtual void DocumentOnLoadCompletedInPrimaryMainFrame() {} // This method is invoked when we have received a response from the // renderer in response to a dom automation controller action.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 6b9a2db..943a1df7 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -483,13 +483,9 @@ // file:///alias/some/path.html into file:///replacement/some/path.html. const char kFileUrlPathAlias[] = "file-url-path-alias"; -// Disables OOP rasterization. Takes precedence over the enable flag. +// Disables OOP rasterization. const char kDisableOopRasterization[] = "disable-oop-rasterization"; -// Turns on out of process raster for the renderer whenever gpu raster -// would have been used. Enables the chromium_raster_transport extension. -const char kEnableOopRasterization[] = "enable-oop-rasterization"; - // Forces the Chrome major version to 100 in the User-Agent string. const char kForceMajorVersionTo100[] = "force-major-version-to-100";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index d09b07e..eb6561f 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -141,7 +141,6 @@ CONTENT_EXPORT extern const char kFileUrlPathAlias[]; CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kDisableOopRasterization[]; -CONTENT_EXPORT extern const char kEnableOopRasterization[]; CONTENT_EXPORT extern const char kForceMajorVersionToMinorPosition[]; CONTENT_EXPORT extern const char kForceMajorVersionTo100[]; CONTENT_EXPORT extern const char kForceMinorVersionTo100[];
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 5883bcc..be2dcf1d 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1985,7 +1985,8 @@ std::string GetCookies(BrowserContext* browser_context, const GURL& url, - net::CookieOptions::SameSiteCookieContext context) { + net::CookieOptions::SameSiteCookieContext context, + net::CookiePartitionKeyCollection key_collection) { std::string cookies; base::RunLoop run_loop; mojo::Remote<network::mojom::CookieManager> cookie_manager; @@ -1995,7 +1996,7 @@ net::CookieOptions options; options.set_same_site_cookie_context(context); cookie_manager->GetCookieList( - url, options, net::CookiePartitionKeyCollection(), + url, options, key_collection, base::BindOnce( [](std::string* cookies_out, base::RunLoop* run_loop, const net::CookieAccessResultList& cookies, @@ -2010,7 +2011,8 @@ std::vector<net::CanonicalCookie> GetCanonicalCookies( BrowserContext* browser_context, - const GURL& url) { + const GURL& url, + net::CookiePartitionKeyCollection key_collection) { std::vector<net::CanonicalCookie> cookies; base::RunLoop run_loop; mojo::Remote<network::mojom::CookieManager> cookie_manager; @@ -2022,7 +2024,7 @@ options.set_same_site_cookie_context( net::CookieOptions::SameSiteCookieContext::MakeInclusive()); cookie_manager->GetCookieList( - url, options, net::CookiePartitionKeyCollection(), + url, options, key_collection, base::BindOnce( [](base::RunLoop* run_loop, std::vector<net::CanonicalCookie>* cookies_out, @@ -2055,8 +2057,7 @@ net::CookieOptions options; options.set_include_httponly(); options.set_same_site_cookie_context(context); - options.set_same_party_context(net::SamePartyContext( - party_context, net::FirstPartySetsContextType::kUnknown)); + options.set_same_party_context(net::SamePartyContext(party_context)); cookie_manager->SetCanonicalCookie( *cc.get(), url, options, base::BindOnce(
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 146e12f2..7d3df9d 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -42,6 +42,7 @@ #include "ipc/message_filter.h" #include "net/base/load_flags.h" #include "net/cookies/cookie_options.h" +#include "net/cookies/cookie_partition_key_collection.h" #include "services/network/public/mojom/network_service.mojom.h" #include "storage/common/file_system/file_system_types.h" #include "testing/gtest/include/gtest/gtest.h" @@ -924,12 +925,16 @@ BrowserContext* browser_context, const GURL& url, net::CookieOptions::SameSiteCookieContext context = - net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + net::CookieOptions::SameSiteCookieContext::MakeInclusive(), + net::CookiePartitionKeyCollection key_collection = + net::CookiePartitionKeyCollection::ContainsAll()); // Returns the canonical cookies for the given url. std::vector<net::CanonicalCookie> GetCanonicalCookies( BrowserContext* browser_context, - const GURL& url); + const GURL& url, + net::CookiePartitionKeyCollection key_collection = + net::CookiePartitionKeyCollection::ContainsAll()); // Sets a cookie for the given url. Uses inclusive SameSiteCookieContext and // SamePartyContext::Type by default, which get cookies regardless of their
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 689734f4..0243a7b 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -223,8 +223,7 @@ mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) override { } void CreateLockManager( - int render_frame_id, - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::LockManager> receiver) override {} void CreateOneShotSyncService( const url::Origin& origin,
diff --git a/content/public/test/mock_web_contents_observer.h b/content/public/test/mock_web_contents_observer.h index 724c8916..f9052d96 100644 --- a/content/public/test/mock_web_contents_observer.h +++ b/content/public/test/mock_web_contents_observer.h
@@ -99,10 +99,7 @@ DocumentAvailableInMainFrame, (RenderFrameHost* render_frame_host), (override)); - MOCK_METHOD(void, - DocumentOnLoadCompletedInMainFrame, - (RenderFrameHost* render_frame_host), - (override)); + MOCK_METHOD(void, DocumentOnLoadCompletedInPrimaryMainFrame, (), (override)); MOCK_METHOD(void, DOMContentLoaded, (RenderFrameHost* render_frame_host),
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index f202ec4b..64ff8e7 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -297,7 +297,8 @@ public: explicit Awaiter(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), - observed_(web_contents->IsDocumentOnLoadCompletedInMainFrame()) {} + observed_( + web_contents->IsDocumentOnLoadCompletedInPrimaryMainFrame()) {} Awaiter(const Awaiter&) = delete; Awaiter& operator=(const Awaiter&) = delete; @@ -307,12 +308,11 @@ void Await() { if (!observed_) run_loop_.Run(); - DCHECK(web_contents()->IsDocumentOnLoadCompletedInMainFrame()); + DCHECK(web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame()); } // WebContentsObserver: - void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) override { + void DocumentOnLoadCompletedInPrimaryMainFrame() override { observed_ = true; if (run_loop_.running()) run_loop_.Quit();
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index f449ca6..39a5495 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -154,7 +154,7 @@ // inner WebContents will be deleted if the frame it's attached to goes away. WebContents* CreateAndAttachInnerContents(RenderFrameHost* rfh); -// Spins a run loop until IsDocumentOnLoadCompletedInMainFrame() is true. +// Spins a run loop until IsDocumentOnLoadCompletedInPrimaryMainFrame() is true. void AwaitDocumentOnLoadCompleted(WebContents* web_contents); // Helper class to Run and Quit the message loop. Run and Quit can only happen
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 91078dc..8f5d497 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -617,7 +617,7 @@ if (has_valid_page_state) return WebFrameLoadType::kBackForward; // If there is no valid page state, fall through to the default case. - FALLTHROUGH; + [[fallthrough]]; case blink::mojom::NavigationType::SAME_DOCUMENT: case blink::mojom::NavigationType::DIFFERENT_DOCUMENT:
diff --git a/content/services/auction_worklet/auction_worklet_service_impl.cc b/content/services/auction_worklet/auction_worklet_service_impl.cc index f05e017..d9c2ce3 100644 --- a/content/services/auction_worklet/auction_worklet_service_impl.cc +++ b/content/services/auction_worklet/auction_worklet_service_impl.cc
@@ -44,12 +44,15 @@ bool pause_for_debugger_on_start, mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const GURL& decision_logic_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, LoadSellerWorkletCallback load_seller_worklet_callback) { seller_worklets_.Add( std::make_unique<SellerWorklet>( auction_v8_helper_, pause_for_debugger_on_start, - std::move(pending_url_loader_factory), script_source_url, + std::move(pending_url_loader_factory), decision_logic_url, + trusted_scoring_signals_url, top_window_origin, std::move(load_seller_worklet_callback)), std::move(seller_worklet_receiver)); }
diff --git a/content/services/auction_worklet/auction_worklet_service_impl.h b/content/services/auction_worklet/auction_worklet_service_impl.h index 78edc91..b8fbb96 100644 --- a/content/services/auction_worklet/auction_worklet_service_impl.h +++ b/content/services/auction_worklet/auction_worklet_service_impl.h
@@ -15,6 +15,12 @@ #include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" +class GURL; + +namespace url { +class Origin; +} + namespace auction_worklet { class BidderWorklet; @@ -47,7 +53,9 @@ bool pause_for_debugger_on_start, mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const GURL& decision_logic_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, LoadSellerWorkletCallback load_seller_worklet_callback) override; private:
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index 7e2d6de..c22a752 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -41,6 +41,7 @@ #include "v8/include/v8-object.h" #include "v8/include/v8-primitive.h" #include "v8/include/v8-template.h" +#include "v8/include/v8-wasm.h" namespace auction_worklet { @@ -158,6 +159,7 @@ // worklets shouldn't be created when there's no bidding URL. script_source_url_( bidding_interest_group->group.bidding_url.value_or(GURL())), + wasm_helper_url_(bidding_interest_group->group.bidding_wasm_helper_url), trusted_bidding_signals_url_( bidding_interest_group->group.trusted_bidding_signals_url), trusted_bidding_signals_keys_( @@ -212,8 +214,9 @@ generate_bid_task->auction_start_time = auction_start_time; generate_bid_task->callback = std::move(generate_bid_callback); - // If worklet script failed to load, fail and exit early. - if (worklet_js_load_state_ == LoadState::kFailure) { + // If worklet script failed to load, or WASM was requested and failed, fail + // and exit early. + if (CodeLoadState() == LoadState::kFailure) { DeliverBidCallbackOnUserThread(generate_bid_task, mojom::BidderWorkletBidPtr(), /*error_msgs=*/std::vector<std::string>()); @@ -244,6 +247,7 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const url::Origin& browser_signal_seller_origin, ReportWinCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); @@ -255,12 +259,15 @@ report_win_task->seller_signals_json = seller_signals_json; report_win_task->browser_signal_render_url = browser_signal_render_url; report_win_task->browser_signal_bid = browser_signal_bid; + report_win_task->browser_signal_seller_origin = browser_signal_seller_origin; report_win_task->callback = std::move(callback); - // If worklet script isn't loaded, can't run script immediately. - if (worklet_js_load_state_ != LoadState::kSuccess) { - // If worklet script failed to load, fail and exit early. - if (worklet_js_load_state_ == LoadState::kFailure) { + // If worklet script and, if requested, WASM, aren't loaded, can't run script + // immediately. + LoadState code_load_state = CodeLoadState(); + if (code_load_state != LoadState::kSuccess) { + // If required files failed to load, fail and exit early. + if (code_load_state == LoadState::kFailure) { DeliverReportWinOnUserThread(report_win_task, /*report_url=*/absl::optional<GURL>(), /*errors=*/std::vector<std::string>()); @@ -309,6 +316,12 @@ worklet_script_ = WorkletLoader::TakeScript(std::move(worklet_script)); } +void BidderWorklet::V8State::SetWasmHelper( + WorkletWasmLoader::Result wasm_helper) { + DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_); + wasm_helper_ = std::move(wasm_helper); +} + void BidderWorklet::V8State::ReportWin( const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, @@ -316,6 +329,7 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const url::Origin& browser_signal_seller_origin, ReportWinCallbackInternal callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_); @@ -354,7 +368,9 @@ bidding_interest_group_->group.name) || !browser_signals_dict.Set("renderUrl", browser_signal_render_url.spec()) || - !browser_signals_dict.Set("bid", browser_signal_bid)) { + !browser_signals_dict.Set("bid", browser_signal_bid) || + !browser_signals_dict.Set("seller", + browser_signal_seller_origin.Serialize())) { PostReportWinCallbackToUserThread(std::move(callback), absl::nullopt /* report_url */, std::vector<std::string>() /* errors */); @@ -474,6 +490,19 @@ return; } + if (wasm_helper_.success()) { + v8::Local<v8::WasmModuleObject> module; + v8::Maybe<bool> result = v8::Nothing<bool>(); + if (WorkletWasmLoader::MakeModule(wasm_helper_).ToLocal(&module)) { + result = browser_signals->Set( + context, gin::StringToV8(isolate, "wasmHelper"), module); + } + if (result.IsNothing() || !result.FromJust()) { + PostErrorBidCallbackToUserThread(std::move(callback)); + return; + } + } + v8::Local<v8::Value> prev_wins; if (!CreatePrevWinsArray(v8_helper_.get(), context, auction_start_time, bidding_interest_group_->signals->prev_wins) @@ -678,6 +707,17 @@ url_loader_factory_.get(), script_source_url_, v8_helper_, debug_id_, base::BindOnce(&BidderWorklet::OnScriptDownloaded, base::Unretained(this))); + + if (wasm_helper_url_.has_value()) { + wasm_loader_ = std::make_unique<WorkletWasmLoader>( + url_loader_factory_.get(), wasm_helper_url_.value(), v8_helper_, + debug_id_, + base::BindOnce(&BidderWorklet::OnWasmDownloaded, + base::Unretained(this))); + } else { + // WASM helper is optional if not specified. + worklet_wasm_load_state_ = LoadState::kSuccess; + } } void BidderWorklet::OnScriptDownloaded(WorkletLoader::Result worklet_script, @@ -689,7 +729,8 @@ // Fail all pending tasks if the script failed to load. if (!worklet_script.success()) { worklet_js_load_state_ = LoadState::kFailure; - load_script_error_msg_ = std::move(error_msg); + if (error_msg.has_value()) + load_code_error_msgs_.push_back(std::move(error_msg.value())); FailAllPendingTasks(); return; } @@ -699,18 +740,46 @@ base::BindOnce(&BidderWorklet::V8State::SetWorkletScript, base::Unretained(v8_state_.get()), std::move(worklet_script))); + RunReadyGenerateBidTasks(); + RunReportWinTasks(); // These only depends on JS, so they can be run. +} - // Run any pending task that's ready to run. +void BidderWorklet::OnWasmDownloaded(WorkletWasmLoader::Result wasm_helper, + absl::optional<std::string> error_msg) { + DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); + wasm_loader_.reset(); + + // If the WASM helper is actually requested, its failure fails the bid. + if (!wasm_helper.success()) { + worklet_wasm_load_state_ = LoadState::kFailure; + if (error_msg.has_value()) + load_code_error_msgs_.push_back(std::move(error_msg.value())); + FailAllPendingTasks(); + return; + } + + worklet_wasm_load_state_ = LoadState::kSuccess; + v8_runner_->PostTask(FROM_HERE, + base::BindOnce(&BidderWorklet::V8State::SetWasmHelper, + base::Unretained(v8_state_.get()), + std::move(wasm_helper))); + RunReadyGenerateBidTasks(); + // ReportWin() tasks currently don't have access to WASM. +} + +void BidderWorklet::RunReadyGenerateBidTasks() { // Run all GenerateBid() tasks that are ready. GenerateBidIfReady() does *not* // modify `generate_bid_tasks_` when invoked, so this is safe. for (auto generate_bid_task = generate_bid_tasks_.begin(); generate_bid_task != generate_bid_tasks_.end(); ++generate_bid_task) { GenerateBidIfReady(generate_bid_task); } +} +void BidderWorklet::RunReportWinTasks() { // Run all ReportWin() tasks. RunReportWin() does *not* modify - // `generate_bid_tasks_` when invoked, so this is safe. + // `report_win_tasks_` when invoked, so this is safe. for (auto report_win_task = report_win_tasks_.begin(); report_win_task != report_win_tasks_.end(); ++report_win_task) { RunReportWin(report_win_task); @@ -732,10 +801,10 @@ void BidderWorklet::GenerateBidIfReady(GenerateBidTaskList::iterator task) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); - // Script load failure should abort all tasks before getting here. - DCHECK_NE(worklet_js_load_state_, LoadState::kFailure); - if (task->trusted_bidding_signals || - worklet_js_load_state_ != LoadState::kSuccess) { + // Script or WASM load failure should abort all tasks before getting here. + LoadState code_load_state = CodeLoadState(); + DCHECK_NE(code_load_state, LoadState::kFailure); + if (task->trusted_bidding_signals || code_load_state != LoadState::kSuccess) { return; } @@ -761,6 +830,7 @@ task->auction_signals_json, task->per_buyer_signals_json, task->top_window_origin, task->seller_signals_json, task->browser_signal_render_url, task->browser_signal_bid, + task->browser_signal_seller_origin, base::BindOnce(&BidderWorklet::DeliverReportWinOnUserThread, weak_ptr_factory_.GetWeakPtr(), task))); } @@ -785,8 +855,8 @@ std::vector<std::string> error_msgs) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); - if (load_script_error_msg_) - error_msgs.emplace_back(load_script_error_msg_.value()); + error_msgs.insert(error_msgs.end(), load_code_error_msgs_.begin(), + load_code_error_msgs_.end()); if (task->trusted_bidding_signals_error_msg) { error_msgs.emplace_back( std::move(task->trusted_bidding_signals_error_msg).value()); @@ -800,10 +870,25 @@ absl::optional<GURL> report_url, std::vector<std::string> errors) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); - if (load_script_error_msg_) - errors.emplace_back(load_script_error_msg_.value()); + errors.insert(errors.end(), load_code_error_msgs_.begin(), + load_code_error_msgs_.end()); std::move(task->callback).Run(std::move(report_url), errors); report_win_tasks_.erase(task); } +BidderWorklet::LoadState BidderWorklet::CodeLoadState() const { + if (worklet_js_load_state_ == LoadState::kFailure || + worklet_wasm_load_state_ == LoadState::kFailure) { + return LoadState::kFailure; + } + + if (worklet_js_load_state_ == LoadState::kLoading || + worklet_wasm_load_state_ == LoadState::kLoading) { + return LoadState::kLoading; + } + DCHECK_EQ(worklet_js_load_state_, LoadState::kSuccess); + DCHECK_EQ(worklet_wasm_load_state_, LoadState::kSuccess); + return LoadState::kSuccess; +} + } // namespace auction_worklet
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h index 4d802051..19bec47 100644 --- a/content/services/auction_worklet/bidder_worklet.h +++ b/content/services/auction_worklet/bidder_worklet.h
@@ -84,6 +84,7 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const url::Origin& browser_signal_seller_origin, ReportWinCallback callback) override; void ConnectDevToolsAgent( mojo::PendingReceiver<blink::mojom::DevToolsAgent> agent) override; @@ -123,6 +124,7 @@ std::string seller_signals_json; GURL browser_signal_render_url; double browser_signal_bid; + url::Origin browser_signal_seller_origin; ReportWinCallback callback; }; @@ -140,6 +142,7 @@ mojom::BiddingInterestGroupPtr bidding_interest_group); void SetWorkletScript(WorkletLoader::Result worklet_script); + void SetWasmHelper(WorkletWasmLoader::Result wasm_helper); // These match the mojom GenerateBidCallback / ReportWinCallback functions, // except the errors vectors are passed by value. They're callbacks that @@ -157,6 +160,7 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const url::Origin& browser_signal_seller_origin, ReportWinCallbackInternal callback); void GenerateBid( @@ -200,6 +204,9 @@ // different context and executed, without persisting any state. v8::Global<v8::UnboundScript> worklet_script_; + // Loaded WASM module. Can be used to create instances for each context. + WorkletWasmLoader::Result wasm_helper_; + const GURL script_source_url_; SEQUENCE_CHECKER(v8_sequence_checker_); @@ -212,6 +219,10 @@ void OnScriptDownloaded(WorkletLoader::Result worklet_script, absl::optional<std::string> error_msg); + void OnWasmDownloaded(WorkletWasmLoader::Result worklet_script, + absl::optional<std::string> error_msg); + void RunReadyGenerateBidTasks(); + void RunReportWinTasks(); void OnTrustedBiddingSignalsDownloaded( GenerateBidTaskList::iterator task, @@ -243,6 +254,9 @@ absl::optional<GURL> report_url, std::vector<std::string> errors); + // Combines `worklet_js_load_state_` and `worklet_wasm_load_state_`. + LoadState CodeLoadState() const; + scoped_refptr<base::SequencedTaskRunner> v8_runner_; const scoped_refptr<AuctionV8Helper> v8_helper_; @@ -256,6 +270,10 @@ std::unique_ptr<WorkletLoader> worklet_loader_; LoadState worklet_js_load_state_ = LoadState::kLoading; + absl::optional<GURL> wasm_helper_url_; + std::unique_ptr<WorkletWasmLoader> wasm_loader_; + LoadState worklet_wasm_load_state_ = LoadState::kLoading; + // Values copied from the interest group used to create the BidderWorklet. const absl::optional<GURL> trusted_bidding_signals_url_; const absl::optional<std::vector<std::string>> trusted_bidding_signals_keys_; @@ -270,8 +288,8 @@ GenerateBidTaskList generate_bid_tasks_; ReportWinTaskList report_win_tasks_; - // Error that occurred while loading the bidder worklet script, if any. - absl::optional<std::string> load_script_error_msg_; + // Errors that occurred while loading the code, if any. + std::vector<std::string> load_code_error_msgs_; SEQUENCE_CHECKER(user_sequence_checker_);
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index 9cac626a..22d6ace 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/bind.h" +#include "base/cxx17_backports.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" @@ -39,6 +40,23 @@ namespace auction_worklet { namespace { +// This was produced by running wat2wasm on this: +// (module +// (global (export "test_const") i32 (i32.const 123)) +// ) +const uint8_t kToyWasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x07, 0x01, + 0x7f, 0x00, 0x41, 0xfb, 0x00, 0x0b, 0x07, 0x0e, 0x01, 0x0a, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x03, 0x00}; + +const char kWasmUrl[] = "https://foo.test/helper.wasm"; + +// Packs kToyWasm into a std::string. +std::string ToyWasm() { + return std::string(reinterpret_cast<const char*>(kToyWasm), + base::size(kToyWasm)); +} + // Creates generateBid() scripts with the specified result value, in raw // Javascript. Allows returning generateBid() arguments, arbitrary values, // incorrect types, etc. @@ -196,6 +214,7 @@ bidder_worklet->ReportWin( auction_signals_, per_buyer_signals_, browser_signal_top_window_origin_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, base::BindOnce( [](const absl::optional<GURL>& expected_report_url, const std::vector<std::string>& expected_errors, @@ -230,6 +249,7 @@ interest_group.owner = interest_group_owner_; interest_group.name = interest_group_name_; interest_group.bidding_url = url; + interest_group.bidding_wasm_helper_url = interest_group_wasm_url_; interest_group.user_bidding_signals = interest_group_user_bidding_signals_; interest_group.trusted_bidding_signals_url = interest_group_trusted_bidding_signals_url_; @@ -323,6 +343,7 @@ url::Origin interest_group_owner_; std::string interest_group_name_; const GURL interest_group_bidding_url_ = GURL("https://url.test/"); + absl::optional<GURL> interest_group_wasm_url_; absl::optional<std::string> interest_group_user_bidding_signals_; std::vector<blink::InterestGroup::Ad> interest_group_ads_; absl::optional<std::vector<blink::InterestGroup::Ad>> @@ -1437,6 +1458,149 @@ base::TimeDelta())); } +TEST_F(BidderWorkletTest, GenerateBidWasm404) { + interest_group_wasm_url_ = GURL(kWasmUrl); + // Have the WASM URL 404. + AddResponse(&url_loader_factory_, interest_group_wasm_url_.value(), + kWasmMimeType, + /*charset=*/absl::nullopt, "Error 404", kAllowFledgeHeader, + net::HTTP_NOT_FOUND); + + RunGenerateBidWithJavascriptExpectingResult( + CreateBasicGenerateBidScript(), + /*expected_bid=*/mojom::BidderWorkletBidPtr(), + {"Failed to load https://foo.test/helper.wasm " + "HTTP status = 404 Not Found."}); +} + +TEST_F(BidderWorkletTest, GenerateBidWasmFailure) { + interest_group_wasm_url_ = GURL(kWasmUrl); + // Instead of WASM have JS, but with WASM mimetype. + AddResponse(&url_loader_factory_, interest_group_wasm_url_.value(), + kWasmMimeType, + /*charset=*/absl::nullopt, CreateBasicGenerateBidScript()); + + RunGenerateBidWithJavascriptExpectingResult( + CreateBasicGenerateBidScript(), + /*expected_bid=*/mojom::BidderWorkletBidPtr(), + {"https://foo.test/helper.wasm Uncaught CompileError: " + "WasmModuleObject::Compile(): expected magic word 00 61 73 6d, found " + "0a 20 20 20 @+0."}); +} + +TEST_F(BidderWorkletTest, GenerateBidWasm) { + std::string bid_script = CreateGenerateBidScript( + R"({ad: WebAssembly.Module.exports(browserSignals.wasmHelper), bid: 1, + render:"https://response.test/"})"); + + interest_group_wasm_url_ = GURL(kWasmUrl); + AddResponse(&url_loader_factory_, GURL(kWasmUrl), kWasmMimeType, + /*charset=*/absl::nullopt, ToyWasm()); + + RunGenerateBidWithJavascriptExpectingResult( + bid_script, mojom::BidderWorkletBid::New( + R"([{"name":"test_const","kind":"global"}])", 1, + GURL("https://response.test/"), + /*ad_components=*/absl::nullopt, base::TimeDelta())); +} + +TEST_F(BidderWorkletTest, WasmReportWin) { + // Regression test for state machine bug during development, with + // double-execution of report win tasks when waiting on WASM. + AddJavascriptResponse( + &url_loader_factory_, interest_group_bidding_url_, + CreateReportWinScript(R"(sendReportTo("https://foo.test"))")); + interest_group_wasm_url_ = GURL(kWasmUrl); + + auto bidder_worklet = CreateWorklet(); + ASSERT_TRUE(bidder_worklet); + + // Wedge the V8 thread so that completed first instance of reportWin doesn't + // fully wrap up and clean up the task by time the WASM is delivered. + base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); + + base::RunLoop run_loop; + bidder_worklet->ReportWin( + /*auction_signals_json=*/"0", per_buyer_signals_, + browser_signal_top_window_origin_, seller_signals_, + browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, + base::BindLambdaForTesting( + [&run_loop](const absl::optional<GURL>& report_url, + const std::vector<std::string>& errors) { + run_loop.Quit(); + })); + base::RunLoop().RunUntilIdle(); + AddResponse(&url_loader_factory_, GURL(kWasmUrl), kWasmMimeType, + /*charset=*/absl::nullopt, ToyWasm()); + base::RunLoop().RunUntilIdle(); + event_handle->Signal(); + run_loop.Run(); + // Make sure there isn't a second attempt to complete lurking. + task_environment_.RunUntilIdle(); +} + +TEST_F(BidderWorkletTest, WasmOrdering) { + enum Event { kWasmSuccess, kJsSuccess, kWasmFailure, kJsFailure }; + + struct Test { + std::vector<Event> events; + bool expect_success; + }; + + const Test tests[] = { + {{kWasmSuccess, kJsSuccess}, /*expect_success=*/true}, + {{kJsSuccess, kWasmSuccess}, /*expect_success=*/true}, + {{kWasmFailure, kJsSuccess}, /*expect_success=*/false}, + {{kJsSuccess, kWasmFailure}, /*expect_success=*/false}, + {{kWasmSuccess, kJsFailure}, /*expect_success=*/false}, + {{kJsFailure, kWasmSuccess}, /*expect_success=*/false}, + {{kJsFailure, kWasmFailure}, /*expect_success=*/false}, + {{kWasmFailure, kJsFailure}, /*expect_success=*/false}, + }; + + interest_group_wasm_url_ = GURL(kWasmUrl); + + for (const Test& test : tests) { + url_loader_factory_.ClearResponses(); + + mojo::Remote<mojom::BidderWorklet> bidder_worklet = CreateWorklet(); + load_script_run_loop_ = std::make_unique<base::RunLoop>(); + GenerateBid(bidder_worklet.get()); + + for (Event ev : test.events) { + switch (ev) { + case kWasmSuccess: + AddResponse(&url_loader_factory_, GURL(kWasmUrl), + std::string(kWasmMimeType), + /*charset=*/absl::nullopt, ToyWasm()); + break; + + case kJsSuccess: + AddJavascriptResponse(&url_loader_factory_, + interest_group_bidding_url_, + CreateBasicGenerateBidScript()); + break; + + case kWasmFailure: + url_loader_factory_.AddResponse(kWasmUrl, "", net::HTTP_NOT_FOUND); + break; + + case kJsFailure: + url_loader_factory_.AddResponse(interest_group_bidding_url_.spec(), + "", net::HTTP_NOT_FOUND); + + break; + }; + task_environment_.RunUntilIdle(); + } + + load_script_run_loop_->Run(); + load_script_run_loop_.reset(); + EXPECT_EQ(bid_.is_null(), !test.expect_success); + } +} + // Utility method to create a vector of PreviousWin. Needed because StructPtrs // don't allow copying. std::vector<mojom::PreviousWinPtr> CreateWinList( @@ -1646,6 +1810,7 @@ bidder_worklet->ReportWin( auction_signals_, per_buyer_signals_, browser_signal_top_window_origin_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, base::BindOnce([](const absl::optional<GURL>& report_url, const std::vector<std::string>& errors) { ADD_FAILURE() << "Callback should not be invoked since worklet deleted"; @@ -1682,6 +1847,7 @@ /*auction_signals_json=*/base::NumberToString(i), per_buyer_signals_, browser_signal_top_window_origin_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, base::BindLambdaForTesting( [&run_loop, &num_report_win_calls, i]( const absl::optional<GURL>& report_url, @@ -1730,6 +1896,7 @@ /*auction_signals_json=*/base::NumberToString(i), per_buyer_signals_, browser_signal_top_window_origin_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, base::BindLambdaForTesting( [&run_loop, &num_report_win_calls]( const absl::optional<GURL>& report_url, @@ -1861,6 +2028,14 @@ GURL("https://jumboshrimp.test")); } +TEST_F(BidderWorkletTest, ReportWinBrowserSignalSeller) { + GURL seller_raw_url = GURL("https://seller.origin.test"); + browser_signal_seller_origin_ = url::Origin::Create(seller_raw_url); + RunReportWinWithFunctionBodyExpectingResult( + "sendReportTo(browserSignals.seller)", + /*expected_report_url=*/seller_raw_url); +} + // Subsequent runs of the same script should not affect each other. Same is true // for different scripts, but it follows from the single script case. // @@ -1905,6 +2080,7 @@ bidder_worklet->ReportWin( auction_signals_, per_buyer_signals_, browser_signal_top_window_origin_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_seller_origin_, base::BindLambdaForTesting( [&run_loop](const absl::optional<GURL>& report_url, const std::vector<std::string>& errors) {
diff --git a/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom b/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom index 9f94e380..ebd268a 100644 --- a/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom +++ b/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom
@@ -55,6 +55,12 @@ BiddingInterestGroup bidding_interest_group); // Attempts to load Javascript at the specified URL and loads a SellerWorklet. + // While a single SellerWorklet object can be used in auctions with different + // AuctionAdConfigs, the configs of all auctions using a single SellerWorklet + // object must share a `script_source_url` and `trusted_scoring_signals_url`, + // which match the ones passed in when creating the SellerWorklet. All + // auctions sharing a SellerWorklet must also have the same + // `top_window_origin`. // // Arguments: // `seller_worklet` The pipe to communicate with the SellerWorklet. Closing @@ -73,6 +79,11 @@ // // `script_source_url` is the URL of the seller worklet script. // + // `trusted_scoring_signals_url` The trusted scoring signals URL for the + // auction, if there is one. + // + // `top_window_origin` The origin of the top-level window running the auction. + // // Returns: // `success` is true if the worklet was successfully loaded. // @@ -84,7 +95,9 @@ pending_receiver<SellerWorklet> seller_worklet, bool pause_for_debugger_on_start, pending_remote<network.mojom.URLLoaderFactory> url_loader_factory, - url.mojom.Url script_source_url) => ( + url.mojom.Url script_source_url, + url.mojom.Url? trusted_scoring_signals_url, + url.mojom.Origin top_window_origin) => ( bool success, array<string> errors); };
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom index 449af89..180cd3e0 100644 --- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -99,7 +99,7 @@ // where the auction is running. // // `browser_signal_seller_origin` The origin of the seller script running - // the auction. + // the auction. Typically a valid, non-opaque HTTPS origin. // // `auction_start_time` The time the auction started, used to ensure the // last win times provided to all worklets are relative to the same time. @@ -145,6 +145,9 @@ // BidderWorklet's generateBid() method, invoked as part of BidderWorklet // creation. // + // `browser_signal_seller_origin` The origin of the seller script running + // the auction. Typically a valid, non-opaque HTTPS origin. + // // Returns: // `report_url` is the URL to request to report the result of the auction // to the bidder. It will be null if no reports are requested, or the @@ -160,7 +163,8 @@ url.mojom.Origin browser_signal_top_window_origin, string seller_signals_json, url.mojom.Url browser_signal_render_url, - double browser_signal_bid) => ( + double browser_signal_bid, + url.mojom.Origin browser_signal_seller_origin) => ( url.mojom.Url? report_url, array<string> errors);
diff --git a/content/services/auction_worklet/public/mojom/seller_worklet.mojom b/content/services/auction_worklet/public/mojom/seller_worklet.mojom index ad7b683..af56a96 100644 --- a/content/services/auction_worklet/public/mojom/seller_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
@@ -24,17 +24,19 @@ // leaked between consecutive invocations of this method, or between // invocations of this method and ReportResult(). // + // In the case a worklet needs to fetch trusted scoring signals before + // running any Javascript, the method may wait so it can merge several signals + // fetched together. See SendPendingSignalsRequests() for more information. + // // Arguments: // `ad_metadata_json` JSON representation of the `ad` value returned by the // BidderWorklet that offered the bid. // // `bid` The numeric value of the bid offered by the BidWorklet. // - // `auction_config` The configuration provided by client JavaScript in the - // renderer in order to initiate the auction. - // - // `browser_signal_top_window_origin` The top-level origin of the window - // running the auction. + // `shareable_auction_config` Subset of the blink.mojom.AuctionAdConfig that + // excludes values that must be the same for all auctions using this + // worklet. // // `browser_signal_interest_group_owner` The owner of the interest group // that offered the bid. @@ -60,14 +62,22 @@ // `score` is 0. ScoreAd(string ad_metadata_json, double bid, - blink.mojom.AuctionAdConfig auction_config, - url.mojom.Origin browser_signal_top_window_origin, + blink.mojom.ShareableAuctionAdConfig shareable_auction_config, url.mojom.Origin browser_signal_interest_group_owner, url.mojom.Url browser_signal_render_url, array<url.mojom.Url> browser_signal_ad_component_render_urls, uint32 browser_signal_bidding_duration_msecs) => (double score, array<string> errors); + // Hint to the worklet to send a network request for any needed trusted + // signals data now. SellerWorklets normally wait briefy for there to be a + // number of ScoreAd() calls before requesting trusted scoring signals so the + // request can be batched together. This method can be called once all bids + // have been generated to minimize the amount of time an auction spends + // waiting on trusted signals data once the final bid has been generated. Does + // nothing if no trusted scoring signals need to be fetched. + SendPendingSignalsRequests(); + // Calls the Javascript reportResult() function to get the information needed // to report the result of the auction to the seller. May only be called once // the worklet has successfully completed loading. No data is leaked between @@ -75,11 +85,9 @@ // method and ScoreAd(). // // Arguments: - // `auction_config` The configuration provided by client JavaScript in the - // renderer in order to initiate the auction. - // - // `browser_signal_top_window_origin` The top-level origin of the window - // running the auction. + // `shareable_auction_config` Subset of the blink.mojom.AuctionAdConfig that + // excludes values that must be the same for all auctions using this + // worklet. // // `browser_signal_interest_group_owner` The owner of the interest group // that offered the winning bid. @@ -102,8 +110,7 @@ // sensitive for the renderers to see. `errors` should not be assumed to be // empty if the other values are populated, nor should it be assumed to be // non-empty if the other values are null. - ReportResult(blink.mojom.AuctionAdConfig auction_config, - url.mojom.Origin browser_signal_top_window_origin, + ReportResult(blink.mojom.ShareableAuctionAdConfig shareable_auction_config, url.mojom.Origin browser_signal_interest_group_owner, url.mojom.Url browser_signal_render_url, double browser_signal_bid,
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index 390b080b0..0f1a31a 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc
@@ -55,27 +55,29 @@ // 'https://www.another-buyer.com': {...}, // ...} // } -bool AppendAuctionConfig(AuctionV8Helper* const v8_helper, - v8::Local<v8::Context> context, - const blink::mojom::AuctionAdConfig& auction_config, - std::vector<v8::Local<v8::Value>>* args) { +bool AppendAuctionConfig( + AuctionV8Helper* const v8_helper, + v8::Local<v8::Context> context, + const GURL& decision_logic_url, + const blink::mojom::ShareableAuctionAdConfig& shareable_auction_config, + std::vector<v8::Local<v8::Value>>* args) { v8::Isolate* isolate = v8_helper->isolate(); v8::Local<v8::Object> auction_config_value = v8::Object::New(isolate); gin::Dictionary auction_config_dict(isolate, auction_config_value); - if (!auction_config_dict.Set("seller", auction_config.seller.Serialize()) || - !auction_config_dict.Set("decisionLogicUrl", - auction_config.decision_logic_url.spec())) { + if (!auction_config_dict.Set( + "seller", url::Origin::Create(decision_logic_url).Serialize()) || + !auction_config_dict.Set("decisionLogicUrl", decision_logic_url.spec())) { return false; } - if (auction_config.interest_group_buyers) { - if (auction_config.interest_group_buyers->is_all_buyers()) { + if (shareable_auction_config.interest_group_buyers) { + if (shareable_auction_config.interest_group_buyers->is_all_buyers()) { if (!auction_config_dict.Set("interestGroupBuyers", std::string("*"))) return false; } else { std::vector<v8::Local<v8::Value>> interest_group_buyers; for (const url::Origin& buyer : - auction_config.interest_group_buyers->get_buyers()) { + shareable_auction_config.interest_group_buyers->get_buyers()) { v8::Local<v8::String> v8_buyer; if (!v8_helper->CreateUtf8String(buyer.Serialize()).ToLocal(&v8_buyer)) return false; @@ -85,23 +87,25 @@ } } - if (auction_config.auction_signals.has_value() && - !v8_helper->InsertJsonValue(context, "auctionSignals", - auction_config.auction_signals.value(), - auction_config_value)) { + if (shareable_auction_config.auction_signals.has_value() && + !v8_helper->InsertJsonValue( + context, "auctionSignals", + shareable_auction_config.auction_signals.value(), + auction_config_value)) { return false; } - if (auction_config.seller_signals.has_value() && - !v8_helper->InsertJsonValue(context, "sellerSignals", - auction_config.seller_signals.value(), - auction_config_value)) { + if (shareable_auction_config.seller_signals.has_value() && + !v8_helper->InsertJsonValue( + context, "sellerSignals", + shareable_auction_config.seller_signals.value(), + auction_config_value)) { return false; } - if (auction_config.per_buyer_signals.has_value()) { + if (shareable_auction_config.per_buyer_signals.has_value()) { v8::Local<v8::Object> per_buyer_value = v8::Object::New(isolate); - for (const auto& kv : auction_config.per_buyer_signals.value()) { + for (const auto& kv : shareable_auction_config.per_buyer_signals.value()) { if (!v8_helper->InsertJsonValue(context, kv.first.Serialize(), kv.second, per_buyer_value)) { return false; @@ -121,22 +125,34 @@ bool pause_for_debugger_on_start, mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const GURL& decision_logic_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, mojom::AuctionWorkletService::LoadSellerWorkletCallback load_worklet_callback) : v8_runner_(v8_helper->v8_runner()), - v8_helper_(v8_helper), + v8_helper_(std::move(v8_helper)), debug_id_( - base::MakeRefCounted<AuctionV8Helper::DebugId>(v8_helper.get())), + base::MakeRefCounted<AuctionV8Helper::DebugId>(v8_helper_.get())), url_loader_factory_(std::move(pending_url_loader_factory)), - script_source_url_(script_source_url), + script_source_url_(decision_logic_url), + trusted_signals_request_manager_( + trusted_scoring_signals_url + ? std::make_unique<TrustedSignalsRequestManager>( + TrustedSignalsRequestManager::Type::kScoringSignals, + url_loader_factory_.get(), + /*automatically_send_requests=*/true, + top_window_origin, + *trusted_scoring_signals_url, + v8_helper_.get()) + : nullptr), v8_state_(nullptr, base::OnTaskRunnerDeleter(v8_runner_)), load_worklet_callback_(std::move(load_worklet_callback)) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); DCHECK(load_worklet_callback_); v8_state_ = std::unique_ptr<V8State, base::OnTaskRunnerDeleter>( - new V8State(v8_helper_, debug_id_, script_source_url, + new V8State(v8_helper_, debug_id_, decision_logic_url, top_window_origin, weak_ptr_factory_.GetWeakPtr()), base::OnTaskRunnerDeleter(v8_runner_)); @@ -161,8 +177,7 @@ void SellerWorklet::ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<GURL>& browser_signal_ad_components, @@ -175,9 +190,7 @@ auto score_ad_task = score_ad_tasks_.begin(); score_ad_task->ad_metadata_json = ad_metadata_json; score_ad_task->bid = bid; - score_ad_task->auction_config = std::move(auction_config); - score_ad_task->browser_signal_top_window_origin = - browser_signal_top_window_origin; + score_ad_task->shareable_auction_config = std::move(shareable_auction_config); score_ad_task->browser_signal_interest_group_owner = browser_signal_interest_group_owner; score_ad_task->browser_signal_render_url = browser_signal_render_url; @@ -188,18 +201,13 @@ browser_signal_bidding_duration_msecs; score_ad_task->callback = std::move(callback); - if (score_ad_task->auction_config->trusted_scoring_signals_url) { - score_ad_task->trusted_scoring_signals = TrustedSignals::LoadScoringSignals( - url_loader_factory_.get(), - /*render_urls=*/ - std::set<std::string>{browser_signal_render_url.spec()}, - /*ad_component_render_urls=*/ - {score_ad_task->browser_signal_ad_components.begin(), - score_ad_task->browser_signal_ad_components.end()}, - browser_signal_top_window_origin.host(), - *score_ad_task->auction_config->trusted_scoring_signals_url, v8_helper_, - base::BindOnce(&SellerWorklet::OnTrustedScoringSignalsDownloaded, - base::Unretained(this), score_ad_task)); + if (trusted_signals_request_manager_) { + score_ad_task->trusted_scoring_signals_request = + trusted_signals_request_manager_->RequestScoringSignals( + browser_signal_render_url, + score_ad_task->browser_signal_ad_components, + base::BindOnce(&SellerWorklet::OnTrustedScoringSignalsDownloaded, + base::Unretained(this), score_ad_task)); return; } @@ -207,23 +215,28 @@ /*error_msg=*/absl::nullopt); } +void SellerWorklet::SendPendingSignalsRequests() { + if (trusted_signals_request_manager_) + trusted_signals_request_manager_->StartBatchedTrustedSignalsRequest(); +} + void SellerWorklet::ReportResult( - blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, double browser_signal_desirability, ReportResultCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); + v8_runner_->PostTask( FROM_HERE, - base::BindOnce( - &SellerWorklet::V8State::ReportResult, - base::Unretained(v8_state_.get()), std::move(auction_config), - browser_signal_top_window_origin, browser_signal_interest_group_owner, - browser_signal_render_url, browser_signal_bid, - browser_signal_desirability, std::move(callback))); + base::BindOnce(&SellerWorklet::V8State::ReportResult, + base::Unretained(v8_state_.get()), + std::move(shareable_auction_config), + browser_signal_interest_group_owner, + browser_signal_render_url, browser_signal_bid, + browser_signal_desirability, std::move(callback))); } void SellerWorklet::ConnectDevToolsAgent( @@ -241,13 +254,15 @@ SellerWorklet::V8State::V8State( scoped_refptr<AuctionV8Helper> v8_helper, scoped_refptr<AuctionV8Helper::DebugId> debug_id, - GURL script_source_url, + const GURL& decision_logic_url, + const url::Origin& top_window_origin, base::WeakPtr<SellerWorklet> parent) : v8_helper_(std::move(v8_helper)), debug_id_(debug_id), parent_(std::move(parent)), user_thread_(base::SequencedTaskRunnerHandle::Get()), - script_source_url_(std::move(script_source_url)) { + decision_logic_url_(decision_logic_url), + top_window_origin_(top_window_origin) { DETACH_FROM_SEQUENCE(v8_sequence_checker_); v8_helper_->v8_runner()->PostTask( FROM_HERE, base::BindOnce(&V8State::FinishInit, base::Unretained(this))); @@ -262,9 +277,8 @@ void SellerWorklet::V8State::ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigPtr auction_config, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, - const url::Origin& browser_signal_top_window_origin, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<std::string>& browser_signal_ad_components, @@ -288,7 +302,8 @@ args.push_back(gin::ConvertToV8(isolate, bid)); - if (!AppendAuctionConfig(v8_helper_.get(), context, *auction_config, &args)) { + if (!AppendAuctionConfig(v8_helper_.get(), context, decision_logic_url_, + *shareable_auction_config, &args)) { PostScoreAdCallbackToUserThread(std::move(callback), 0 /* score */, std::vector<std::string>() /* errors */); return; @@ -307,7 +322,7 @@ v8::Local<v8::Object> browser_signals = v8::Object::New(isolate); gin::Dictionary browser_signals_dict(isolate, browser_signals); if (!browser_signals_dict.Set("topWindowHostname", - browser_signal_top_window_origin.host()) || + top_window_origin_.host()) || !browser_signals_dict.Set( "interestGroupOwner", browser_signal_interest_group_owner.Serialize()) || @@ -346,7 +361,7 @@ if (!gin::ConvertFromV8(isolate, score_ad_result, &score) || std::isnan(score) || !std::isfinite(score)) { errors_out.push_back( - base::StrCat({script_source_url_.spec(), + base::StrCat({decision_logic_url_.spec(), " scoreAd() did not return a valid number."})); PostScoreAdCallbackToUserThread(std::move(callback), 0 /* score */, @@ -365,8 +380,7 @@ } void SellerWorklet::V8State::ReportResult( - blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, @@ -386,7 +400,8 @@ v8::Context::Scope context_scope(context); std::vector<v8::Local<v8::Value>> args; - if (!AppendAuctionConfig(v8_helper_.get(), context, *auction_config, &args)) { + if (!AppendAuctionConfig(v8_helper_.get(), context, decision_logic_url_, + *shareable_auction_config, &args)) { PostReportResultCallbackToUserThread( std::move(callback), absl::nullopt /* signals_for_winner */, absl::nullopt /* report_url */, @@ -397,7 +412,7 @@ v8::Local<v8::Object> browser_signals = v8::Object::New(isolate); gin::Dictionary browser_signals_dict(isolate, browser_signals); if (!browser_signals_dict.Set("topWindowHostname", - browser_signal_top_window_origin.host()) || + top_window_origin_.host()) || !browser_signals_dict.Set( "interestGroupOwner", browser_signal_interest_group_owner.Serialize()) || @@ -538,15 +553,15 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); task->trusted_scoring_signals_error_msg = std::move(error_msg); - // Clean up single-use object. - task->trusted_scoring_signals.reset(); + // Clean up single-use object, now that it has done its job. + task->trusted_scoring_signals_request.reset(); v8_runner_->PostTask( FROM_HERE, base::BindOnce( &SellerWorklet::V8State::ScoreAd, base::Unretained(v8_state_.get()), - task->ad_metadata_json, task->bid, std::move(task->auction_config), - std::move(result), std::move(task->browser_signal_top_window_origin), + task->ad_metadata_json, task->bid, + std::move(task->shareable_auction_config), std::move(result), std::move(task->browser_signal_interest_group_owner), std::move(task->browser_signal_render_url), std::move(task->browser_signal_ad_components),
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h index 5464783..d41a084 100644 --- a/content/services/auction_worklet/seller_worklet.h +++ b/content/services/auction_worklet/seller_worklet.h
@@ -20,6 +20,7 @@ #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h" #include "content/services/auction_worklet/public/mojom/seller_worklet.mojom.h" #include "content/services/auction_worklet/trusted_signals.h" +#include "content/services/auction_worklet/trusted_signals_request_manager.h" #include "content/services/auction_worklet/worklet_loader.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -47,7 +48,9 @@ bool pause_for_debugger_on_start, mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const GURL& decision_logic_url, + const absl::optional<GURL>& trusted_scoring_signals_url, + const url::Origin& top_window_origin, mojom::AuctionWorkletService::LoadSellerWorkletCallback load_worklet_callback); @@ -59,22 +62,23 @@ int context_group_id_for_testing() const; // mojom::SellerWorklet implementation: - void ScoreAd(const std::string& ad_metadata_json, - double bid, - blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - const std::vector<GURL>& browser_signal_ad_components, - uint32_t browser_signal_bidding_duration_msecs, - ScoreAdCallback callback) override; - void ReportResult(blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - double browser_signal_bid, - double browser_signal_desirability, - ReportResultCallback callback) override; + void ScoreAd( + const std::string& ad_metadata_json, + double bid, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + const std::vector<GURL>& browser_signal_ad_components, + uint32_t browser_signal_bidding_duration_msecs, + ScoreAdCallback callback) override; + void SendPendingSignalsRequests() override; + void ReportResult( + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + double browser_signal_bid, + double browser_signal_desirability, + ReportResultCallback callback) override; void ConnectDevToolsAgent( mojo::PendingReceiver<blink::mojom::DevToolsAgent> agent) override; @@ -90,8 +94,7 @@ // safe to access after that happens. std::string ad_metadata_json; double bid; - blink::mojom::AuctionAdConfigPtr auction_config; - url::Origin browser_signal_top_window_origin; + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config; url::Origin browser_signal_interest_group_owner; GURL browser_signal_render_url; // While these are URLs, it's more concenient to store these as strings @@ -102,7 +105,8 @@ ScoreAdCallback callback; - std::unique_ptr<TrustedSignals> trusted_scoring_signals; + std::unique_ptr<TrustedSignalsRequestManager::Request> + trusted_scoring_signals_request; // Error message from downloading trusted scoring signals, if any. Prepended // to errors passed to the ScoreAdCallback. @@ -124,29 +128,30 @@ V8State(scoped_refptr<AuctionV8Helper> v8_helper, scoped_refptr<AuctionV8Helper::DebugId> debug_id, - GURL script_source_url, + const GURL& decision_logic_url, + const url::Origin& top_window_origin, base::WeakPtr<SellerWorklet> parent); void SetWorkletScript(WorkletLoader::Result worklet_script); - void ScoreAd(const std::string& ad_metadata_json, - double bid, - blink::mojom::AuctionAdConfigPtr auction_config, - scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, - const url::Origin& browser_signal_top_window_origin, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - const std::vector<std::string>& browser_signal_ad_components, - uint32_t browser_signal_bidding_duration_msecs, - ScoreAdCallbackInternal callback); + void ScoreAd( + const std::string& ad_metadata_json, + double bid, + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, + scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + const std::vector<std::string>& browser_signal_ad_components, + uint32_t browser_signal_bidding_duration_msecs, + ScoreAdCallbackInternal callback); - void ReportResult(blink::mojom::AuctionAdConfigPtr auction_config, - const url::Origin& browser_signal_top_window_origin, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - double browser_signal_bid, - double browser_signal_desirability, - ReportResultCallback callback); + void ReportResult( + blink::mojom::ShareableAuctionAdConfigPtr shareable_auction_config, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + double browser_signal_bid, + double browser_signal_desirability, + ReportResultCallback callback); void ConnectDevToolsAgent( mojo::PendingReceiver<blink::mojom::DevToolsAgent> agent); @@ -180,7 +185,8 @@ // different context and executed, without persisting any state. v8::Global<v8::UnboundScript> worklet_script_; - const GURL script_source_url_; + const GURL decision_logic_url_; + const url::Origin top_window_origin_; SEQUENCE_CHECKER(v8_sequence_checker_); }; @@ -217,6 +223,11 @@ const GURL script_source_url_; + // This is populated only if `this` was created with a non-null + // `trusted_scoring_signals_url`. + std::unique_ptr<TrustedSignalsRequestManager> + trusted_signals_request_manager_; + bool paused_; // Pending calls to the corresponding Javascript method. Only accessed on
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index 406d4c8..99a8cbf 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -34,6 +34,10 @@ namespace auction_worklet { namespace { +// Very short time used by some tests that want to wait until just before a +// timer triggers. +constexpr base::TimeDelta kTinyTime = base::Microseconds(1); + // Common trusted scoring signals response. const char kTrustedScoringSignalsResponse[] = R"( { @@ -95,10 +99,11 @@ void SetDefaultParameters() { ad_metadata_ = "[1]"; bid_ = 1; - auction_config_ = blink::mojom::AuctionAdConfig::New(); + decision_logic_url_ = GURL("https://url.test/"); + trusted_scoring_signals_url_.reset(); + shareable_config_ = blink::mojom::ShareableAuctionAdConfig::New(); - browser_signal_top_window_origin_ = - url::Origin::Create(GURL("https://window.test/")); + top_window_origin_ = url::Origin::Create(GURL("https://window.test/")); browser_signal_interest_group_owner_ = url::Origin::Create(GURL("https://interest.group.owner.test/")); browser_signal_render_url_ = GURL("https://render.url.test/"); @@ -118,6 +123,31 @@ CreateScoreAdScript(raw_return_value), expected_score, expected_errors); } + // Behaves just like RunScoreAdWithReturnValueExpectingResult(), but + // additionally expects the auction to take exactly `expected_duration`, using + // FastForwardBy() to advance time. Can't just use RunLoop and Time::Now() + // time, because that can get confused by superfluous events and wait 30 + // seconds too long (perhaps confused by the 30 second download timer, even + // though the download should complete immediately, and the URLLoader with the + // timer on it deleted?) + void RunScoreAdWithReturnValueExpectingResultInExactTime( + const std::string& raw_return_value, + double expected_score, + base::TimeDelta expected_duration, + const std::vector<std::string>& expected_errors = {}) { + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + CreateScoreAdScript(raw_return_value)); + auto seller_worklet = CreateWorklet(); + + base::RunLoop run_loop; + RunScoreAdOnWorkletAsync(seller_worklet.get(), expected_score, + expected_errors, run_loop.QuitClosure()); + task_environment_.FastForwardBy(expected_duration - kTinyTime); + EXPECT_FALSE(run_loop.AnyQuitCalled()); + task_environment_.FastForwardBy(kTinyTime); + EXPECT_TRUE(run_loop.AnyQuitCalled()); + } + // Configures `url_loader_factory_` to return the provided script, and then // runs its generate_bid() function. Then runs the script, expecting the // provided result. @@ -127,7 +157,8 @@ const std::vector<std::string>& expected_errors = std::vector<std::string>()) { SCOPED_TRACE(javascript); - AddJavascriptResponse(&url_loader_factory_, url_, javascript); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + javascript); RunScoreAdExpectingResult(expected_score, expected_errors); } @@ -138,10 +169,9 @@ const std::vector<std::string>& expected_errors, base::OnceClosure done_closure) { seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_config_.Clone(), - browser_signal_top_window_origin_, browser_signal_interest_group_owner_, - browser_signal_render_url_, browser_signal_ad_components_, - browser_signal_bidding_duration_msecs_, + ad_metadata_, bid_, shareable_config_.Clone(), + browser_signal_interest_group_owner_, browser_signal_render_url_, + browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, base::BindOnce( [](double expected_score, std::vector<std::string> expected_errors, base::OnceClosure done_closure, double score, @@ -201,7 +231,8 @@ const std::vector<std::string>& expected_errors = std::vector<std::string>()) { SCOPED_TRACE(javascript); - AddJavascriptResponse(&url_loader_factory_, url_, javascript); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + javascript); RunReportResultExpectingResult(expected_signals_for_winner, expected_report_url, expected_errors); } @@ -216,9 +247,8 @@ const std::vector<std::string>& expected_errors, base::OnceClosure done_closure) { seller_worklet->ReportResult( - auction_config_.Clone(), browser_signal_top_window_origin_, - browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, - browser_signal_desireability_, + shareable_config_.Clone(), browser_signal_interest_group_owner_, + browser_signal_render_url_, bid_, browser_signal_desireability_, base::BindOnce( [](const absl::optional<std::string>& expected_signals_for_winner, const absl::optional<GURL>& expected_report_url, @@ -256,7 +286,6 @@ // out_seller_worklet_impl is non-null, will also the stash the actual // implementation point there. mojo::Remote<mojom::SellerWorklet> CreateWorkletImpl( - const GURL& url, bool pause_for_debugger_on_start, SellerWorklet** out_seller_worklet_impl = nullptr) { mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory; @@ -266,7 +295,7 @@ mojo::Remote<mojom::SellerWorklet> seller_worklet; auto seller_worklet_impl = std::make_unique<SellerWorklet>( v8_helper_, pause_for_debugger_on_start, std::move(url_loader_factory), - url, + decision_logic_url_, trusted_scoring_signals_url_, top_window_origin_, base::BindOnce(&SellerWorkletTest::CreateWorkletCallback, base::Unretained(this))); if (out_seller_worklet_impl) @@ -283,7 +312,7 @@ create_worklet_succeeded_ = false; mojo::Remote<mojom::SellerWorklet> seller_worklet = - CreateWorkletImpl(url_, /*pause_for_debugger_on_start=*/false); + CreateWorkletImpl(/*pause_for_debugger_on_start=*/false); load_script_run_loop_ = std::make_unique<base::RunLoop>(); load_script_run_loop_->Run(); load_script_run_loop_.reset(); @@ -302,10 +331,8 @@ } protected: - base::test::TaskEnvironment task_environment_; - - // The seller worklet URL. - const GURL url_ = GURL("https://url.test/"); + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; // Arguments passed to score_bid() and report_result(). Arguments common to // both of them use the same field. @@ -313,8 +340,10 @@ // This is a browser signal for report_result(), but a direct parameter for // score_bid(). double bid_; - blink::mojom::AuctionAdConfigPtr auction_config_; - url::Origin browser_signal_top_window_origin_; + GURL decision_logic_url_; + absl::optional<GURL> trusted_scoring_signals_url_; + blink::mojom::ShareableAuctionAdConfigPtr shareable_config_; + url::Origin top_window_origin_; url::Origin browser_signal_interest_group_owner_; GURL browser_signal_render_url_; std::vector<GURL> browser_signal_ad_components_; @@ -344,7 +373,8 @@ mojo::MakeSelfOwnedReceiver( std::make_unique<SellerWorklet>( v8_helper_, /*pause_for_debugger_on_start=*/false, - url_loader_factory_receiver.InitWithNewPipeAndPassRemote(), url_, + url_loader_factory_receiver.InitWithNewPipeAndPassRemote(), + decision_logic_url_, trusted_scoring_signals_url_, top_window_origin_, base::BindOnce(&SellerWorkletTest::CreateWorkletCallback, base::Unretained(this))), seller_worklet.BindNewPipeAndPassReceiver()); @@ -357,7 +387,8 @@ } TEST_F(SellerWorkletTest, NetworkError) { - url_loader_factory_.AddResponse(url_.spec(), CreateBasicSellAdScript(), + url_loader_factory_.AddResponse(decision_logic_url_.spec(), + CreateBasicSellAdScript(), net::HTTP_NOT_FOUND); EXPECT_FALSE(CreateWorklet()); EXPECT_EQ( @@ -367,7 +398,8 @@ } TEST_F(SellerWorkletTest, CompileError) { - AddJavascriptResponse(&url_loader_factory_, url_, "Invalid Javascript"); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + "Invalid Javascript"); EXPECT_FALSE(CreateWorklet()); ASSERT_EQ(1u, last_errors_.size()); EXPECT_THAT(last_errors_[0], StartsWith("https://url.test/:1 ")); @@ -440,13 +472,11 @@ } TEST_F(SellerWorkletTest, ScoreAdTopWindowOrigin) { - browser_signal_top_window_origin_ = - url::Origin::Create(GURL("https://foo.test/")); + top_window_origin_ = url::Origin::Create(GURL("https://foo.test/")); RunScoreAdWithReturnValueExpectingResult( R"(browserSignals.topWindowHostname == "foo.test" ? 2 : 0)", 2); - browser_signal_top_window_origin_ = - url::Origin::Create(GURL("https://[::1]:40000/")); + top_window_origin_ = url::Origin::Create(GURL("https://[::1]:40000/")); RunScoreAdWithReturnValueExpectingResult( R"(browserSignals.topWindowHostname == "[::1]" ? 3 : 0)", 3); } @@ -521,27 +551,30 @@ // (shared) construction of actual object is in ReportResultAuctionConfigParam, // as that worklet is easier to get things out of. TEST_F(SellerWorkletTest, ScoreAdAuctionConfigParam) { - // Default value, no URL + decision_logic_url_ = GURL("https://url.test/"); RunScoreAdWithReturnValueExpectingResult( - "auctionConfig.decisionLogicUrl.length", 0); + "auctionConfig.decisionLogicUrl.length", + decision_logic_url_.spec().length()); - std::string url = "https://example.com/auction.js"; - auction_config_ = blink::mojom::AuctionAdConfig::New(); - auction_config_->seller = url::Origin::Create(GURL("https://example.com")); - auction_config_->decision_logic_url = GURL(url); + decision_logic_url_ = GURL("https://url.test/longer/url"); RunScoreAdWithReturnValueExpectingResult( - "auctionConfig.decisionLogicUrl.length", url.length()); + "auctionConfig.decisionLogicUrl.length", + decision_logic_url_.spec().length()); } -// Tests that trusted scoring signals are correctly passed to scoreAd(). +// Tests that trusted scoring signals are correctly passed to scoreAd(). Each +// request is sent individually, without calling SendPendingSignalsRequests() - +// instead, the test advances the mock clock by +// TrustedSignalsRequestManager::kAutoSendDelay, triggering each request to +// automatically be sent. TEST_F(SellerWorkletTest, ScoreAdTrustedScoringSignals) { // With no trusted scoring signals URL, `trustedScoringSignals` should be // null. - auction_config_->trusted_scoring_signals_url = absl::nullopt; + trusted_scoring_signals_url_ = absl::nullopt; RunScoreAdWithReturnValueExpectingResult( "trustedScoringSignals === null ? 1 : 0", 1); - auction_config_->trusted_scoring_signals_url = + trusted_scoring_signals_url_ = GURL("https://url.test/trusted_scoring_signals"); // Trusted scoring signals URL without any component ads. const GURL kNoComponentSignalsUrl = GURL( @@ -549,13 +582,20 @@ "&renderUrls=https%3A%2F%2Frender.url.test%2F"); // Successful download case. + AddJsonResponse(&url_loader_factory_, kNoComponentSignalsUrl, kTrustedScoringSignalsResponse); - RunScoreAdWithReturnValueExpectingResult( + + // Each call should cause the clock to advance exactly `kAutoSendDelay` + // milliseconds before the request is send over the wire, waiting for other + // requests. + RunScoreAdWithReturnValueExpectingResultInExactTime( "trustedScoringSignals.renderUrl['https://render.url.test/']", - 4 /* Magic value in trustedScoringSignals */); - RunScoreAdWithReturnValueExpectingResult( - "trustedScoringSignals.adComponentRenderUrls === undefined ? 1 : 0", 1); + 4 /* Magic value in trustedScoringSignals */, + TrustedSignalsRequestManager::kAutoSendDelay); + RunScoreAdWithReturnValueExpectingResultInExactTime( + "trustedScoringSignals.adComponentRenderUrls === undefined ? 1 : 0", 1, + TrustedSignalsRequestManager::kAutoSendDelay); // A network error when fetching the scoring signals results in null // `trustedScoringSignals`. This case is just before the component ad test @@ -564,8 +604,9 @@ url_loader_factory_.AddResponse(kNoComponentSignalsUrl.spec(), /*content=*/std::string(), net::HTTP_NOT_FOUND); - RunScoreAdWithReturnValueExpectingResult( + RunScoreAdWithReturnValueExpectingResultInExactTime( "trustedScoringSignals === null ? 1 : 0", 1, + TrustedSignalsRequestManager::kAutoSendDelay, /*expected_errors=*/ {base::StringPrintf("Failed to load %s HTTP status = 404 Not Found.", kNoComponentSignalsUrl.spec().c_str())}); @@ -579,22 +620,26 @@ "&adComponentRenderUrls=https%3A%2F%2Fcomponent1.test%2F," "https%3A%2F%2Fcomponent2.test%2F"), kTrustedScoringSignalsResponse); - RunScoreAdWithReturnValueExpectingResult( + + RunScoreAdWithReturnValueExpectingResultInExactTime( "trustedScoringSignals.renderUrl['https://render.url.test/']", - 4 /* Magic value in trustedScoringSignals */); - RunScoreAdWithReturnValueExpectingResult( + 4 /* Magic value in trustedScoringSignals */, + TrustedSignalsRequestManager::kAutoSendDelay); + RunScoreAdWithReturnValueExpectingResultInExactTime( "trustedScoringSignals.adComponentRenderUrls['https://component1.test/']", - 1 /* Magic value in trustedScoringSignals */); - RunScoreAdWithReturnValueExpectingResult( + 1 /* Magic value in trustedScoringSignals */, + TrustedSignalsRequestManager::kAutoSendDelay); + RunScoreAdWithReturnValueExpectingResultInExactTime( "trustedScoringSignals.adComponentRenderUrls['https://component2.test/']", - 2 /* Magic value in trustedScoringSignals */); + 2 /* Magic value in trustedScoringSignals */, + TrustedSignalsRequestManager::kAutoSendDelay); } // Test the case of a bunch of ScoreAd() calls in parallel. TEST_F(SellerWorkletTest, ScoreAdParallel) { // Seller script that uses the last character of `renderUrl` as the score. AddJavascriptResponse( - &url_loader_factory_, url_, + &url_loader_factory_, decision_logic_url_, CreateScoreAdScript("parseInt(browserSignals.renderUrl.slice(-1))")); auto seller_worklet = CreateWorklet(); @@ -615,15 +660,75 @@ } // Test the case of a bunch of ScoreAd() calls in parallel, in the case trusted -// scoring signals is non-null. -TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignals) { +// scoring signals is non-null. In this case, call AllBidsGenerated() between +// scoring each bid, which should result in requests being sent individually. +TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsNotBatched) { + base::Time start_time = base::Time::Now(); + // Seller script that gets the core from the `trustedScoringSignals` value of // the passed in `renderUrl`. AddJavascriptResponse( - &url_loader_factory_, url_, + &url_loader_factory_, decision_logic_url_, CreateScoreAdScript( "trustedScoringSignals.renderUrl[browserSignals.renderUrl]")); - auction_config_->trusted_scoring_signals_url = + trusted_scoring_signals_url_ = + GURL("https://url.test/trusted_scoring_signals"); + auto seller_worklet = CreateWorklet(); + + // Start scoring a bunch of worklets. Don't provide JSON responses to make + // sure they all reside in the worklet's task list at once. + const size_t kNumWorklets = 10; + size_t num_completed_worklets = 0; + base::RunLoop run_loop; + for (size_t i = 0; i < kNumWorklets; ++i) { + browser_signal_render_url_ = GURL(base::StringPrintf("https://foo/%zu", i)); + RunScoreAdOnWorkletAsync(seller_worklet.get(), /*expected_score=*/2 * i, + /*expected_errors=*/std::vector<std::string>(), + base::BindLambdaForTesting([&]() { + ++num_completed_worklets; + if (num_completed_worklets == kNumWorklets) + run_loop.Quit(); + })); + seller_worklet->SendPendingSignalsRequests(); + } + + // Spin run loop so all requests reach the scoring worklet. + run_loop.RunUntilIdle(); + EXPECT_EQ(0u, num_completed_worklets); + + // Provide all JSON responses. + for (size_t i = 0; i < kNumWorklets; ++i) { + GURL trusted_scoring_signals = GURL(base::StringPrintf( + "%s?hostname=%s&renderUrls=https%%3A%%2F%%2Ffoo%%2F%zu", + trusted_scoring_signals_url_->spec().c_str(), + top_window_origin_.host().c_str(), i)); + std::string response_body = base::StringPrintf( + R"({"renderUrls": {"https://foo/%zu": %zu}})", i, 2 * i); + AddJsonResponse(&url_loader_factory_, trusted_scoring_signals, + response_body); + } + run_loop.Run(); + + // No time should have passed during this test, since the + // SendPendingSignalsRequests() calls ensure requests are send immediately, + // without waiting on a timer. Using a mock time ensures that the passage of + // wall clock time doesn't impact the current time, only delayed tasks and + // timers do. + EXPECT_EQ(base::Time::Now(), start_time); +} + +// Test the case of a bunch of ScoreAd() calls in parallel, in the case trusted +// scoring signals is non-null. In this case, don't call AllBidsGenerated() +// between scoring each bid, which should result in all requests being sent as a +// single request. +TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched) { + // Seller script that gets the core from the `trustedScoringSignals` value of + // the passed in `renderUrl`. + AddJavascriptResponse( + &url_loader_factory_, decision_logic_url_, + CreateScoreAdScript( + "trustedScoringSignals.renderUrl[browserSignals.renderUrl]")); + trusted_scoring_signals_url_ = GURL("https://url.test/trusted_scoring_signals"); auto seller_worklet = CreateWorklet(); @@ -647,17 +752,24 @@ run_loop.RunUntilIdle(); EXPECT_EQ(0u, num_completed_worklets); - // Provide all JSON responses. + // Provide a single response for the merged URL request. + std::string request_url = + base::StringPrintf("%s?hostname=%s&renderUrls=", + trusted_scoring_signals_url_->spec().c_str(), + top_window_origin_.host().c_str()); + std::string response_body; for (size_t i = 0; i < kNumWorklets; ++i) { - GURL trusted_scoring_signals = GURL(base::StringPrintf( - "%s?hostname=%s&renderUrls=https%%3A%%2F%%2Ffoo%%2F%zu", - auction_config_->trusted_scoring_signals_url->spec().c_str(), - browser_signal_top_window_origin_.host().c_str(), i)); - std::string response_body = base::StringPrintf( - R"({"renderUrls": {"https://foo/%zu": %zu}})", i, 2 * i); - AddJsonResponse(&url_loader_factory_, trusted_scoring_signals, - response_body); + if (i > 0) { + request_url += ","; + response_body += ","; + } + request_url += base::StringPrintf("https%%3A%%2F%%2Ffoo%%2F%zu", i); + response_body += base::StringPrintf(R"("https://foo/%zu": %zu)", i, 2 * i); } + response_body = + base::StringPrintf(R"({"renderUrls": {%s}})", response_body.c_str()); + AddJsonResponse(&url_loader_factory_, GURL(request_url), response_body); + run_loop.Run(); } @@ -759,15 +871,13 @@ } TEST_F(SellerWorkletTest, ReportResultTopWindowOrigin) { - browser_signal_top_window_origin_ = - url::Origin::Create(GURL("https://foo.test/")); + top_window_origin_ = url::Origin::Create(GURL("https://foo.test/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.topWindowHostname == "foo.test" ? 2 : 1)", std::string() /* extra_code */, "2", absl::nullopt /* expected_report_url */); - browser_signal_top_window_origin_ = - url::Origin::Create(GURL("https://[::1]:40000/")); + top_window_origin_ = url::Origin::Create(GURL("https://[::1]:40000/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.topWindowHostname == "[::1]" ? 3 : 1)", std::string() /* extra_code */, "3", @@ -814,27 +924,28 @@ } TEST_F(SellerWorkletTest, ReportResultAuctionConfigParam) { - // Empty AuctionAdConfig, with nothing filled in. + // Empty AuctionAdConfig, with nothing filled in, except the seller and + // decision logic URL. + decision_logic_url_ = GURL("https://example.com/auction.js"); RunReportResultCreatedScriptExpectingResult( "auctionConfig", std::string() /* extra_code */, - R"({"seller":"null","decisionLogicUrl":""})", + R"({"seller":"https://example.com",)" + R"("decisionLogicUrl":"https://example.com/auction.js"})", absl::nullopt /* expected_report_url */); // Everything filled in. - auction_config_ = blink::mojom::AuctionAdConfig::New(); - auction_config_->seller = url::Origin::Create(GURL("https://example.com")); - auction_config_->decision_logic_url = GURL("https://example.com/auction.js"); - auction_config_->interest_group_buyers = + decision_logic_url_ = GURL("https://example.com/auction.js"); + shareable_config_->interest_group_buyers = blink::mojom::InterestGroupBuyers::NewAllBuyers( blink::mojom::AllBuyers::New()); - auction_config_->auction_signals = R"({"is_auction_signals": true})"; - auction_config_->seller_signals = R"({"is_seller_signals": true})"; + shareable_config_->auction_signals = R"({"is_auction_signals": true})"; + shareable_config_->seller_signals = R"({"is_seller_signals": true})"; base::flat_map<url::Origin, std::string> per_buyer_signals; per_buyer_signals[url::Origin::Create(GURL("https://a.com"))] = R"({"signals_a": "A"})"; per_buyer_signals[url::Origin::Create(GURL("https://b.com"))] = R"({"signals_b": "B"})"; - auction_config_->per_buyer_signals = std::move(per_buyer_signals); + shareable_config_->per_buyer_signals = std::move(per_buyer_signals); const char kExpectedJson[] = R"({"seller":"https://example.com",)" @@ -853,10 +964,9 @@ std::vector<url::Origin> buyers; buyers.push_back(url::Origin::Create(GURL("https://buyer1.com"))); buyers.push_back(url::Origin::Create(GURL("https://another-buyer.com"))); - auction_config_ = blink::mojom::AuctionAdConfig::New(); - auction_config_->seller = url::Origin::Create(GURL("https://example.com")); - auction_config_->decision_logic_url = GURL("https://example.com/auction.js"); - auction_config_->interest_group_buyers = + shareable_config_ = blink::mojom::ShareableAuctionAdConfig::New(); + decision_logic_url_ = GURL("https://example.com/auction.js"); + shareable_config_->interest_group_buyers = blink::mojom::InterestGroupBuyers::NewBuyers(std::move(buyers)); const char kExpectedJson2[] = R"({"seller":"https://example.com",)" @@ -873,7 +983,7 @@ // Use arrays so that all values are references, to catch both the case where // variables are persisted, and the case where what they refer to is // persisted, but variables are overwritten between runs. - AddJavascriptResponse(&url_loader_factory_, url_, + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, R"( // Globally scoped variable. if (!globalThis.var1) @@ -900,8 +1010,7 @@ for (int j = 0; j < 2; ++j) { base::RunLoop run_loop; seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_config_.Clone(), - browser_signal_top_window_origin_, + ad_metadata_, bid_, shareable_config_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, base::BindLambdaForTesting( @@ -917,9 +1026,8 @@ for (int j = 0; j < 2; ++j) { base::RunLoop run_loop; seller_worklet->ReportResult( - auction_config_.Clone(), browser_signal_top_window_origin_, - browser_signal_interest_group_owner_, browser_signal_render_url_, - bid_, browser_signal_desireability_, + shareable_config_.Clone(), browser_signal_interest_group_owner_, + browser_signal_render_url_, bid_, browser_signal_desireability_, base::BindLambdaForTesting( [&run_loop](const absl::optional<std::string>& signals_for_winner, const absl::optional<GURL>& report_url, @@ -934,16 +1042,16 @@ } TEST_F(SellerWorkletTest, DeleteBeforeScoreAdCallback) { - AddJavascriptResponse(&url_loader_factory_, url_, CreateBasicSellAdScript()); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + CreateBasicSellAdScript()); auto seller_worklet = CreateWorklet(); ASSERT_TRUE(seller_worklet); base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_config_.Clone(), - browser_signal_top_window_origin_, browser_signal_interest_group_owner_, - browser_signal_render_url_, browser_signal_ad_components_, - browser_signal_bidding_duration_msecs_, + ad_metadata_, bid_, shareable_config_.Clone(), + browser_signal_interest_group_owner_, browser_signal_render_url_, + browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, base::BindOnce([](double score, const std::vector<std::string>& errors) { ADD_FAILURE() << "Callback should not be invoked since worklet deleted"; })); @@ -954,16 +1062,15 @@ TEST_F(SellerWorkletTest, DeleteBeforeReportResultCallback) { AddJavascriptResponse( - &url_loader_factory_, url_, + &url_loader_factory_, decision_logic_url_, CreateReportToScript("1", R"(sendReportTo("https://foo.test"))")); auto seller_worklet = CreateWorklet(); ASSERT_TRUE(seller_worklet); base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ReportResult( - auction_config_.Clone(), browser_signal_top_window_origin_, - browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, - browser_signal_desireability_, + shareable_config_.Clone(), browser_signal_interest_group_owner_, + browser_signal_render_url_, bid_, browser_signal_desireability_, base::BindOnce([](const absl::optional<std::string>& signals_for_winner, const absl::optional<GURL>& report_url, const std::vector<std::string>& errors) { @@ -976,18 +1083,20 @@ TEST_F(SellerWorkletTest, PauseOnStart) { // If pause isn't working, this will be used and not the right script. - url_loader_factory_.AddResponse(url_.spec(), "", net::HTTP_NOT_FOUND); + url_loader_factory_.AddResponse(decision_logic_url_.spec(), "", + net::HTTP_NOT_FOUND); SellerWorklet* worklet_impl = nullptr; - auto worklet = CreateWorkletImpl(url_, /*pause_for_debugger_on_start=*/true, - &worklet_impl); + auto worklet = + CreateWorkletImpl(/*pause_for_debugger_on_start=*/true, &worklet_impl); // Grab the context ID to be able to resume. int id = worklet_impl->context_group_id_for_testing(); // Give it a chance to fetch. task_environment_.RunUntilIdle(); - AddJavascriptResponse(&url_loader_factory_, url_, CreateScoreAdScript("10")); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + CreateScoreAdScript("10")); // Set up the event loop for the standard callback. load_script_run_loop_ = std::make_unique<base::RunLoop>(); @@ -1003,11 +1112,12 @@ } TEST_F(SellerWorkletTest, PauseOnStartDelete) { - AddJavascriptResponse(&url_loader_factory_, url_, CreateScoreAdScript("10")); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + CreateScoreAdScript("10")); SellerWorklet* worklet_impl = nullptr; - auto worklet = CreateWorkletImpl(url_, /*pause_for_debugger_on_start=*/true, - &worklet_impl); + auto worklet = + CreateWorkletImpl(/*pause_for_debugger_on_start=*/true, &worklet_impl); // Give it a chance to fetch. task_environment_.RunUntilIdle(); @@ -1044,21 +1154,21 @@ return (candidate_method && *candidate_method == "Debugger.scriptParsed"); }; - const char kUrl1[] = "http://example.com/first.js"; - const char kUrl2[] = "http://example.org/second.js"; + const GURL kUrl1 = GURL("http://example.com/first.js"); + const GURL kUrl2 = GURL("http://example.org/second.js"); - AddJavascriptResponse(&url_loader_factory_, GURL(kUrl1), - CreateScoreAdScript("1")); - AddJavascriptResponse(&url_loader_factory_, GURL(kUrl2), - CreateScoreAdScript("2")); + AddJavascriptResponse(&url_loader_factory_, kUrl1, CreateScoreAdScript("1")); + AddJavascriptResponse(&url_loader_factory_, kUrl2, CreateScoreAdScript("2")); SellerWorklet* worklet_impl1 = nullptr; + decision_logic_url_ = kUrl1; auto worklet1 = CreateWorkletImpl( - GURL(kUrl1), /*pause_for_debugger_on_start=*/true, &worklet_impl1); + /*pause_for_debugger_on_start=*/true, &worklet_impl1); + decision_logic_url_ = kUrl2; SellerWorklet* worklet_impl2 = nullptr; auto worklet2 = CreateWorkletImpl( - GURL(kUrl2), /*pause_for_debugger_on_start=*/true, &worklet_impl2); + /*pause_for_debugger_on_start=*/true, &worklet_impl2); int id1 = worklet_impl1->context_group_id_for_testing(); int id2 = worklet_impl2->context_group_id_for_testing(); @@ -1093,6 +1203,7 @@ create_worklet_succeeded_ = false; // Run the script to get parsing events. + decision_logic_url_ = kUrl1; RunScoreAdExpectingResultOnWorklet(worklet1.get(), 1.0); // channel1 should have had a parsed notification for kUrl1. @@ -1100,7 +1211,7 @@ channel1->WaitForMethodNotification("Debugger.scriptParsed"); const std::string* url1 = script_parsed1.value.FindStringPath("params.url"); ASSERT_TRUE(url1); - EXPECT_EQ(kUrl1, *url1); + EXPECT_EQ(kUrl1.spec(), *url1); // There shouldn't be a parsed notification on channel 2, however. std::list<TestChannel::Event> events2 = channel2->TakeAllEvents(); @@ -1116,6 +1227,7 @@ EXPECT_TRUE(create_worklet_succeeded_); // Run the script to get parsing events. + decision_logic_url_ = kUrl2; RunScoreAdExpectingResultOnWorklet(worklet2.get(), 2.0); // channel2 should have had a parsed notification for kUrl2. @@ -1138,10 +1250,11 @@ TEST_F(SellerWorkletTest, ParseErrorV8Debug) { ScopedInspectorSupport inspector_support(v8_helper_.get()); - AddJavascriptResponse(&url_loader_factory_, url_, "Invalid Javascript"); + AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, + "Invalid Javascript"); SellerWorklet* worklet_impl = nullptr; - auto worklet = CreateWorkletImpl(url_, /*pause_for_debugger_on_start=*/true, - &worklet_impl); + auto worklet = + CreateWorkletImpl(/*pause_for_debugger_on_start=*/true, &worklet_impl); int id = worklet_impl->context_group_id_for_testing(); TestChannel* channel = inspector_support.ConnectDebuggerSession(id); @@ -1165,7 +1278,7 @@ channel->WaitForMethodNotification("Debugger.scriptFailedToParse"); const std::string* error_url = parse_error.value.FindStringPath("params.url"); ASSERT_TRUE(error_url); - EXPECT_EQ(url_.spec(), *error_url); + EXPECT_EQ(decision_logic_url_.spec(), *error_url); } TEST_F(SellerWorkletTest, BasicDevToolsDebug) { @@ -1179,10 +1292,10 @@ AddJavascriptResponse(&url_loader_factory_, GURL(kUrl2), CreateScoreAdScript(kScriptResult)); - auto worklet1 = - CreateWorkletImpl(GURL(kUrl1), true /* pause_for_debugger_on_start */); - auto worklet2 = - CreateWorkletImpl(GURL(kUrl2), true /* pause_for_debugger_on_start */); + decision_logic_url_ = GURL(kUrl1); + auto worklet1 = CreateWorkletImpl(true /* pause_for_debugger_on_start */); + decision_logic_url_ = GURL(kUrl2); + auto worklet2 = CreateWorkletImpl(true /* pause_for_debugger_on_start */); mojo::Remote<blink::mojom::DevToolsAgent> agent1, agent2; worklet1->ConnectDevToolsAgent(agent1.BindNewPipeAndPassReceiver()); @@ -1245,6 +1358,7 @@ // To actually have execution happen, call the score_ad function. // For this one, we will modify the result to 100.5 + decision_logic_url_ = GURL(kUrl1); base::RunLoop run_loop; RunScoreAdOnWorkletAsync(worklet1.get(), 100.5, {}, run_loop.QuitClosure()); @@ -1293,6 +1407,7 @@ run_loop.Run(); // Now score_ad on worklet 2. + decision_logic_url_ = GURL(kUrl2); base::RunLoop run_loop2; RunScoreAdOnWorkletAsync( worklet2.get(), 0, @@ -1332,8 +1447,8 @@ CreateReportToScript("1", R"(sendReportTo("https://foo.test"))"); AddJavascriptResponse(&url_loader_factory_, GURL(kUrl), script_body); - auto worklet = - CreateWorkletImpl(GURL(kUrl), true /* pause_for_debugger_on_start */); + decision_logic_url_ = GURL(kUrl); + auto worklet = CreateWorkletImpl(true /* pause_for_debugger_on_start */); mojo::Remote<blink::mojom::DevToolsAgent> agent; worklet->ConnectDevToolsAgent(agent.BindNewPipeAndPassReceiver()); @@ -1435,8 +1550,8 @@ CreateReportToScript("1", R"(sendReportTo("https://foo.test"))"); AddJavascriptResponse(&url_loader_factory_, GURL(kUrl), script_body); - auto worklet = - CreateWorkletImpl(GURL(kUrl), /* pause_for_debugger_on_start= */ true); + decision_logic_url_ = GURL(kUrl); + auto worklet = CreateWorkletImpl(/*pause_for_debugger_on_start=*/true); mojo::Remote<blink::mojom::DevToolsAgent> agent; worklet->ConnectDevToolsAgent(agent.BindNewPipeAndPassReceiver());
diff --git a/content/services/auction_worklet/trusted_signals_request_manager.h b/content/services/auction_worklet/trusted_signals_request_manager.h index 9cf4be3c..4aa128dc 100644 --- a/content/services/auction_worklet/trusted_signals_request_manager.h +++ b/content/services/auction_worklet/trusted_signals_request_manager.h
@@ -119,6 +119,8 @@ // Starts a single TrustedSignals request for all currently queued Requests. void StartBatchedTrustedSignalsRequest(); + const GURL& trusted_signals_url() const { return trusted_signals_url_; } + private: struct BatchedTrustedSignalsRequest;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index a8f9816..8e92405 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -368,6 +368,8 @@ "test_content_browser_client.h", "test_content_client.cc", "test_content_client.h", + "test_fenced_frame_url_mapping_result_observer.cc", + "test_fenced_frame_url_mapping_result_observer.h", "test_navigation_url_loader.cc", "test_navigation_url_loader.h", "test_navigation_url_loader_delegate.cc", @@ -1060,6 +1062,7 @@ sources = [ "../app/mojo/mojo_browsertest.cc", + "../app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm", "../browser/accessibility/accessibility_action_browsertest.cc", "../browser/accessibility/accessibility_content_browsertest.cc", "../browser/accessibility/accessibility_content_browsertest.h",
diff --git a/content/test/data/accessibility/mac/attributes/ax-dom-class-list-expected.txt b/content/test/data/accessibility/mac/attributes/ax-dom-class-list-expected.txt new file mode 100644 index 0000000..7e625a3 --- /dev/null +++ b/content/test/data/accessibility/mac/attributes/ax-dom-class-list-expected.txt
@@ -0,0 +1,2 @@ +class_list.AXDOMClassList=['firstclass', 'secondclass'] +empty.AXDOMClassList=[]
diff --git a/content/test/data/accessibility/mac/attributes/ax-dom-class-list.html b/content/test/data/accessibility/mac/attributes/ax-dom-class-list.html new file mode 100644 index 0000000..810f228c --- /dev/null +++ b/content/test/data/accessibility/mac/attributes/ax-dom-class-list.html
@@ -0,0 +1,8 @@ +<!-- +@SCRIPT: + class_list.AXDOMClassList + empty.AXDOMClassList +--> +<!DOCTYPE html> +<div id="class_list" class="firstclass secondclass"> +<div id="empty"></div>
diff --git a/content/test/data/gpu/pixel_webgpu_import_video_frame.html b/content/test/data/gpu/pixel_webgpu_import_video_frame.html index f3b432a..b027a7be 100644 --- a/content/test/data/gpu/pixel_webgpu_import_video_frame.html +++ b/content/test/data/gpu/pixel_webgpu_import_video_frame.html
@@ -36,6 +36,7 @@ const renderCallback = function() { webGpuUtils.importExternalTextureTest(gpuDevice, gpuContext, frame); + frame.close(); waitForFinish(); }; @@ -44,7 +45,6 @@ function waitForFinish() { if (g_swapsBeforeAck == 0) { - frame.close(); domAutomationController.send("SUCCESS"); } else { g_swapsBeforeAck--;
diff --git a/content/test/gpu/fuchsia_util.py b/content/test/gpu/fuchsia_util.py index 6b7c3291..d313e92 100644 --- a/content/test/gpu/fuchsia_util.py +++ b/content/test/gpu/fuchsia_util.py
@@ -26,6 +26,8 @@ parser = argparse.ArgumentParser() AddCommonArgs(parser) AddTargetSpecificArgs(parser) + parser.add_argument('--browser', + choices=['web-engine-shell', 'fuchsia-chrome']) runner_script_args, test_args = parser.parse_known_args() ConfigureLogging(runner_script_args) @@ -40,12 +42,18 @@ if not runner_script_args.logs_dir: runner_script_args.logs_dir = tempfile.mkdtemp() - package_names = ['web_engine_with_webui', 'web_engine_shell'] - web_engine_dir = os.path.join(runner_script_args.out_dir, 'gen', 'fuchsia', - 'engine') - package_paths = map( - lambda package_name: os.path.join(web_engine_dir, package_name), - package_names) + if runner_script_args.browser == 'web-engine-shell': + package_names = ['web_engine_with_webui', 'web_engine_shell'] + package_dir = os.path.join(runner_script_args.out_dir, 'gen', 'fuchsia', + 'engine') + else: + package_names = ['chrome'] + package_dir = os.path.join(runner_script_args.out_dir, 'gen', 'chrome', + 'app') + + package_paths = list( + map(lambda package_name: os.path.join(package_dir, package_name), + package_names)) # Pass all other arguments to the gpu integration tests. script_cmd.extend(test_args) @@ -64,6 +72,7 @@ '--fuchsia-system-log-file', os.path.join(runner_script_args.logs_dir, 'system_log') ]) + script_cmd.extend(['--browser', runner_script_args.browser]) # Add to the script if runner_script_args.verbose: script_cmd.append('-v') @@ -71,10 +80,11 @@ # Keep the package repository live while the test runs. with target.GetPkgRepo(): # Install necessary packages on the device. - far_files = map( - lambda package_name: os.path.join(web_engine_dir, package_name, - package_name + '.far'), - package_names) + far_files = list( + map( + lambda package_name: os.path.join(package_dir, package_name, + package_name + '.far'), + package_names)) target.InstallPackage(far_files) return subprocess.call(script_cmd) finally:
diff --git a/content/test/gpu/gpu_tests/gpu_helper.py b/content/test/gpu/gpu_tests/gpu_helper.py index 7c65b99..da58cec 100644 --- a/content/test/gpu/gpu_tests/gpu_helper.py +++ b/content/test/gpu/gpu_tests/gpu_helper.py
@@ -35,6 +35,7 @@ 'android-chromium', 'android-webview-instrumentation', 'cros-chrome', + 'fuchsia-chrome', 'web-engine-shell', ]
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 428fec6a..0eef51b 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -433,7 +433,7 @@ def PaintWorkletPages(base_name): browser_args = [ '--enable-blink-features=OffMainThreadCSSPaint', - '--enable-gpu-rasterization', '--enable-oop-rasterization' + '--enable-gpu-rasterization' ] return [
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 89a4383..7a113c2 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -447,9 +447,6 @@ # WebGPU pixel tests flakily hang in the metal shader compiler on Mac. crbug.com/1268120 [ mac ] Pixel_WebGPUToDataURL [ Failure ] -# NVIDIA Quadro P400 GPU has problem to generate correct rendering results. -crbug.com/1238570 [ win nvidia-0x1cb3 ] Pixel_WebGPUImportVideoFrame [ Failure ] - # Failures on Sherlock # These two tests causes a crash on Swarming. Skipping so that we have a signal for other tests. crbug.com/1268144 [ fuchsia fuchsia-board-sherlock skia-renderer-vulkan ] Pixel_BackgroundImage [ Skip ] @@ -465,10 +462,7 @@ crbug.com/1261867 [ fuchsia fuchsia-board-sherlock skia-renderer-vulkan ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Failure ] # Pixel_WebGPUImportVideoFrame hangs on Windows FYI bots -crbug.com/1274796 [ win nvidia-0x2184 ] Pixel_WebGPUImportVideoFrame [ Failure ] -crbug.com/1274796 [ win intel-0x5912 ] Pixel_WebGPUImportVideoFrame [ Failure ] -crbug.com/1274796 [ win intel-0x3e92 ] Pixel_WebGPUImportVideoFrame [ Failure ] -crbug.com/1274796 [ win amd-0x7340 ] Pixel_WebGPUImportVideoFrame [ Failure ] +crbug.com/1274796 [ win skia-renderer-gl ] Pixel_WebGPUImportVideoFrame [ Failure ] # Pixel_Video_Media_Stream_Incompatible_Stride flakes with SkiaRenderer GL crbug.com/1213542 [ skia-renderer-gl linux nvidia-0x1cb3 ] Pixel_Video_Media_Stream_Incompatible_Stride [ RetryOnFailure ] @@ -478,6 +472,9 @@ # Flaky on Pixel 4 Android WebView crbug.com/1278893 [ android android-pixel-4 android-webview-instrumentation skia-renderer-gl ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ] +crbug.com/1285104 [ android android-pixel-4 android-webview-instrumentation skia-renderer-gl ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ] +crbug.com/1285084 [ android android-pixel-4 android-webview-instrumentation skia-renderer-gl ] Pixel_CSS3DBlueBox [ RetryOnFailure ] + ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 2a0738f..a0cee5d 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -139,6 +139,10 @@ crbug.com/1237319 [ chromeos no-passthrough ] conformance2/textures/webgl_canvas/tex-3d-* [ Skip ] crbug.com/1237319 [ chromeos no-passthrough ] deqp/functional/gles3/clipping.html [ Skip ] +# Parallel Shader compile/link is currently slower with Vulkan backend. +crbug.com/angleproject/6748 [ angle-vulkan passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ] +crbug.com/angleproject/6748 [ angle-swiftshader passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ] + ############################### # Temporary Skip Expectations # ############################### @@ -1165,15 +1169,15 @@ crbug.com/1241183 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Failure ] crbug.com/1211588 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/transformfeedback/* [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_EXT_texture_compression_bptc [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_EXT_texture_compression_rgtc [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_EXT_texture_filter_anisotropic [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_EXT_texture_norm16 [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_OES_texture_float_linear [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_OVR_multiview2 [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_WEBGL_compressed_texture_s3tc [ Failure ] -crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_EXT_texture_compression_bptc [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_EXT_texture_compression_rgtc [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_EXT_texture_filter_anisotropic [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_EXT_texture_norm16 [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_OES_texture_float_linear [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_OVR_multiview2 [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_WEBGL_compressed_texture_s3tc [ Failure ] +crbug.com/1213198 [ chromeos chromeos-board-kevin ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Failure ] crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_WEBGL_draw_instanced_base_vertex_base_instance [ Failure ] crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance [ Failure ] crbug.com/1213198 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/ext-float-blend.html [ Failure ] @@ -1194,27 +1198,27 @@ crbug.com/1215698 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/fborender/shared_depth_stencil.html [ Failure ] crbug.com/1218157 [ chromeos chromeos-board-kevin no-passthrough ] conformance/offscreencanvas/context-lost-restored.html [ Failure ] crbug.com/1218157 [ chromeos chromeos-board-kevin no-passthrough ] conformance/offscreencanvas/context-lost-restored-worker.html [ Failure ] -crbug.com/1218162 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html [ Failure ] -crbug.com/1218162 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/uniformbuffers/random.html [ Failure ] -crbug.com/1218162 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/uniformbuffers/single_basic_array.html [ Failure ] -crbug.com/1218162 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/uniformbuffers/single_basic_type.html [ Failure ] -crbug.com/1218169 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/fragmentoutput/array.float.html [ Failure ] -crbug.com/1218169 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/fragmentoutput/basic.float.html [ Failure ] -crbug.com/1218509 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/fbomultisample.8_samples.html [ Failure ] -crbug.com/1218512 [ chromeos chromeos-board-kevin no-passthrough ] deqp/functional/gles3/shadertexturefunction/texturelodoffset.html [ Failure ] -crbug.com/1218516 [ chromeos chromeos-board-kevin no-passthrough ] deqp/data/gles3/shaders/arrays.html [ Failure ] +crbug.com/1218162 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html [ Failure ] +crbug.com/1218162 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/uniformbuffers/random.html [ Failure ] +crbug.com/1218162 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/uniformbuffers/single_basic_array.html [ Failure ] +crbug.com/1218162 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/uniformbuffers/single_basic_type.html [ Failure ] +crbug.com/1218169 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/fragmentoutput/array.float.html [ Failure ] +crbug.com/1218169 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/fragmentoutput/basic.float.html [ Failure ] +crbug.com/1218509 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/fbomultisample.8_samples.html [ Failure ] +crbug.com/1218512 [ chromeos chromeos-board-kevin ] deqp/functional/gles3/shadertexturefunction/texturelodoffset.html [ Failure ] +crbug.com/1218516 [ chromeos chromeos-board-kevin ] deqp/data/gles3/shaders/arrays.html [ Failure ] crbug.com/1218607 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/reading/read-pixels-from-fbo-test.html [ Failure ] -crbug.com/1218607 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ] -crbug.com/1218612 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/glsl3/array-as-return-value.html [ Failure ] -crbug.com/1218612 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/glsl3/matrix-row-major.html [ Failure ] -crbug.com/1218612 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ] -crbug.com/1218612 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/glsl3/uninitialized-local-global-variables.html [ Failure ] -crbug.com/1218615 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/extensions/ext-color-buffer-float.html [ Failure ] -crbug.com/1219024 [ chromeos chromeos-board-kevin no-passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ] -crbug.com/1219024 [ chromeos chromeos-board-kevin no-passthrough ] conformance/misc/shader-precision-format.html [ Failure ] -crbug.com/1219024 [ chromeos chromeos-board-kevin no-passthrough ] conformance/rendering/blending.html [ Failure ] +crbug.com/1218607 [ chromeos chromeos-board-kevin ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ] +crbug.com/1218612 [ chromeos chromeos-board-kevin ] conformance2/glsl3/array-as-return-value.html [ Failure ] +crbug.com/1218612 [ chromeos chromeos-board-kevin ] conformance2/glsl3/matrix-row-major.html [ Failure ] +crbug.com/1218612 [ chromeos chromeos-board-kevin ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ] +crbug.com/1218612 [ chromeos chromeos-board-kevin ] conformance2/glsl3/uninitialized-local-global-variables.html [ Failure ] +crbug.com/1218615 [ chromeos chromeos-board-kevin ] conformance2/extensions/ext-color-buffer-float.html [ Failure ] +crbug.com/1219024 [ chromeos chromeos-board-kevin ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ] +crbug.com/1219024 [ chromeos chromeos-board-kevin ] conformance/misc/shader-precision-format.html [ Failure ] +crbug.com/1219024 [ chromeos chromeos-board-kevin ] conformance/rendering/blending.html [ Failure ] crbug.com/1219024 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/rendering/framebuffer-render-to-layer.html [ Failure ] -crbug.com/1219057 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/buffers/uniform-buffers.html [ Failure ] +crbug.com/1219057 [ chromeos chromeos-board-kevin ] conformance2/buffers/uniform-buffers.html [ Failure ] crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance/canvas/webgl-to-2d-canvas.html [ Failure ] crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ] crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance/context/context-creation-and-destruction.html [ Failure ] @@ -1242,6 +1246,27 @@ crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html [ Failure ] crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html [ Failure ] crbug.com/1212917 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/textures/video/tex-3d-rgba32f-rgba-float.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_separate_points.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/interpolation_centroid.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/interpolation_flat.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/interpolation_smooth.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/point_size.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/position.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_interleaved_lines.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_interleaved_points.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_separate_lines.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_separate_points.html [ Failure ] +crbug.com/1284804 [ chromeos chromeos-board-kevin passthrough ] deqp/functional/gles3/transformfeedback/random_separate_triangles.html [ Failure ] +crbug.com/1285109 [ chromeos chromeos-board-kevin passthrough ] conformance/canvas/render-after-resize-test.html [ Failure ] +crbug.com/1285111 [ chromeos chromeos-board-kevin passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ] +crbug.com/1285112 [ chromeos chromeos-board-kevin passthrough ] conformance2/rendering/blitframebuffer-multisampled-readbuffer.html [ Failure ] +crbug.com/1285114 [ chromeos chromeos-board-kevin passthrough ] conformance2/transform_feedback/transform_feedback.html [ Failure ] ############################## # Lacros-like Linux Failures #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 69fcb9f..79ee4c2 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -169,6 +169,8 @@ # Extensions not available on angle-vulkan crbug.com/1187260 [ angle-vulkan passthrough ] WebglExtension_WEBGL_debug_shaders [ Skip ] crbug.com/1187260 [ angle-swiftshader passthrough ] WebglExtension_WEBGL_debug_shaders [ Skip ] +crbug.com/angleproject/6748 [ angle-vulkan passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ] +crbug.com/angleproject/6748 [ angle-swiftshader passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ] # Extensions not available on angle-metal crbug.com/angleproject/4846 [ mac angle-metal passthrough ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 2cc0667..7c947d3e 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -699,6 +699,11 @@ browser_interface_broker_receiver_.reset(); } + // The initial `navigation_url_` may have been mapped to a new URL at this + // point. Overwrite it here with the desired value to correctly mock the + // DidCommitProvisionalLoadParams. + navigation_url_ = request_->GetURL(); + auto params = BuildDidCommitProvisionalLoadParams( same_document_ /* same_document */, false /* failed_navigation */, render_frame_host_->last_http_status_code()); @@ -1331,10 +1336,15 @@ if (!request) return false; - // Prerendered page activation can be deferred by CommitDeferringConditions in - // BeginNavigation(), and `request_` hasn't been set by DidStartNavigation() - // yet. In that case, we set it here. - if (request->is_potentially_prerendered_page_activation_for_testing()) { + // `request_` may not have been set by DidStartNavigation() yet, due to + // either: + // 1) Prerendered page activation can be deferred by CommitDeferringConditions + // in BeginNavigation(). + // 2) Fenced frame navigation can be deferred on pending URL mapping. + // + // In these cases, we set the `request_` here. + if (request->is_potentially_prerendered_page_activation_for_testing() || + request->is_deferred_on_fenced_frame_url_mapping_for_testing()) { DCHECK(!request_); request_ = request; }
diff --git a/content/test/test_aggregation_service_impl.cc b/content/test/test_aggregation_service_impl.cc index 48e865c..a1c9774 100644 --- a/content/test/test_aggregation_service_impl.cc +++ b/content/test/test_aggregation_service_impl.cc
@@ -61,7 +61,7 @@ return; } - std::move(callback).Run(std::move(report.value()).GetAsJson()); + std::move(callback).Run(report->GetAsJson()); } } // namespace
diff --git a/content/test/test_fenced_frame_url_mapping_result_observer.cc b/content/test/test_fenced_frame_url_mapping_result_observer.cc new file mode 100644 index 0000000..3415f25 --- /dev/null +++ b/content/test/test_fenced_frame_url_mapping_result_observer.cc
@@ -0,0 +1,24 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/test_fenced_frame_url_mapping_result_observer.h" + +namespace content { + +TestFencedFrameURLMappingResultObserver:: + TestFencedFrameURLMappingResultObserver() = default; + +TestFencedFrameURLMappingResultObserver:: + ~TestFencedFrameURLMappingResultObserver() = default; + +void TestFencedFrameURLMappingResultObserver::OnFencedFrameURLMappingComplete( + absl::optional<GURL> mapped_url, + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> + pending_ad_components_map) { + mapping_complete_observed_ = true; + mapped_url_ = std::move(mapped_url); + pending_ad_components_map_ = std::move(pending_ad_components_map); +} + +} // namespace content
diff --git a/content/test/test_fenced_frame_url_mapping_result_observer.h b/content/test/test_fenced_frame_url_mapping_result_observer.h new file mode 100644 index 0000000..e7295a5 --- /dev/null +++ b/content/test/test_fenced_frame_url_mapping_result_observer.h
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_TEST_FENCED_FRAME_URL_MAPPING_RESULT_OBSERVER_H_ +#define CONTENT_TEST_TEST_FENCED_FRAME_URL_MAPPING_RESULT_OBSERVER_H_ + +#include "content/browser/fenced_frame/fenced_frame_url_mapping.h" + +namespace content { + +// Tests can use this class to observe and check the URL mapping result. +class TestFencedFrameURLMappingResultObserver + : public FencedFrameURLMapping::MappingResultObserver { + public: + TestFencedFrameURLMappingResultObserver(); + ~TestFencedFrameURLMappingResultObserver() override; + + void OnFencedFrameURLMappingComplete( + absl::optional<GURL> mapped_url, + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> + pending_ad_components_map) override; + + bool mapping_complete_observed() const { return mapping_complete_observed_; } + + const absl::optional<GURL>& mapped_url() const { return mapped_url_; } + + const absl::optional<FencedFrameURLMapping::PendingAdComponentsMap>& + pending_ad_components_map() const { + return pending_ad_components_map_; + } + + private: + bool mapping_complete_observed_ = false; + absl::optional<GURL> mapped_url_; + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> + pending_ad_components_map_; +}; + +} // namespace content + +#endif // CONTENT_TEST_TEST_FENCED_FRAME_URL_MAPPING_RESULT_OBSERVER_H_
diff --git a/content/test/test_render_frame_host_unittest.cc b/content/test/test_render_frame_host_unittest.cc index c1283b4..5da5c45 100644 --- a/content/test/test_render_frame_host_unittest.cc +++ b/content/test/test_render_frame_host_unittest.cc
@@ -44,9 +44,8 @@ events_.push_back("DocumentAvailableInMainFrame"); } - void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) override { - events_.push_back("DocumentOnLoadCompletedInMainFrame"); + void DocumentOnLoadCompletedInPrimaryMainFrame() override { + events_.push_back("DocumentOnLoadCompletedInPrimaryMainFrame"); } void DOMContentLoaded(RenderFrameHost* render_frame_host) override { @@ -80,12 +79,12 @@ simulator->Start(); simulator->Commit(); - EXPECT_THAT(Events(), - testing::ElementsAre( - "DidStartLoading", "DidStartNavigation", - "DidFinishNavigation", "DocumentAvailableInMainFrame", - "DOMContentLoaded", "DocumentOnLoadCompletedInMainFrame", - "DidFinishLoad", "DidStopLoading")); + EXPECT_THAT(Events(), testing::ElementsAre( + "DidStartLoading", "DidStartNavigation", + "DidFinishNavigation", + "DocumentAvailableInMainFrame", "DOMContentLoaded", + "DocumentOnLoadCompletedInPrimaryMainFrame", + "DidFinishLoad", "DidStopLoading")); } TEST_F(TestRenderFrameHostTest, LoadingCallbacksOrder_SameDocument) {
diff --git a/content/test/web_contents_observer_consistency_checker.cc b/content/test/web_contents_observer_consistency_checker.cc index a68d607..223367b 100644 --- a/content/test/web_contents_observer_consistency_checker.cc +++ b/content/test/web_contents_observer_consistency_checker.cc
@@ -335,9 +335,9 @@ AssertMainFrameExists(); } -void WebContentsObserverConsistencyChecker::DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) { - CHECK(static_cast<PageImpl&>(render_frame_host->GetPage()) +void WebContentsObserverConsistencyChecker:: + DocumentOnLoadCompletedInPrimaryMainFrame() { + CHECK(static_cast<PageImpl&>(web_contents()->GetPrimaryPage()) .is_on_load_completed_in_main_document()); AssertMainFrameExists(); }
diff --git a/content/test/web_contents_observer_consistency_checker.h b/content/test/web_contents_observer_consistency_checker.h index 3bd2cab..5b48d135 100644 --- a/content/test/web_contents_observer_consistency_checker.h +++ b/content/test/web_contents_observer_consistency_checker.h
@@ -58,8 +58,7 @@ void PrimaryPageChanged(Page& page) override; void DocumentAvailableInMainFrame( RenderFrameHost* render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame( - RenderFrameHost* render_frame_host) override; + void DocumentOnLoadCompletedInPrimaryMainFrame() override; void DOMContentLoaded(RenderFrameHost* render_frame_host) override; void DidFinishLoad(RenderFrameHost* render_frame_host, const GURL& validated_url) override;
diff --git a/device/bluetooth/bluetooth_socket.h b/device/bluetooth/bluetooth_socket.h index 2eda881..bc44d97 100644 --- a/device/bluetooth/bluetooth_socket.h +++ b/device/bluetooth/bluetooth_socket.h
@@ -30,7 +30,16 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothSocket : public base::RefCountedThreadSafe<BluetoothSocket> { public: - enum ErrorReason { kSystemError, kIOPending, kDisconnected }; + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. This enum should be kept in sync + // with the BluetoothSocketErrorReason enum in + // src/tools/metrics/histograms/enums.xml. + enum ErrorReason { + kSystemError = 0, + kIOPending = 1, + kDisconnected = 2, + kMaxValue = kDisconnected, + }; using SendCompletionCallback = base::OnceCallback<void(int)>; using ReceiveCompletionCallback =
diff --git a/docs/chromium_browser_vs_google_chrome.md b/docs/chromium_browser_vs_google_chrome.md index ff20f16..1ed161f8 100644 --- a/docs/chromium_browser_vs_google_chrome.md +++ b/docs/chromium_browser_vs_google_chrome.md
@@ -19,7 +19,6 @@ * Video and Audio codecs (may vary by distribution) * **H.264**, AV1, VP8, and VP9 video codecs. * **AAC**, MP3, Opus, Theora, Vorbis, FLAC, and WAV audio codecs. -* Sandboxed PPAPI (non-free) Flash plugin included in release * Code is tested by Chrome developers * Sandbox is always on * Single deb/rpm package @@ -37,8 +36,6 @@ * Video and Audio codecs (may vary by distribution) * AV1, VP8, and VP9 video codecs. * MP3, Opus, Theora, Vorbis, FLAC, and WAV audio codecs. -* Supports NPAPI (unsandboxed) Flash plugins, including the one from Adobe in - Chrome 34 and below * Code may be modified by distributions * Sandbox depends on the distribution (navigate to about:sandbox to confirm) * Packaging depends on the distribution
diff --git a/docs/enterprise/description_guidelines.md b/docs/enterprise/description_guidelines.md index ee409ca..f21363a 100644 --- a/docs/enterprise/description_guidelines.md +++ b/docs/enterprise/description_guidelines.md
@@ -6,6 +6,7 @@ * Chrome Browser Cloud Management: `<ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph>` * Chrome Cleanup: `<ph name="CHROME_CLEANUP_NAME">Chrome Cleanup</ph>` * Chrome Sync: `<ph name="CHROME_SYNC_NAME">Chrome Sync</ph>` +* Chrome Remote Desktop: `<ph name="CHROME_REMOTE_DESKTOP_PRODUCT_NAME">Chrome Remote Desktop</ph>` * Linux: `<ph name="LINUX_OS_NAME">Linux</ph>` * Internet Explorer: `<ph name="IE_PRODUCT_NAME">Internet® Explorer®</ph>` * Google Admin console: `<ph name="GOOGLE_ADMIN_CONSOLE_PRODUCT_NAME">Google Admin console</ph>`
diff --git a/docs/mac_arm64.md b/docs/mac_arm64.md index ddaf5d6..9401292 100644 --- a/docs/mac_arm64.md +++ b/docs/mac_arm64.md
@@ -2,9 +2,14 @@ This document describes the state of Chromium on Apple Silicon Macs. -There's a [bot](https://ci.chromium.org/p/chromium/builders/ci/mac-arm64-rel) +There's a [main waterfall +bot](https://ci.chromium.org/p/chromium/builders/ci/mac-arm64-rel) that builds for Arm. It cross-builds on an Intel machine. +There's a [main waterfall +bot](https://ci.chromium.org/p/chromium/builders/ci/mac-arm64-on-arm64-rel) +that builds for Arm on an Arm bot as well. + There's also a [tester bot](https://ci.chromium.org/p/chromium/builders/ci/mac11-arm64-rel-tests) that continuously runs tests. Most tests pass. @@ -75,24 +80,20 @@ ## Building _on_ arm Macs -It's possible to build _on_ an arm Mac, without Rosetta. However, this -configuration is not yet covered by bots, so it might be broken from time to -time. If you run into issues, complain on -[https://crbug.com/1103236](https://crbug.com/1103236). +It's possible to build _on_ an arm Mac, without Rosetta. This +configuration is covered by a [main waterfall +bot](https://ci.chromium.org/p/chromium/builders/ci/mac-arm64-on-arm64-rel). -Also, some of the hermetic binaries in `depot_tools` aren't available for -Arm yet. Most notably, some parts of `vpython` are not yet working ([tracking -bug](https://crbug.com/1103275)). The main effect of this is that some -presubmits don't yet work, and **you need to use -`git cl upload --bypass-hooks`** to upload CLs. - -(The build will also use `git` from `PATH`, instead of `depot_tools`'s -hermetic versions for now.) - -Other than that, checking out and building (with goma too) should just work. +Checking out and building (with goma too) should just work. You should be able to run `fetch chromium` normally, and then build, using `gn`, `ninja` etc like normal. -gtest-based binaries should build, run, and mostly pass. Web tests probably -don't work yet due to lack of an Arm Apache binary +Building Chrome/Mac/Intel on an arm Mac currently needs a small local tweak +to work, see [tracking bug](https://crbug.com/1280968). + +All tests should build, run, and mostly pass. We're in the process of removing +Rosetta on our Mac arm tester bots. + +Web tests don't work on macOS 12+ due to lack of a hermetic Arm Apache binary +with PHP support (system Apache dropped PHP support in macOS 12).) ([tracking bug](https://crbug.com/1190885)).
diff --git a/docs/navigation-request-navigation-state.gv b/docs/navigation-request-navigation-state.gv index 2affcd00..e8ceef28 100644 --- a/docs/navigation-request-navigation-state.gv +++ b/docs/navigation-request-navigation-state.gv
@@ -4,7 +4,7 @@ // See tools/state_transitions/README.md digraph createflow { NOT_STARTED -> {WAITING_FOR_RENDERER_RESPONSE, WILL_START_NAVIGATION, WILL_START_REQUEST}; - WAITING_FOR_RENDERER_RESPONSE -> {WILL_START_NAVIGATION}; + WAITING_FOR_RENDERER_RESPONSE -> {WILL_START_NAVIGATION, WILL_START_REQUEST}; WILL_START_NAVIGATION -> {WILL_START_REQUEST, WILL_FAIL_REQUEST}; WILL_START_REQUEST -> {WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, READY_TO_COMMIT, DID_COMMIT, CANCELING, WILL_FAIL_REQUEST, DID_COMMIT_ERROR_PAGE}; WILL_REDIRECT_REQUEST -> {WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, CANCELING, WILL_FAIL_REQUEST};
diff --git a/docs/navigation-request-navigation-state.png b/docs/navigation-request-navigation-state.png index aa1ccb9..572a0ce 100644 --- a/docs/navigation-request-navigation-state.png +++ b/docs/navigation-request-navigation-state.png Binary files differ
diff --git a/docs/testing/identifying_tests_that_depend_on_order.md b/docs/testing/identifying_tests_that_depend_on_order.md index 2e61928..c0b1a6f 100644 --- a/docs/testing/identifying_tests_that_depend_on_order.md +++ b/docs/testing/identifying_tests_that_depend_on_order.md
@@ -68,7 +68,7 @@ pass when run as part of the full test suite represent some state that we're not properly resetting between test runs or some state that we're not properly setting when starting up content_shell. You might want to run with -`--time-out-ms=60000` to weed out tests that timeout due to waiting on +`--timeout-ms=60000` to weed out tests that timeout due to waiting on content_shell startup time. #### Diagnose especially flaky tests
diff --git a/docs/testing/web_tests.md b/docs/testing/web_tests.md index 38b86ba6..1a702bcb 100644 --- a/docs/testing/web_tests.md +++ b/docs/testing/web_tests.md
@@ -510,7 +510,7 @@ * Do one of the following: * Option A) Run from the `chromium/src` folder: - `third_party/blink/tools/run_web_tests.py --additional-driver-flag='--remote-debugging-port=9222' --additional-driver-flag='--debug-devtools' --time-out-ms=6000000` + `third_party/blink/tools/run_web_tests.py --additional-driver-flag='--remote-debugging-port=9222' --additional-driver-flag='--debug-devtools' --timeout-ms=6000000` * Option B) If you need to debug an http/tests/inspector test, start httpd as described above. Then, run content_shell: `out/Default/content_shell --remote-debugging-port=9222 --additional-driver-flag='--debug-devtools' --run-web-tests http://127.0.0.1:8000/path/to/test.html`
diff --git a/docs/testing/web_tests_linux.md b/docs/testing/web_tests_linux.md index 3aea3661..a4189eb 100644 --- a/docs/testing/web_tests_linux.md +++ b/docs/testing/web_tests_linux.md
@@ -72,7 +72,7 @@ `blink/web_tests`). 1. Or, run as normal but with the `--additional-drt-flag=--renderer-startup-dialog - --additional-drt-flag=--no-timeout --time-out-ms=86400000` flags. The first + --additional-drt-flag=--no-timeout --timeout-ms=86400000` flags. The first one makes content\_shell bring up a dialog before running, which then would let you attach to the process via `gdb -p PID_OF_DUMPRENDERTREE`. The others help avoid the test shell and DumpRenderTree timeouts during the debug
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn index f97a98d..0a884d1 100644 --- a/extensions/BUILD.gn +++ b/extensions/BUILD.gn
@@ -316,6 +316,7 @@ "//chrome/browser", "//chrome/common/extensions/api", "//chrome/renderer", + "//chrome/test:test_support", "//components/autofill/content/browser:risk_proto", "//components/autofill/content/renderer:test_support", "//components/captive_portal/core:test_support",
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 520b8564..6002573 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -571,6 +571,7 @@ "//extensions:extensions_browser_resources", "//extensions/browser/api/virtual_keyboard_private:virtual_keyboard_delegate", "//extensions/browser/guest_view/web_view/web_ui", + "//extensions/browser/updater:keepalive", "//extensions/buildflags", "//extensions/common", "//extensions/common:mojom",
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index ba61dd2f..2c6eb6f 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1670,6 +1670,7 @@ ACCESSIBILITY_PRIVATE_UPDATEDICTATIONBUBBLE = 1607, TERMINALPRIVATE_GETOSINFO = 1608, OS_TELEMETRY_GETMEMORYINFO = 1609, + AUTOTESTPRIVATE_COULDALLOWCROSTINI = 1610, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extensions_browser_client.cc b/extensions/browser/extensions_browser_client.cc index 34ff7ea..7123615 100644 --- a/extensions/browser/extensions_browser_client.cc +++ b/extensions/browser/extensions_browser_client.cc
@@ -4,11 +4,14 @@ #include "extensions/browser/extensions_browser_client.h" +#include <memory> + #include "base/files/file_path.h" #include "base/logging.h" #include "components/update_client/update_client.h" #include "extensions/browser/extension_api_frame_id_map.h" #include "extensions/browser/extension_error.h" +#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h" namespace extensions { @@ -45,6 +48,12 @@ return scoped_refptr<update_client::UpdateClient>(nullptr); } +std::unique_ptr<ScopedExtensionUpdaterKeepAlive> +ExtensionsBrowserClient::CreateUpdaterKeepAlive( + content::BrowserContext* context) { + return nullptr; +} + void ExtensionsBrowserClient::ReportError( content::BrowserContext* context, std::unique_ptr<ExtensionError> error) {
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h index 564a62eb..1fa1e67d 100644 --- a/extensions/browser/extensions_browser_client.h +++ b/extensions/browser/extensions_browser_client.h
@@ -75,6 +75,7 @@ class ProcessManagerDelegate; class ProcessMap; class RuntimeAPIDelegate; +class ScopedExtensionUpdaterKeepAlive; class UserScriptListener; // Interface to allow the extensions module to make browser-process-specific @@ -303,6 +304,11 @@ virtual scoped_refptr<update_client::UpdateClient> CreateUpdateClient( content::BrowserContext* context); + // Returns a new ScopedExtensionUpdaterKeepAlive, or nullptr if the embedder + // does not support keeping the context alive while the updater is running. + virtual std::unique_ptr<ScopedExtensionUpdaterKeepAlive> + CreateUpdaterKeepAlive(content::BrowserContext* context); + // Returns true if activity logging is enabled for the given |context|. virtual bool IsActivityLoggingEnabled(content::BrowserContext* context);
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc index 7a169c3..a68a5460 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -477,8 +477,7 @@ : content::WebContentsObserver(web_contents) {} ~DocumentLoadComplete() override {} - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) override { + void DocumentOnLoadCompletedInPrimaryMainFrame() override { did_load_ = true; run_loop_.Quit(); }
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index 7c2c383..4fad18c 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -430,8 +430,7 @@ return true; } -void MimeHandlerViewGuest::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void MimeHandlerViewGuest::DocumentOnLoadCompletedInPrimaryMainFrame() { DCHECK(GetEmbedderFrame()); DCHECK_NE(element_instance_id(), guest_view::kInstanceIDNone);
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index 8aa91c42..1b38877 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -188,8 +188,7 @@ bool SetFullscreenState(bool is_fullscreen); // content::WebContentsObserver implementation. - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) final; + void DocumentOnLoadCompletedInPrimaryMainFrame() final; void ReadyToCommitNavigation( content::NavigationHandle* navigation_handle) final; void DidFinishNavigation(content::NavigationHandle* navigation_handle) final;
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index a52c632..2e1b055 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -839,8 +839,7 @@ webview::kEventLoadProgress, std::move(args))); } -void WebViewGuest::DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) { +void WebViewGuest::DocumentOnLoadCompletedInPrimaryMainFrame() { auto args = std::make_unique<base::DictionaryValue>(); DispatchEventToView(std::make_unique<GuestViewEvent>( webview::kEventContentLoad, std::move(args)));
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 049a363..714008d5 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -250,8 +250,7 @@ content::NavigationHandle* navigation_handle) final; void DidFinishNavigation(content::NavigationHandle* navigation_handle) final; void LoadProgressChanged(double progress) final; - void DocumentOnLoadCompletedInMainFrame( - content::RenderFrameHost* render_frame_host) final; + void DocumentOnLoadCompletedInPrimaryMainFrame() final; void PrimaryMainFrameRenderProcessGone(base::TerminationStatus status) final; void UserAgentOverrideSet(const blink::UserAgentOverride& ua_override) final; void FrameNameChanged(content::RenderFrameHost* render_frame_host,
diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h index 62c1b32..98403f8 100644 --- a/extensions/browser/notification_types.h +++ b/extensions/browser/notification_types.h
@@ -59,12 +59,6 @@ // TODO(https://crbug.com/1174748): Remove. NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED, - // Sent when an omnibox extension has sent back omnibox suggestions. The - // source is the BrowserContext*, and the details are an - // extensions::api::omnibox::SendSuggestions::Params object. - // TODO(https://crbug.com/1174750): Remove. - NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, - // Sent when an omnibox extension has updated the default suggestion. The // source is the BrowserContext*. // TODO(https://crbug.com/1174752): Remove.
diff --git a/extensions/browser/updater/BUILD.gn b/extensions/browser/updater/BUILD.gn index 68ba9ba0..4a9a382ce 100644 --- a/extensions/browser/updater/BUILD.gn +++ b/extensions/browser/updater/BUILD.gn
@@ -38,6 +38,8 @@ ] deps = [ + ":keepalive", + "//base", "//components/crx_file", "//components/keyed_service/content", "//components/signin/public/identity_manager", @@ -50,3 +52,10 @@ "//services/data_decoder/public/cpp", ] } + +source_set("keepalive") { + sources = [ + "scoped_extension_updater_keep_alive.cc", + "scoped_extension_updater_keep_alive.h", + ] +}
diff --git a/extensions/browser/updater/scoped_extension_updater_keep_alive.cc b/extensions/browser/updater/scoped_extension_updater_keep_alive.cc new file mode 100644 index 0000000..98e9863 --- /dev/null +++ b/extensions/browser/updater/scoped_extension_updater_keep_alive.cc
@@ -0,0 +1,11 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h" + +namespace extensions { + +ScopedExtensionUpdaterKeepAlive::~ScopedExtensionUpdaterKeepAlive() = default; + +} // namespace extensions
diff --git a/extensions/browser/updater/scoped_extension_updater_keep_alive.h b/extensions/browser/updater/scoped_extension_updater_keep_alive.h new file mode 100644 index 0000000..7bad2390 --- /dev/null +++ b/extensions/browser/updater/scoped_extension_updater_keep_alive.h
@@ -0,0 +1,25 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_UPDATER_SCOPED_EXTENSION_UPDATER_KEEP_ALIVE_H_ +#define EXTENSIONS_BROWSER_UPDATER_SCOPED_EXTENSION_UPDATER_KEEP_ALIVE_H_ + +namespace extensions { + +// Embedders should subclass ScopedExtensionUpdaterKeepAlive to hold any +// this class to hold any keepalive objects they need. +class ScopedExtensionUpdaterKeepAlive { + public: + ScopedExtensionUpdaterKeepAlive() = default; + virtual ~ScopedExtensionUpdaterKeepAlive() = 0; + + ScopedExtensionUpdaterKeepAlive( + const ScopedExtensionUpdaterKeepAlive& other) = delete; + ScopedExtensionUpdaterKeepAlive& operator=( + const ScopedExtensionUpdaterKeepAlive& other) = delete; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_UPDATER_SCOPED_EXTENSION_UPDATER_KEEP_ALIVE_H_
diff --git a/extensions/browser/updater/update_service.cc b/extensions/browser/updater/update_service.cc index 2b3ebd06..a1deb970 100644 --- a/extensions/browser/updater/update_service.cc +++ b/extensions/browser/updater/update_service.cc
@@ -8,6 +8,8 @@ #include <utility> #include "base/bind.h" +#include "base/callback.h" +#include "base/callback_helpers.h" #include "base/feature_list.h" #include "base/files/file_util.h" #include "base/metrics/histogram_functions.h" @@ -26,6 +28,7 @@ #include "extensions/browser/notification_types.h" #include "extensions/browser/updater/extension_downloader.h" #include "extensions/browser/updater/extension_update_data.h" +#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h" #include "extensions/browser/updater/update_data_provider.h" #include "extensions/browser/updater/update_service_factory.h" #include "extensions/common/extension_features.h" @@ -40,8 +43,6 @@ constexpr const char* kOmahaAttributes[] = { "_malware", "_esbAllowlist", "_potentially_uws", "_policy_violation"}; -void SendUninstallPingCompleteCallback(update_client::Error error) {} - } // namespace UpdateService::InProgressUpdate::InProgressUpdate(base::OnceClosure callback, @@ -85,8 +86,14 @@ update_client::CrxComponent crx; crx.app_id = id; crx.version = version; + // A ScopedExtensionUpdaterKeepAlive is bound into the callback to keep the + // context alive throughout the operation. update_client_->SendUninstallPing( - crx, reason, base::BindOnce(&SendUninstallPingCompleteCallback)); + crx, reason, + base::BindOnce([](std::unique_ptr<ScopedExtensionUpdaterKeepAlive>, + update_client::Error) {}, + ExtensionsBrowserClient::Get()->CreateUpdaterKeepAlive( + browser_context_))); } void UpdateService::OnEvent(Events event, const std::string& extension_id) {
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 192687f..7b9ef00e 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -490,8 +490,10 @@ "channel": "dev", "contexts": ["webui_untrusted"], "matches": [ - // Allow only nassh.html page in Terminal System Web App. - "chrome-untrusted://terminal/html/nassh.html" + // Allow only terminal_ssh.html in Terminal System Web App. + // TODO(crbug.com/1283153): remove nassh.html when the migration is done. + "chrome-untrusted://terminal/html/nassh.html", + "chrome-untrusted://terminal/html/terminal_ssh.html" ] }], "runtime.connectNative": { @@ -560,8 +562,10 @@ "channel": "dev", "contexts": ["webui_untrusted"], "matches": [ - // Allow only nassh.html page in Terminal System Web App. - "chrome-untrusted://terminal/html/nassh.html" + // Allow only terminal_ssh.html in Terminal System Web App. + // TODO(1283153): remove nassh.html when the migration is done. + "chrome-untrusted://terminal/html/nassh.html", + "chrome-untrusted://terminal/html/terminal_ssh.html" ] }], "runtime.sendNativeMessage": {
diff --git a/extensions/common/api/content_scripts.idl b/extensions/common/api/content_scripts.idl index 0da5c55f..ebc4ba35 100644 --- a/extensions/common/api/content_scripts.idl +++ b/extensions/common/api/content_scripts.idl
@@ -48,9 +48,15 @@ // requirements are not met. Defaults to false, meaning that only the top // frame is matched. boolean? all_frames; - // TODO(devlin): Add documentation once the implementation is complete. See - // crbug.com/55084. - [nodoc] + // Whether the script should inject into any frames where the URL belongs to + // a scheme that would never match a specified Match Pattern, including + // about:, data:, blob:, and filesystem: schemes. In these cases, in order + // to determine if the script should inject, the origin of the URL is + // checked. If the origin is `null` (as is the case for data: URLs), then + // the "initiator" or "creator" origin is used (i.e., the origin of the + // frame that created or navigated this frame). Note that this may not + // be the parent frame, if the frame was navigated by another frame in the + // document hierarchy. boolean? match_origin_as_fallback; // Whether the script should inject into an about:blank frame where the // parent or opener frame matches one of the patterns declared in matches.
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc index 2cc2b42..6386c124 100644 --- a/extensions/common/constants.cc +++ b/extensions/common/constants.cc
@@ -117,7 +117,7 @@ namespace extension_misc { -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMECAST) +#if defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMECAST) // The extension id for the built-in component extension. const char kChromeVoxExtensionId[] = "mndnfokpggljbaajbnioimlmbfngpief"; #else
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index 6147505..731da16d 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc
@@ -56,11 +56,13 @@ namespace { -constexpr int kModernManifestVersion = 2; +constexpr int kMinimumSupportedManifestVersion = 2; constexpr int kMaximumSupportedManifestVersion = 3; constexpr int kPEMOutputColumns = 64; -static_assert(kMaximumSupportedManifestVersion >= kModernManifestVersion, +static_assert(kMaximumSupportedManifestVersion >= + kMinimumSupportedManifestVersion, "The modern manifest version must be supported."); +bool g_silence_deprecated_manifest_version_warnings = false; // KEY MARKERS constexpr char kKeyBeginHeaderMarker[] = "-----BEGIN"; @@ -85,6 +87,7 @@ // should be added. bool IsManifestSupported(int manifest_version, Manifest::Type type, + ManifestLocation location, int creation_flags, std::string* warning) { // The ultimate short-circuit: If the feature for MV3 is disabled, it's not @@ -95,9 +98,16 @@ return false; } - // Modern is always safe. - if (manifest_version >= kModernManifestVersion && + // Supported versions are always safe. + if (manifest_version >= kMinimumSupportedManifestVersion && manifest_version <= kMaximumSupportedManifestVersion) { + // Emit a warning for unpacked extensions on Manifest V2 warning that + // MV2 is deprecated. + if (type == Manifest::TYPE_EXTENSION && manifest_version == 2 && + Manifest::IsUnpackedLocation(location) && + !g_silence_deprecated_manifest_version_warnings) { + *warning = errors::kManifestV2IsDeprecatedWarning; + } return true; } @@ -178,16 +188,18 @@ std::u16string InvalidManifestVersionError(const char* manifest_version_error, bool is_platform_app) { std::string valid_version; - if (kModernManifestVersion == kMaximumSupportedManifestVersion) { - valid_version = base::NumberToString(kModernManifestVersion); - } else if (kMaximumSupportedManifestVersion - kModernManifestVersion == 1) { + if (kMinimumSupportedManifestVersion == kMaximumSupportedManifestVersion) { + valid_version = base::NumberToString(kMinimumSupportedManifestVersion); + } else if (kMaximumSupportedManifestVersion - + kMinimumSupportedManifestVersion == + 1) { valid_version = base::StrCat( - {"either ", base::NumberToString(kModernManifestVersion), " or ", - base::NumberToString(kMaximumSupportedManifestVersion)}); + {"either ", base::NumberToString(kMinimumSupportedManifestVersion), + " or ", base::NumberToString(kMaximumSupportedManifestVersion)}); } else { valid_version = base::StrCat( - {"between ", base::NumberToString(kModernManifestVersion), " and ", - base::NumberToString(kMaximumSupportedManifestVersion)}); + {"between ", base::NumberToString(kMinimumSupportedManifestVersion), + " and ", base::NumberToString(kMaximumSupportedManifestVersion)}); } return ErrorUtils::FormatErrorMessageUTF16( @@ -204,10 +216,6 @@ const int Extension::kValidWebExtentSchemes = URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; -const int Extension::kValidBookmarkAppSchemes = URLPattern::SCHEME_HTTP | - URLPattern::SCHEME_HTTPS | - URLPattern::SCHEME_EXTENSION; - // TODO(https://crbug.com/1257045): Remove urn: scheme support. const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI | URLPattern::SCHEME_HTTP | @@ -220,6 +228,12 @@ // // static +void Extension::set_silence_deprecated_manifest_version_warnings_for_testing( + bool silence) { + g_silence_deprecated_manifest_version_warnings = silence; +} + +// static scoped_refptr<Extension> Extension::Create(const base::FilePath& path, ManifestLocation location, const base::DictionaryValue& value, @@ -568,10 +582,6 @@ } void Extension::AddWebExtentPattern(const URLPattern& pattern) { - // Bookmark apps are permissionless. - if (from_bookmark()) - return; - extent_.AddPattern(pattern); } @@ -819,8 +829,8 @@ manifest_version_ = manifest_->manifest_version(); std::string warning; - if (!IsManifestSupported(manifest_version_, GetType(), creation_flags_, - &warning)) { + if (!IsManifestSupported(manifest_version_, GetType(), location(), + creation_flags_, &warning)) { std::string json; base::JSONWriter::Write(*manifest_->value(), &json); LOG(WARNING) << "Failed to load extension. Manifest JSON: " << json;
diff --git a/extensions/common/extension.h b/extensions/common/extension.h index 7cb2e57..3600b4aa 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h
@@ -177,9 +177,6 @@ // Valid schemes for web extent URLPatterns. static const int kValidWebExtentSchemes; - // Valid schemes for bookmark app installs by the user. - static const int kValidBookmarkAppSchemes; - // Valid schemes for host permission URLPatterns. static const int kValidHostPermissionSchemes; @@ -322,7 +319,11 @@ } int creation_flags() const { return creation_flags_; } bool from_webstore() const { return (creation_flags_ & FROM_WEBSTORE) != 0; } - bool from_bookmark() const { return false; } + // TODO(crbug.com/1065748): Retire this function when there are no old + // entries. + bool from_desprecated_bookmark() const { + return (creation_flags_ & FROM_BOOKMARK) != 0; + } bool may_be_untrusted() const { return (creation_flags_ & MAY_BE_UNTRUSTED) != 0; } @@ -352,6 +353,14 @@ void AddWebExtentPattern(const URLPattern& pattern); const URLPatternSet& web_extent() const { return extent_; } + // Sets whether to ignore deprecated manifest versions for testing purposes. + // PLEASE DON'T USE THIS. Instead: + // * Ideally, use the current manifest version (V3)! :) + // * Failing that, please instead allow the warning to be emitted by e.g. + // toggling ignore_manifest_warnings on ChromeTestExtensionLoader. + static void set_silence_deprecated_manifest_version_warnings_for_testing( + bool silence); + private: friend class base::RefCountedThreadSafe<Extension>;
diff --git a/extensions/common/extension_builder.cc b/extensions/common/extension_builder.cc index fecb06a1..0067b3b 100644 --- a/extensions/common/extension_builder.cc +++ b/extensions/common/extension_builder.cc
@@ -22,7 +22,7 @@ Type type; std::string name; std::vector<std::string> permissions; - absl::optional<ActionType> action; + absl::optional<ActionInfo::Type> action; absl::optional<BackgroundContext> background_context; absl::optional<std::string> version; absl::optional<int> manifest_version; @@ -62,15 +62,17 @@ } if (action) { + // TODO(devlin): Update this when action_info_test_util.[h|cc] is moved to + // //extensions. const char* action_key = nullptr; switch (*action) { - case ActionType::PAGE_ACTION: + case ActionInfo::TYPE_PAGE: action_key = manifest_keys::kPageAction; break; - case ActionType::BROWSER_ACTION: + case ActionInfo::TYPE_BROWSER: action_key = manifest_keys::kBrowserAction; break; - case ActionType::ACTION: + case ActionInfo::TYPE_ACTION: action_key = manifest_keys::kAction; break; } @@ -190,9 +192,9 @@ return *this; } -ExtensionBuilder& ExtensionBuilder::SetAction(ActionType action) { +ExtensionBuilder& ExtensionBuilder::SetAction(ActionInfo::Type type) { CHECK(manifest_data_); - manifest_data_->action = action; + manifest_data_->action = type; return *this; }
diff --git a/extensions/common/extension_builder.h b/extensions/common/extension_builder.h index 4a5c960..bbe2596 100644 --- a/extensions/common/extension_builder.h +++ b/extensions/common/extension_builder.h
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/strings/string_piece.h" +#include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/manifest.h" #include "extensions/common/mojom/manifest.mojom-shared.h" #include "extensions/common/value_builder.h" @@ -45,12 +46,6 @@ PLATFORM_APP, }; - enum class ActionType { - PAGE_ACTION, - BROWSER_ACTION, - ACTION, - }; - enum class BackgroundContext { BACKGROUND_PAGE, EVENT_PAGE, @@ -95,7 +90,7 @@ // Sets an action type for the extension to have. By default, no action will // be set (though note that we synthesize a page action for most extensions). - ExtensionBuilder& SetAction(ActionType action); + ExtensionBuilder& SetAction(ActionInfo::Type type); // Sets a background context for the extension. By default, none will be set. ExtensionBuilder& SetBackgroundContext(BackgroundContext background_context);
diff --git a/extensions/common/extension_builder_unittest.cc b/extensions/common/extension_builder_unittest.cc index 9da4524..c063891 100644 --- a/extensions/common/extension_builder_unittest.cc +++ b/extensions/common/extension_builder_unittest.cc
@@ -68,7 +68,7 @@ { scoped_refptr<const Extension> extension = ExtensionBuilder("page action") - .SetAction(ExtensionBuilder::ActionType::PAGE_ACTION) + .SetAction(ActionInfo::TYPE_PAGE) .Build(); EXPECT_TRUE(extension->manifest()->FindKey(manifest_keys::kPageAction)); EXPECT_FALSE(extension->manifest()->FindKey(manifest_keys::kBrowserAction)); @@ -77,7 +77,7 @@ { scoped_refptr<const Extension> extension = ExtensionBuilder("browser action") - .SetAction(ExtensionBuilder::ActionType::BROWSER_ACTION) + .SetAction(ActionInfo::TYPE_BROWSER) .Build(); EXPECT_FALSE(extension->manifest()->FindKey(manifest_keys::kPageAction)); EXPECT_TRUE(extension->manifest()->FindKey(manifest_keys::kBrowserAction)); @@ -85,9 +85,7 @@ } { scoped_refptr<const Extension> extension = - ExtensionBuilder("action") - .SetAction(ExtensionBuilder::ActionType::ACTION) - .Build(); + ExtensionBuilder("action").SetAction(ActionInfo::TYPE_ACTION).Build(); EXPECT_FALSE(extension->manifest()->FindKey(manifest_keys::kPageAction)); EXPECT_FALSE(extension->manifest()->FindKey(manifest_keys::kBrowserAction)); EXPECT_TRUE(extension->manifest()->FindKey(manifest_keys::kAction));
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 0cbffe63..fbb7862 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -34,7 +34,7 @@ // Enables support for the "match_origin_as_fallback" property in content // scripts. const base::Feature kContentScriptsMatchOriginAsFallback{ - "ContentScriptsMatchOriginAsFallback", base::FEATURE_DISABLED_BY_DEFAULT}; + "ContentScriptsMatchOriginAsFallback", base::FEATURE_ENABLED_BY_DEFAULT}; // Whether Manifest Version 3-based extensions are supported. const base::Feature kMv3ExtensionsSupported{"Mv3ExtensionsSupported",
diff --git a/extensions/common/extension_unittest.cc b/extensions/common/extension_unittest.cc index 2a79df8..4b037eb 100644 --- a/extensions/common/extension_unittest.cc +++ b/extensions/common/extension_unittest.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/test/scoped_command_line.h" #include "base/test/scoped_feature_list.h" +#include "extensions/common/error_utils.h" #include "extensions/common/extension_features.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/switches.h" @@ -19,16 +20,23 @@ namespace extensions { namespace { +std::string GetVersionTooHighWarning(int max_version, int supplied_version) { + return ErrorUtils::FormatErrorMessage( + manifest_errors::kManifestVersionTooHighWarning, + base::NumberToString(max_version), + base::NumberToString(supplied_version)); +} + testing::AssertionResult RunManifestVersionSuccess( std::unique_ptr<base::DictionaryValue> manifest, Manifest::Type expected_type, int expected_manifest_version, - bool expect_warning = false, - Extension::InitFromValueFlags custom_flag = Extension::NO_FLAGS) { + base::StringPiece expected_warning = "", + Extension::InitFromValueFlags custom_flag = Extension::NO_FLAGS, + ManifestLocation manifest_location = ManifestLocation::kInternal) { std::string error; - scoped_refptr<const Extension> extension = - Extension::Create(base::FilePath(), ManifestLocation::kInternal, - *manifest, custom_flag, &error); + scoped_refptr<const Extension> extension = Extension::Create( + base::FilePath(), manifest_location, *manifest, custom_flag, &error); if (!extension) { return testing::AssertionFailure() << "Extension creation failed: " << error; @@ -44,18 +52,19 @@ << "Wrong manifest version: " << extension->manifest_version(); } - bool has_manifest_version_warning = false; + std::string manifest_version_warning; for (const auto& warning : extension->install_warnings()) { if (warning.key == manifest_keys::kManifestVersion) { - has_manifest_version_warning = true; + manifest_version_warning = warning.message; break; } } - if (has_manifest_version_warning != expect_warning) + if (expected_warning != manifest_version_warning) { return testing::AssertionFailure() - << "Expected warning: " << expect_warning - << ", Found Warning: " << has_manifest_version_warning; + << "Expected warning: '" << expected_warning << "', Found Warning: '" + << manifest_version_warning << "'"; + } return testing::AssertionSuccess(); } @@ -113,7 +122,13 @@ EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(2), kType, 2)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(3), kType, 3)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(4), kType, 4, - true /* expect warning */)); + GetVersionTooHighWarning(3, 4))); + + // Loading an unpacked MV2 extension should emit a warning. + EXPECT_TRUE(RunManifestVersionSuccess( + get_manifest(2), kType, 2, + manifest_errors::kManifestV2IsDeprecatedWarning, Extension::NO_FLAGS, + ManifestLocation::kUnpacked)); // Manifest v1 is deprecated, and should not load. EXPECT_TRUE(RunManifestVersionFailure(get_manifest(1))); @@ -163,7 +178,7 @@ EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(2), kType, 2)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(3), kType, 3)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(4), kType, 4, - true /* expect warning */)); + GetVersionTooHighWarning(3, 4))); // Omitting the key defaults to v2 for platform apps. EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(absl::nullopt), kType, 2)); @@ -203,7 +218,7 @@ EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(2), kType, 2)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(3), kType, 3)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(4), kType, 4, - true /* expect warning */)); + GetVersionTooHighWarning(3, 4))); // Manifest v1 is deprecated, but should still load for hosted apps. EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(1), kType, 1)); @@ -231,7 +246,7 @@ EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(2), kType, 2)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(3), kType, 3)); EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(4), kType, 4, - true /* expect warning */)); + GetVersionTooHighWarning(3, 4))); // Manifest v1 is deprecated, but should still load for user scripts. EXPECT_TRUE(RunManifestVersionSuccess(get_manifest(1), kType, 1));
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc index baf3770d..7130547e 100644 --- a/extensions/common/file_util_unittest.cc +++ b/extensions/common/file_util_unittest.cc
@@ -36,12 +36,12 @@ namespace { -const char manifest_content[] = - "{\n" - " \"name\": \"Underscore folder test\",\n" - " \"version\": \"1.0\",\n" - " \"manifest_version\": 2\n" - "}\n"; +constexpr char kManifestContent[] = + R"({ + "name": "Underscore folder test", + "version": "1.0", + "manifest_version": 3 + })"; const char kCustomManifest[] = "custom_manifest.json"; const base::FilePath::CharType kCustomManifestFilename[] = @@ -85,9 +85,8 @@ for (const auto& dir : underscore_directories) ASSERT_TRUE(base::CreateDirectory(ext_path.AppendASCII(dir))); - ASSERT_EQ(static_cast<int>(strlen(manifest_content)), - base::WriteFile(ext_path.AppendASCII("manifest.json"), - manifest_content, strlen(manifest_content))); + ASSERT_TRUE( + base::WriteFile(ext_path.AppendASCII("manifest.json"), kManifestContent)); std::string error; scoped_refptr<Extension> extension = file_util::LoadExtension(
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc index e5c9d6bc..2fd9a74 100644 --- a/extensions/common/manifest_constants.cc +++ b/extensions/common/manifest_constants.cc
@@ -638,6 +638,9 @@ const char kManifestParseError[] = "Manifest is not valid JSON."; const char kManifestUnreadable[] = "Manifest file is missing or unreadable"; +const char kManifestV2IsDeprecatedWarning[] = + "Manifest version 2 is deprecated, and support will be removed in 2023. " + "See https://developer.chrome.com/blog/mv2-transition/ for more details."; const char kManifestVersionTooHighWarning[] = "The maximum currently-supported manifest version is *, but this is *. " "Certain features may not work as expected.";
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index 8e24873d..8c44b49 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h
@@ -434,6 +434,7 @@ extern const char kLocalesTreeMissing[]; extern const char kManifestParseError[]; extern const char kManifestUnreadable[]; +extern const char kManifestV2IsDeprecatedWarning[]; extern const char kManifestVersionTooHighWarning[]; extern const char kMatchOriginAsFallbackCantHavePaths[]; extern const char kMatchOriginAsFallbackRestrictedToMV3[];
diff --git a/extensions/docs/extension_and_app_types.md b/extensions/docs/extension_and_app_types.md index 66d56876..9d03f151 100644 --- a/extensions/docs/extension_and_app_types.md +++ b/extensions/docs/extension_and_app_types.md
@@ -115,10 +115,6 @@ flags that specify the app and profile. Activating the icon launched the "bookmarked" URL in a tab or a window. -A bookmark app's `manifest.json` identifies it as a hosted app. However, in the -C++ code, the `Extension` object will return true from its `from_bookmark()` -method. - *Bookmark apps based on Extensions are retired.* ### Web App
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc index 61e6042..7e607d6a 100644 --- a/extensions/shell/browser/shell_content_browser_client.cc +++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -311,6 +311,7 @@ void ShellContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { DCHECK(factories);
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index 7b17e2c..cf7d493 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -102,6 +102,7 @@ void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) override; bool WillCreateURLLoaderFactory( content::BrowserContext* browser_context,
diff --git a/extensions/test/extension_background_page_waiter.cc b/extensions/test/extension_background_page_waiter.cc index 49fb0a6..0b81e60 100644 --- a/extensions/test/extension_background_page_waiter.cc +++ b/extensions/test/extension_background_page_waiter.cc
@@ -4,11 +4,15 @@ #include "extensions/test/extension_background_page_waiter.h" +#include "base/run_loop.h" +#include "base/test/bind.h" #include "content/public/browser/browser_context.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_host_test_helper.h" +#include "extensions/browser/lazy_context_id.h" #include "extensions/browser/process_manager.h" +#include "extensions/browser/service_worker_task_queue.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/incognito_info.h" #include "extensions/common/mojom/view_type.mojom.h" @@ -35,13 +39,6 @@ // static bool ExtensionBackgroundPageWaiter::CanWaitFor(const Extension& extension, std::string& reason_out) { - if (BackgroundInfo::IsServiceWorkerBased(&extension)) { - reason_out = - "ExtensionBackgroundPageWaiter does not currently support " - "Service Worker-based extensions."; - return false; - } - if (extension.is_hosted_app()) { // Little known fact: hosted apps can have background pages. They are // handled separately in BackgroundContents[Service], and don't use the @@ -53,8 +50,9 @@ return false; } - if (!BackgroundInfo::HasBackgroundPage(&extension)) { - reason_out = "Extension has no background page."; + if (!BackgroundInfo::HasBackgroundPage(&extension) && + !BackgroundInfo::IsServiceWorkerBased(&extension)) { + reason_out = "Extension has no background context."; return false; } @@ -64,6 +62,35 @@ ExtensionBackgroundPageWaiter::~ExtensionBackgroundPageWaiter() = default; void ExtensionBackgroundPageWaiter::WaitForBackgroundInitialized() { + if (BackgroundInfo::IsServiceWorkerBased(extension_.get())) { + WaitForBackgroundWorkerInitialized(); + return; + } + + DCHECK(BackgroundInfo::HasBackgroundPage(extension_.get())); + WaitForBackgroundPageInitialized(); +} + +void ExtensionBackgroundPageWaiter::WaitForBackgroundWorkerInitialized() { + // TODO(https://crbug.com/1284799): Currently, we request the content layer + // start the worker each time an event comes in (even if the worker is + // already running), and don't check first if it's active / ready. As a + // result, we have no good way of *just* checking if it's ready (because + // ServiceWorkerTaskQueue resets state right after tasks run). Instead, we + // just have to queue up a task. Luckily, it's easy. + base::RunLoop run_loop; + auto quit_loop_adapter = + [&run_loop](std::unique_ptr<LazyContextTaskQueue::ContextInfo>) { + run_loop.QuitWhenIdle(); + }; + ServiceWorkerTaskQueue::Get(browser_context_) + ->AddPendingTask( + LazyContextId(browser_context_, extension_->id(), extension_->url()), + base::BindLambdaForTesting(quit_loop_adapter)); + run_loop.Run(); +} + +void ExtensionBackgroundPageWaiter::WaitForBackgroundPageInitialized() { ProcessManager* process_manager = ProcessManager::Get(browser_context_); ExtensionHost* extension_host = process_manager->GetBackgroundHostForExtension(extension_->id());
diff --git a/extensions/test/extension_background_page_waiter.h b/extensions/test/extension_background_page_waiter.h index b5a765c..7b10fde1 100644 --- a/extensions/test/extension_background_page_waiter.h +++ b/extensions/test/extension_background_page_waiter.h
@@ -23,7 +23,8 @@ // _event_ - such as host destruction. // See also // https://chromium.googlesource.com/chromium/src/+/main/docs/patterns/synchronous-runloop.md#events-vs-states -// Note: This does not (yet) accommodate ServiceWorker-based extensions. +// TODO(devlin): Rename this to ExtensionBackgroundContextWaiter? It supports +// service workers in addition to background (and event) pages. class ExtensionBackgroundPageWaiter { public: ExtensionBackgroundPageWaiter(content::BrowserContext* browser_context, @@ -49,12 +50,17 @@ void WaitForBackgroundInitialized(); // Waits for the extension background context to currently be open and active. + // Note: this does not (yet) support worker-based extensions. void WaitForBackgroundOpen(); // Waits for the extension background context to be closed. + // Note: this does not (yet) support worker-based extensions. void WaitForBackgroundClosed(); private: + void WaitForBackgroundWorkerInitialized(); + void WaitForBackgroundPageInitialized(); + const raw_ptr<content::BrowserContext> browser_context_; scoped_refptr<const Extension> extension_; };
diff --git a/fuchsia/engine/browser/event_filter.cc b/fuchsia/engine/browser/event_filter.cc index 7ad83ac..5bc09f0 100644 --- a/fuchsia/engine/browser/event_filter.cc +++ b/fuchsia/engine/browser/event_filter.cc
@@ -135,7 +135,7 @@ case ui::ET_LAST: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ui::ET_UNKNOWN: break;
diff --git a/fuchsia/engine/browser/web_engine_content_browser_client.cc b/fuchsia/engine/browser/web_engine_content_browser_client.cc index 91feb4b..9ecfaf0 100644 --- a/fuchsia/engine/browser/web_engine_content_browser_client.cc +++ b/fuchsia/engine/browser/web_engine_content_browser_client.cc
@@ -167,6 +167,7 @@ RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableContentDirectories)) {
diff --git a/fuchsia/engine/browser/web_engine_content_browser_client.h b/fuchsia/engine/browser/web_engine_content_browser_client.h index d97ebce..fe7ced7c3 100644 --- a/fuchsia/engine/browser/web_engine_content_browser_client.h +++ b/fuchsia/engine/browser/web_engine_content_browser_client.h
@@ -46,6 +46,7 @@ void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, + const absl::optional<url::Origin>& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) override; bool ShouldEnableStrictSiteIsolation() override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn index 69fd167..a7be37d 100644 --- a/fuchsia/runners/BUILD.gn +++ b/fuchsia/runners/BUILD.gn
@@ -82,7 +82,6 @@ "//components/cast/common:constants", "//components/cast/message_port", "//components/cast/named_message_port_connector:named_message_port_connector", - "//components/cast_streaming/public", "//fuchsia/base", "//fuchsia/base:modular", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.diagnostics",
diff --git a/fuchsia/runners/cast/DEPS b/fuchsia/runners/cast/DEPS index 17aae4dc..993c074 100644 --- a/fuchsia/runners/cast/DEPS +++ b/fuchsia/runners/cast/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+components/cast", - "+components/cast_streaming/public", "+content/public/test", "+fuchsia/fidl/chromium/cast/cpp/fidl.h", "+net",
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc index 1cea7825..1d6ecad2 100644 --- a/fuchsia/runners/cast/cast_component.cc +++ b/fuchsia/runners/cast/cast_component.cc
@@ -18,7 +18,6 @@ #include "base/task/current_thread.h" #include "components/cast/message_port/fuchsia/message_port_fuchsia.h" #include "components/cast/message_port/platform_message_port.h" -#include "components/cast_streaming/public/constants.h" #include "fuchsia/base/agent_manager.h" #include "fuchsia/runners/cast/cast_runner.h" #include "fuchsia/runners/cast/cast_streaming.h" @@ -173,9 +172,8 @@ fuchsia::sys::TerminationReason::INTERNAL_ERROR); } }); - api_bindings_client_->OnPortConnected( - cast_streaming::kCastTransportBindingName, - std::move(message_port_for_agent)); + api_bindings_client_->OnPortConnected(kCastStreamingMessagePortName, + std::move(message_port_for_agent)); } api_bindings_client_->AttachToFrame(
diff --git a/fuchsia/runners/cast/cast_streaming.cc b/fuchsia/runners/cast/cast_streaming.cc index 708282f..a6e6630 100644 --- a/fuchsia/runners/cast/cast_streaming.cc +++ b/fuchsia/runners/cast/cast_streaming.cc
@@ -42,6 +42,8 @@ const char kCastStreamingWebUrl[] = "fuchsia-dir://cast-streaming/receiver.html"; +const char kCastStreamingMessagePortName[] = "cast.__platform__.cast_transport"; + bool IsAppConfigForCastStreaming( const chromium::cast::ApplicationConfig& application_config) { return application_config.web_url() == kCastStreamingAppUrl;
diff --git a/fuchsia/runners/cast/cast_streaming.h b/fuchsia/runners/cast/cast_streaming.h index 3055ccd..d55dbc9f 100644 --- a/fuchsia/runners/cast/cast_streaming.h +++ b/fuchsia/runners/cast/cast_streaming.h
@@ -17,6 +17,9 @@ // URL for the Cast Streaming application. extern const char kCastStreamingWebUrl[]; +// Name of the Cast Streaming MessagePort. +extern const char kCastStreamingMessagePortName[]; + // Returns true if |application_config| is a cast streaming application. bool IsAppConfigForCastStreaming( const chromium::cast::ApplicationConfig& application_config);
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 6305d03..0cd4077 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc
@@ -106,8 +106,10 @@ IsolateHolder::~IsolateHolder() { isolate_memory_dump_provider_.reset(); - isolate_data_.reset(); + // Calling Isolate::Dispose makes sure all threads which might access + // PerIsolateData are finished. isolate_->Dispose(); + isolate_data_.reset(); isolate_ = nullptr; }
diff --git a/gin/per_isolate_data.cc b/gin/per_isolate_data.cc index 888b984..2ccec60 100644 --- a/gin/per_isolate_data.cc +++ b/gin/per_isolate_data.cc
@@ -42,9 +42,7 @@ } } -PerIsolateData::~PerIsolateData() { - isolate_->SetData(kEmbedderNativeGin, NULL); -} +PerIsolateData::~PerIsolateData() = default; PerIsolateData* PerIsolateData::From(Isolate* isolate) { return static_cast<PerIsolateData*>(isolate->GetData(kEmbedderNativeGin));
diff --git a/google_apis/gaia/oauth_request_signer.cc b/google_apis/gaia/oauth_request_signer.cc index d3f28cdb..9abf3b7 100644 --- a/google_apis/gaia/oauth_request_signer.cc +++ b/google_apis/gaia/oauth_request_signer.cc
@@ -411,7 +411,7 @@ switch (http_method) { case GET_METHOD: signed_text = request_base_url.spec() + '?'; - FALLTHROUGH; + [[fallthrough]]; case POST_METHOD: signed_text += BuildBaseStringParameters(parameters); break;
diff --git a/gpu/command_buffer/client/gl_helper.cc b/gpu/command_buffer/client/gl_helper.cc index 31a4a33..0f14a4e 100644 --- a/gpu/command_buffer/client/gl_helper.cc +++ b/gpu/command_buffer/client/gl_helper.cc
@@ -474,7 +474,7 @@ } bool GLHelper::CopyTextureToImpl::IsBGRAReadbackSupported() { - if (bgra_support_ == BGRA_PREFERENCE_UNKNOWN) { + if (bgra_support_ == BGRA_SUPPORT_UNKNOWN) { bgra_support_ = BGRA_NOT_SUPPORTED; if (auto* extensions = gl_->GetString(GL_EXTENSIONS)) { const std::string extensions_string =
diff --git a/gpu/command_buffer/client/shared_image_interface.cc b/gpu/command_buffer/client/shared_image_interface.cc index 86b4752..42bafa6 100644 --- a/gpu/command_buffer/client/shared_image_interface.cc +++ b/gpu/command_buffer/client/shared_image_interface.cc
@@ -4,6 +4,8 @@ #include "gpu/command_buffer/client/shared_image_interface.h" +#include "base/notreached.h" + namespace gpu { uint32_t SharedImageInterface::UsageForMailbox(const Mailbox& mailbox) {
diff --git a/gpu/command_buffer/service/gr_shader_cache.h b/gpu/command_buffer/service/gr_shader_cache.h index 6639e71..b0f7379 100644 --- a/gpu/command_buffer/service/gr_shader_cache.h +++ b/gpu/command_buffer/service/gr_shader_cache.h
@@ -11,6 +11,7 @@ #include "base/hash/hash.h" #include "base/memory/memory_pressure_listener.h" #include "base/synchronization/lock.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread_checker.h" #include "base/trace_event/memory_dump_provider.h" #include "gpu/raster_export.h"
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index 5183c00e..90c7545a 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -132,11 +132,6 @@ #endif }; -// Enable out of process rasterization by default. This can still be overridden -// by --disable-oop-rasterization. -const base::Feature kDefaultEnableOopRasterization{ - "DefaultEnableOopRasterization", base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables the use of out of process rasterization for canvas. const base::Feature kCanvasOopRasterization{"CanvasOopRasterization", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -145,6 +140,11 @@ const base::Feature kDefaultEnableANGLEValidation{ "DefaultEnableANGLEValidation", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables canvas to free its resources by default when it's running in +// the background. +const base::Feature kCanvasContextLostInBackground{ + "CanvasContextLostInBackground", base::FEATURE_DISABLED_BY_DEFAULT}; + #if defined(OS_WIN) // Use a high priority for GPU process on Windows. const base::Feature kGpuProcessHighPriorityWin{
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h index e9a070c..5cf906f9 100644 --- a/gpu/config/gpu_finch_features.h +++ b/gpu/config/gpu_finch_features.h
@@ -29,12 +29,12 @@ GPU_EXPORT extern const base::Feature kDefaultEnableGpuRasterization; -GPU_EXPORT extern const base::Feature kDefaultEnableOopRasterization; - GPU_EXPORT extern const base::Feature kCanvasOopRasterization; GPU_EXPORT extern const base::Feature kDefaultEnableANGLEValidation; +GPU_EXPORT extern const base::Feature kCanvasContextLostInBackground; + #if defined(OS_WIN) GPU_EXPORT extern const base::Feature kGpuProcessHighPriorityWin; #endif
diff --git a/gpu/config/gpu_info_collector_mac.mm b/gpu/config/gpu_info_collector_mac.mm index 37dada86..fc58409f 100644 --- a/gpu/config/gpu_info_collector_mac.mm +++ b/gpu/config/gpu_info_collector_mac.mm
@@ -4,46 +4,12 @@ #include "gpu/config/gpu_info_collector.h" -#include "base/mac/scoped_nsobject.h" -#include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "third_party/angle/src/gpu_info_util/SystemInfo.h" -#import <Metal/Metal.h> - namespace gpu { -namespace { - -// The enums is used for an UMA histogram so we should never reorder entries or -// remove unused values. -enum class MetalReadWriteTextureSupportTier { - kUnknown = 0, - kTier0_NoSupport = 1, - kTier1_R32Formats = 2, - kTier2_AdditionalFormats = 3, - kMaxValue = kTier2_AdditionalFormats, -}; - -void RecordReadWriteMetalTexturesSupportedHistogram() { - // Metal tiers go 0, 1, 2, but we reserve 0 for when macOS is less then 10.13 - // and we can't query. - NSUInteger best_tier = 0; - - if (@available(macOS 10.13, *)) { - base::scoped_nsobject<NSArray<id<MTLDevice>>> devices(MTLCopyAllDevices()); - for (id<MTLDevice> device in devices.get()) { - best_tier = std::max(best_tier, [device readWriteTextureSupport] + 1); - } - } - - UMA_HISTOGRAM_ENUMERATION( - "Gpu.Metal.ReadWriteTextureSupport", - static_cast<MetalReadWriteTextureSupportTier>(best_tier)); -} -} - bool CollectContextGraphicsInfo(GPUInfo* gpu_info) { DCHECK(gpu_info); @@ -52,8 +18,6 @@ gpu_info->macos_specific_texture_target = gpu::GetPlatformSpecificTextureTarget(); - RecordReadWriteMetalTexturesSupportedHistogram(); - return CollectGraphicsInfoGL(gpu_info); }
diff --git a/gpu/config/gpu_preferences.h b/gpu/config/gpu_preferences.h index 3eebe7e..25ab0d27 100644 --- a/gpu/config/gpu_preferences.h +++ b/gpu/config/gpu_preferences.h
@@ -197,9 +197,7 @@ // Ignores GPU blocklist. bool ignore_gpu_blocklist = false; - // Oop rasterization preferences in the GPU process. disable wins over - // enable, and neither means use defaults from GpuFeatureInfo. - bool enable_oop_rasterization = false; + // Oop rasterization preferences in the GPU process. bool disable_oop_rasterization = false; bool enable_oop_rasterization_ddl = false;
diff --git a/gpu/config/gpu_preferences_unittest.cc b/gpu/config/gpu_preferences_unittest.cc index f2db765..e9c8d10d 100644 --- a/gpu/config/gpu_preferences_unittest.cc +++ b/gpu/config/gpu_preferences_unittest.cc
@@ -68,7 +68,6 @@ EXPECT_EQ(left.texture_target_exception_list, right.texture_target_exception_list); EXPECT_EQ(left.ignore_gpu_blocklist, right.ignore_gpu_blocklist); - EXPECT_EQ(left.enable_oop_rasterization, right.enable_oop_rasterization); EXPECT_EQ(left.disable_oop_rasterization, right.disable_oop_rasterization); EXPECT_EQ(left.watchdog_starts_backgrounded, right.watchdog_starts_backgrounded); @@ -168,7 +167,6 @@ GPU_PREFERENCES_FIELD(disable_biplanar_gpu_memory_buffers_for_video_frames, true) GPU_PREFERENCES_FIELD(ignore_gpu_blocklist, true) - GPU_PREFERENCES_FIELD(enable_oop_rasterization, true) GPU_PREFERENCES_FIELD(disable_oop_rasterization, true) GPU_PREFERENCES_FIELD(watchdog_starts_backgrounded, true) GPU_PREFERENCES_FIELD_ENUM(gr_context_type, GrContextType::kVulkan, @@ -267,7 +265,6 @@ PRINT_INT(texture_target_exception_list[i].format); } PRINT_BOOL(ignore_gpu_blocklist); - PRINT_BOOL(enable_oop_rasterization); PRINT_BOOL(disable_oop_rasterization); PRINT_BOOL(watchdog_starts_backgrounded); PRINT_INT(gr_context_type);
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc index 5cb1246..bbab0ee 100644 --- a/gpu/config/gpu_util.cc +++ b/gpu/config/gpu_util.cc
@@ -210,22 +210,6 @@ if (gpu_preferences.disable_oop_rasterization) return kGpuFeatureStatusDisabled; - else if (gpu_preferences.enable_oop_rasterization) - return kGpuFeatureStatusEnabled; - - // Enable OOP rasterization for vulkan, unless it is overridden by - // commandline. - if (features::IsUsingVulkan() && - !base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine( - features::kDefaultEnableOopRasterization.name, - base::FeatureList::OVERRIDE_DISABLE_FEATURE)) { - return kGpuFeatureStatusEnabled; - } - - // OOP Rasterization on platforms that are not fully enabled is controlled by - // a finch experiment. - if (!base::FeatureList::IsEnabled(features::kDefaultEnableOopRasterization)) - return kGpuFeatureStatusDisabled; return kGpuFeatureStatusEnabled; }
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json index 6a94def..a4a3bba3 100644 --- a/gpu/config/software_rendering_list.json +++ b/gpu/config/software_rendering_list.json
@@ -1667,6 +1667,18 @@ "features": [ "accelerated_video_encode" ] + }, + { + "id": 174, + "description": "Disable canvas acceleration on a specific Haswell GPU on ChromeOS", + "os": { + "type": "chromeos" + }, + "vendor_id": "0x8086", + "device_id": ["0x0a16"], + "features": [ + "accelerated_2d_canvas" + ] } ] }
diff --git a/gpu/ipc/common/gpu_preferences.mojom b/gpu/ipc/common/gpu_preferences.mojom index f95dcac..179f1cc 100644 --- a/gpu/ipc/common/gpu_preferences.mojom +++ b/gpu/ipc/common/gpu_preferences.mojom
@@ -77,7 +77,6 @@ array<gfx.mojom.BufferUsageAndFormat> texture_target_exception_list; bool ignore_gpu_blocklist; - bool enable_oop_rasterization; bool disable_oop_rasterization; bool enable_oop_rasterization_ddl; bool watchdog_starts_backgrounded;
diff --git a/gpu/ipc/common/gpu_preferences_mojom_traits.h b/gpu/ipc/common/gpu_preferences_mojom_traits.h index 8fdb5f6..ded43df 100644 --- a/gpu/ipc/common/gpu_preferences_mojom_traits.h +++ b/gpu/ipc/common/gpu_preferences_mojom_traits.h
@@ -188,7 +188,6 @@ } out->ignore_gpu_blocklist = prefs.ignore_gpu_blocklist(); - out->enable_oop_rasterization = prefs.enable_oop_rasterization(); out->disable_oop_rasterization = prefs.disable_oop_rasterization(); out->enable_oop_rasterization_ddl = prefs.enable_oop_rasterization_ddl(); out->watchdog_starts_backgrounded = prefs.watchdog_starts_backgrounded(); @@ -351,9 +350,6 @@ static bool ignore_gpu_blocklist(const gpu::GpuPreferences& prefs) { return prefs.ignore_gpu_blocklist; } - static bool enable_oop_rasterization(const gpu::GpuPreferences& prefs) { - return prefs.enable_oop_rasterization; - } static bool disable_oop_rasterization(const gpu::GpuPreferences& prefs) { return prefs.disable_oop_rasterization; }
diff --git a/gpu/ipc/service/gpu_watchdog_thread.cc b/gpu/ipc/service/gpu_watchdog_thread.cc index de8422f5..77cded8 100644 --- a/gpu/ipc/service/gpu_watchdog_thread.cc +++ b/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -36,9 +36,6 @@ #endif namespace gpu { -namespace { -constexpr int64_t kDelayForAddPowerObserverInMs = 50; -} base::TimeDelta GetGpuWatchdogTimeout() { std::string timeout_str = @@ -78,15 +75,14 @@ is_test_mode_(is_test_mode), watched_gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()) { base::CurrentThread::Get()->AddTaskObserver(this); - num_of_processors_ = base::SysInfo::NumberOfProcessors(); #if defined(OS_WIN) // GetCurrentThread returns a pseudo-handle that cannot be used by one thread // to identify another. DuplicateHandle creates a "real" handle that can be // used for this purpose. - if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &watched_thread_handle_, - THREAD_QUERY_INFORMATION, FALSE, 0)) { + if (!::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentThread(), + ::GetCurrentProcess(), &watched_thread_handle_, + THREAD_QUERY_INFORMATION, FALSE, 0)) { watched_thread_handle_ = nullptr; } #endif @@ -176,14 +172,11 @@ base::Unretained(this))); Disarm(); - // Use a delayed task for AddPowerObserver. The PowerMonitor is initialized in - // ChildThreadImpl::Init right after GpuInit::InitializeAndStartSandbox which - // calls OnInitComplete() at the end if no errors. - task_runner()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&GpuWatchdogThread::AddPowerObserver, - base::Unretained(this)), - base::Milliseconds(kDelayForAddPowerObserverInMs)); + // The PowerMonitorObserver needs to be register on the watchdog thread so the + // notifications are delivered on that thread. + task_runner()->PostTask(FROM_HERE, + base::BindOnce(&GpuWatchdogThread::AddPowerObserver, + base::Unretained(this))); } // Called from the gpu thread in viz::GpuServiceImpl::~GpuServiceImpl(). @@ -296,26 +289,12 @@ void GpuWatchdogThread::AddPowerObserver() { DCHECK(watchdog_thread_task_runner_->BelongsToCurrentThread()); - // The Observer can only be added after the power monitor is initialized. - // When this function is called, PowerMonitor is probably ready. - if (base::PowerMonitor::IsInitialized()) { - bool is_system_suspended = - base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState( - this); - if (is_system_suspended) { - StopWatchdogTimeoutTask(kPowerSuspendResume); - } - - is_power_observer_added_ = true; - } else { - // Just in case PowerMonitor is not ready. - // It usually takes hundreds of milliseconds to finish the whole GPU - // initialization. Try again in 100 ms. - task_runner()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&GpuWatchdogThread::AddPowerObserver, weak_ptr_), - base::Milliseconds(100)); - } + // Adding the Observer to the power monitor is safe even if power monitor is + // not yet initialized. + bool is_system_suspended = + base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(this); + if (is_system_suspended) + StopWatchdogTimeoutTask(kPowerSuspendResume); } // Running on the watchdog thread. @@ -631,7 +610,6 @@ base::debug::Alias(&in_power_suspension_); base::debug::Alias(&in_gpu_process_teardown_); base::debug::Alias(&is_backgrounded_); - base::debug::Alias(&is_power_observer_added_); base::debug::Alias(&last_on_watchdog_timeout_timeticks_); base::TimeDelta timeticks_elapses = function_begin_timeticks - last_on_watchdog_timeout_timeticks_; @@ -649,7 +627,8 @@ crash_keys::gpu_watchdog_kill_after_power_resume.Set( WithinOneMinFromPowerResumed() ? "1" : "0"); - crash_keys::num_of_processors.Set(base::NumberToString(num_of_processors_)); + const int num_of_processors = base::SysInfo::NumberOfProcessors(); + crash_keys::num_of_processors.Set(base::NumberToString(num_of_processors)); // Check the arm_disarm_counter value one more time. auto last_arm_disarm_counter = ReadArmDisarmCounter(); @@ -704,7 +683,7 @@ if (start_of_more_thread_time) { // This is the start of allowing more thread time. Only record it once for // all following timeouts on the same detected gpu hang, so we know this - // is equivlent one crash in our crash reports. + // is equivalent one crash in our crash reports. GpuWatchdogTimeoutHistogram(GpuWatchdogTimeoutEvent::kMoreThreadTime); } else { if (count_of_more_gpu_thread_time_allowed_ > 0) { @@ -714,12 +693,10 @@ // progress. Record this case. GpuWatchdogTimeoutHistogram( GpuWatchdogTimeoutEvent::kProgressAfterMoreThreadTime); - } else { - if (count_of_more_gpu_thread_time_allowed_ >= - kMaxCountOfMoreGpuThreadTimeAllowed) { - GpuWatchdogTimeoutHistogram( - GpuWatchdogTimeoutEvent::kLessThanFullThreadTimeAfterCapped); - } + } else if (count_of_more_gpu_thread_time_allowed_ >= + kMaxCountOfMoreGpuThreadTimeAllowed) { + GpuWatchdogTimeoutHistogram( + GpuWatchdogTimeoutEvent::kLessThanFullThreadTimeAfterCapped); } // Used by GPU.WatchdogThread.WaitTime later @@ -780,17 +757,4 @@ return test_result_timeout_and_gpu_hang_.IsSet(); } -// This should be called on the test main thread only. It will wait until the -// power observer is added on the watchdog thread. -void GpuWatchdogThread::WaitForPowerObserverAddedForTesting() { - DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread()); - - base::WaitableEvent event; - task_runner()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)), - base::Milliseconds(kDelayForAddPowerObserverInMs)); - event.Wait(); -} - } // namespace gpu
diff --git a/gpu/ipc/service/gpu_watchdog_thread.h b/gpu/ipc/service/gpu_watchdog_thread.h index e8f0ca7..9d1f9df 100644 --- a/gpu/ipc/service/gpu_watchdog_thread.h +++ b/gpu/ipc/service/gpu_watchdog_thread.h
@@ -124,8 +124,6 @@ // For gpu testing only. Return status for the watchdog tests bool IsGpuHangDetectedForTesting(); - void WaitForPowerObserverAddedForTesting(); - // Implements base::Thread. void Init() override; void CleanUp() override; @@ -173,7 +171,7 @@ base::ThreadTicks GetWatchedThreadTime(); #endif - // Do not change the function name. It is used for [GPU HANG] carsh reports. + // Do not change the function name. It is used for [GPU HANG] crash reports. void DeliberatelyTerminateToRecoverFromHang(); // Records "GPU.WatchdogThread.Event". @@ -210,11 +208,11 @@ base::TimeDelta watchdog_timeout_; // The one-time watchdog timeout multiplier in the gpu initialization. - int watchdog_init_factor_; + const int watchdog_init_factor_; // The one-time watchdog timeout multiplier after the watchdog pauses and // restarts. - int watchdog_restart_factor_; + const int watchdog_restart_factor_; // The time the gpu watchdog was created. base::TimeTicks watchdog_start_timeticks_; @@ -286,10 +284,6 @@ // The GPU watchdog is paused. The timeout task is temporarily stopped. bool is_paused_ = false; - // Whether the watchdog thread has added the power monitor observer. - // Read/Write by the watchdog thread only. - bool is_power_observer_added_ = false; - // whether GpuWatchdogThreadEvent::kGpuWatchdogStart has been recorded. bool is_watchdog_start_histogram_recorded = false; @@ -297,9 +291,6 @@ // constructor. bool in_gpu_initialization_ = false; - // The number of logical processors/cores on the current machine. - int num_of_processors_ = 0; - // For the experiment and the debugging purpose size_t num_of_timeout_after_power_resume_ = 0; size_t num_of_timeout_after_foregrounded_ = 0;
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc index 15bcaff..5efd9e7d 100644 --- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc +++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -80,9 +80,6 @@ // Report GPU init complete. watchdog_thread_->OnInitComplete(); - - // Wait until the power observer is added on the watchdog thread - watchdog_thread_->WaitForPowerObserverAddedForTesting(); } void GpuWatchdogPowerTest::TearDown() {
diff --git a/gpu/perftests/texture_upload_perftest.cc b/gpu/perftests/texture_upload_perftest.cc index 00fc637..e472b1d 100644 --- a/gpu/perftests/texture_upload_perftest.cc +++ b/gpu/perftests/texture_upload_perftest.cc
@@ -151,7 +151,7 @@ case GL_LUMINANCE: // (L_t, L_t, L_t, 1) expected[1] = pixels[pixels_index]; expected[2] = pixels[pixels_index]; - FALLTHROUGH; + [[fallthrough]]; case GL_RED: // (R_t, 0, 0, 1) expected[0] = pixels[pixels_index]; expected[3] = 255;
diff --git a/gpu/vulkan/win32/vulkan_implementation_win32.cc b/gpu/vulkan/win32/vulkan_implementation_win32.cc index d6e1878e..d7ae676 100644 --- a/gpu/vulkan/win32/vulkan_implementation_win32.cc +++ b/gpu/vulkan/win32/vulkan_implementation_win32.cc
@@ -26,25 +26,27 @@ bool VulkanImplementationWin32::InitializeVulkanInstance(bool using_surface) { DCHECK(using_surface); + + if (!vulkan_instance_.is_from_angle()) { + VulkanFunctionPointers* vulkan_function_pointers = + gpu::GetVulkanFunctionPointers(); + + base::FilePath path(use_swiftshader() ? L"vk_swiftshader.dll" + : L"vulkan-1.dll"); + + base::NativeLibraryLoadError native_library_load_error; + vulkan_function_pointers->vulkan_loader_library = + base::LoadNativeLibrary(path, &native_library_load_error); + if (!vulkan_function_pointers->vulkan_loader_library) + return false; + } + std::vector<const char*> required_extensions = { VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, }; - - VulkanFunctionPointers* vulkan_function_pointers = - gpu::GetVulkanFunctionPointers(); - - base::FilePath path(use_swiftshader() ? L"vk_swiftshader.dll" - : L"vulkan-1.dll"); - - base::NativeLibraryLoadError native_library_load_error; - vulkan_function_pointers->vulkan_loader_library = - base::LoadNativeLibrary(path, &native_library_load_error); - if (!vulkan_function_pointers->vulkan_loader_library) - return false; - if (!vulkan_instance_.Initialize(required_extensions, {})) return false; return true;
diff --git a/infra/config/chops-weetbix-dev.cfg b/infra/config/chops-weetbix-dev.cfg index f98e6a5a..cead963 100644 --- a/infra/config/chops-weetbix-dev.cfg +++ b/infra/config/chops-weetbix-dev.cfg
@@ -53,6 +53,8 @@ } } priority_hysteresis_percent: 50 + monorail_hostname: "monorail-staging.appspot.com" + display_prefix: "crbug.com" } realms {
diff --git a/infra/config/chops-weetbix.cfg b/infra/config/chops-weetbix.cfg index a6c1cea..154a32c5 100644 --- a/infra/config/chops-weetbix.cfg +++ b/infra/config/chops-weetbix.cfg
@@ -43,6 +43,8 @@ } } priority_hysteresis_percent: 50 + monorail_hostname: "bugs.chromium.org" + display_prefix: "crbug.com" } realms {
diff --git a/infra/config/dev/subprojects/chromium/ci.star b/infra/config/dev/subprojects/chromium/ci.star index 719c5e6..d965446e 100644 --- a/infra/config/dev/subprojects/chromium/ci.star +++ b/infra/config/dev/subprojects/chromium/ci.star
@@ -3,6 +3,7 @@ # found in the LICENSE file. load("//lib/builders.star", "builder", "cpu", "defaults", "goma", "os") +load("//lib/builder_config.star", "builder_config") luci.bucket( name = "ci",
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050NVIDIA Shield TV\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050NVIDIA Shield TV\051/properties.textpb" index def7636..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050NVIDIA Shield TV\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050NVIDIA Shield TV\051/properties.textpb"
@@ -1,10 +1,4 @@ { - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5X\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5X\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5X\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 5X\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 9\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 9\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050Nexus 9\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050Nexus 9\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050Pixel 2\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050Pixel 2\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050Pixel 2\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050Pixel 2\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI Release \050Pixel 4\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI Release \050Pixel 4\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI Release \050Pixel 4\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI Release \050Pixel 4\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI SkiaRenderer GL \050Nexus 5X\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI SkiaRenderer GL \050Nexus 5X\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI SkiaRenderer GL \050Nexus 5X\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI SkiaRenderer GL \050Nexus 5X\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Android FYI SkiaRenderer Vulkan \050Pixel 2\051/properties.textpb" "b/infra/config/generated/builders/ci/Android FYI SkiaRenderer Vulkan \050Pixel 2\051/properties.textpb" index 1c9949f..ee8f716 100644 --- "a/infra/config/generated/builders/ci/Android FYI SkiaRenderer Vulkan \050Pixel 2\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Android FYI SkiaRenderer Vulkan \050Pixel 2\051/properties.textpb"
@@ -1,9 +1,4 @@ { - "$build/reclient": { - "instance": "rbe-chromium-trusted", - "jobs": 250, - "metrics_project": "chromium-reclient-metrics" - }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/GPU FYI Android arm Builder/properties.textpb b/infra/config/generated/builders/ci/GPU FYI Android arm Builder/properties.textpb new file mode 100644 index 0000000..1c9949f --- /dev/null +++ b/infra/config/generated/builders/ci/GPU FYI Android arm Builder/properties.textpb
@@ -0,0 +1,20 @@ +{ + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.gpu.fyi", + "perf_dashboard_machine_group": "ChromiumGPUFYI", + "recipe": "chromium", + "sheriff_rotations": [ + "chromium.gpu" + ] +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.textpb b/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.textpb new file mode 100644 index 0000000..1c9949f --- /dev/null +++ b/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.textpb
@@ -0,0 +1,20 @@ +{ + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.gpu.fyi", + "perf_dashboard_machine_group": "ChromiumGPUFYI", + "recipe": "chromium", + "sheriff_rotations": [ + "chromium.gpu" + ] +} \ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/GPU FYI Linux Builder \050dbg\051/properties.textpb" "b/infra/config/generated/builders/ci/GPU FYI Linux Builder \050dbg\051/properties.textpb" index def7636..c01b8ac 100644 --- "a/infra/config/generated/builders/ci/GPU FYI Linux Builder \050dbg\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/GPU FYI Linux Builder \050dbg\051/properties.textpb"
@@ -1,9 +1,8 @@ { - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 500, + "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [],
diff --git a/infra/config/generated/builders/ci/GPU FYI Linux Builder/properties.textpb b/infra/config/generated/builders/ci/GPU FYI Linux Builder/properties.textpb index def7636..c01b8ac 100644 --- a/infra/config/generated/builders/ci/GPU FYI Linux Builder/properties.textpb +++ b/infra/config/generated/builders/ci/GPU FYI Linux Builder/properties.textpb
@@ -1,9 +1,8 @@ { - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 500, + "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [],
diff --git "a/infra/config/generated/builders/ci/Linux CFI \050reclient shadow\051/properties.textpb" "b/infra/config/generated/builders/ci/Linux CFI \050reclient shadow\051/properties.textpb" index 505efbb..dabc646 100644 --- "a/infra/config/generated/builders/ci/Linux CFI \050reclient shadow\051/properties.textpb" +++ "b/infra/config/generated/builders/ci/Linux CFI \050reclient shadow\051/properties.textpb"
@@ -1,5 +1,6 @@ { "$build/reclient": { + "ensure_verified": true, "instance": "rbe-chromium-trusted", "jobs": 400, "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/ci/ToTWinCFI/properties.textpb b/infra/config/generated/builders/ci/ToTWinCFI/properties.textpb deleted file mode 100644 index 3fa5f41e..0000000 --- a/infra/config/generated/builders/ci/ToTWinCFI/properties.textpb +++ /dev/null
@@ -1,15 +0,0 @@ -{ - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "chromium.clang", - "perf_dashboard_machine_group": "ChromiumClang", - "recipe": "chromium", - "sheriff_rotations": [ - "chromium.clang" - ] -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ToTWinCFI64/properties.textpb b/infra/config/generated/builders/ci/ToTWinCFI64/properties.textpb deleted file mode 100644 index 3fa5f41e..0000000 --- a/infra/config/generated/builders/ci/ToTWinCFI64/properties.textpb +++ /dev/null
@@ -1,15 +0,0 @@ -{ - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "chromium.clang", - "perf_dashboard_machine_group": "ChromiumClang", - "recipe": "chromium", - "sheriff_rotations": [ - "chromium.clang" - ] -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/Win10 Tests x64 20h2/properties.textpb b/infra/config/generated/builders/ci/Win10 Tests x64 20h2/properties.textpb deleted file mode 100644 index ef42b767..0000000 --- a/infra/config/generated/builders/ci/Win10 Tests x64 20h2/properties.textpb +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "chromium.fyi", - "recipe": "chromium" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/win-bootstrap-tests/properties.textpb b/infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.textpb similarity index 89% rename from infra/config/generated/builders/ci/win-bootstrap-tests/properties.textpb rename to infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.textpb index edab103a..fc3bce3 100644 --- a/infra/config/generated/builders/ci/win-bootstrap-tests/properties.textpb +++ b/infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.textpb
@@ -12,6 +12,6 @@ "v.test_suite" ] }, - "builder_group": "infra", + "builder_group": "chromium.fyi", "recipe": "chromium" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb b/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb deleted file mode 100644 index 9fa6504..0000000 --- a/infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb +++ /dev/null
@@ -1,87 +0,0 @@ -{ - "$build/chromium_tests_builder_config": { - "builder_config": { - "builder_db": { - "entries": [ - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "COMPILE_AND_TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - } - } - }, - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - } - } - } - ] - }, - "builder_ids": [ - { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - } - ], - "mirroring_builders": [ - { - "builder": "linux-bootstrap", - "group": "tryserver.infra" - } - ] - } - }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "infra", - "recipe": "chromium" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb b/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb deleted file mode 100644 index c7c2f5a..0000000 --- a/infra/config/generated/builders/ci/linux-bootstrap/properties.textpb +++ /dev/null
@@ -1,94 +0,0 @@ -{ - "$build/chromium_tests_builder_config": { - "builder_config": { - "builder_db": { - "entries": [ - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "COMPILE_AND_TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - } - } - }, - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - } - } - } - ] - }, - "builder_ids": [ - { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - } - ], - "builder_ids_in_scope_for_testing": [ - { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - } - ], - "mirroring_builders": [ - { - "builder": "linux-bootstrap", - "group": "tryserver.infra" - } - ] - } - }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "infra", - "recipe": "chromium" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/win-bootstrap/properties.textpb b/infra/config/generated/builders/ci/win-bootstrap/properties.textpb deleted file mode 100644 index edab103a..0000000 --- a/infra/config/generated/builders/ci/win-bootstrap/properties.textpb +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "infra", - "recipe": "chromium" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android_clang_dbg_recipe/properties.textpb b/infra/config/generated/builders/try/android-11-x86-rel-compilator/properties.textpb similarity index 70% rename from infra/config/generated/builders/try/android_clang_dbg_recipe/properties.textpb rename to infra/config/generated/builders/try/android-11-x86-rel-compilator/properties.textpb index 1128113..e4f5494 100644 --- a/infra/config/generated/builders/try/android_clang_dbg_recipe/properties.textpb +++ b/infra/config/generated/builders/try/android-11-x86-rel-compilator/properties.textpb
@@ -14,5 +14,9 @@ ] }, "builder_group": "tryserver.chromium.android", - "recipe": "chromium_trybot" + "orchestrator": { + "builder_group": "tryserver.chromium.android", + "builder_name": "android-11-x86-rel" + }, + "recipe": "chromium/compilator" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-11-x86-rel/properties.textpb b/infra/config/generated/builders/try/android-11-x86-rel/properties.textpb index d90599c..243cf95 100644 --- a/infra/config/generated/builders/try/android-11-x86-rel/properties.textpb +++ b/infra/config/generated/builders/try/android-11-x86-rel/properties.textpb
@@ -1,4 +1,8 @@ { + "$build/chromium_orchestrator": { + "compilator": "android-11-x86-rel-compilator", + "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649" + }, "$build/goma": { "enable_ats": true, "rpc_extra_params": "?prod", @@ -13,5 +17,5 @@ ] }, "builder_group": "tryserver.chromium.android", - "recipe": "chromium_trybot" + "recipe": "chromium/orchestrator" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-bootstrap/properties.textpb b/infra/config/generated/builders/try/linux-bootstrap/properties.textpb deleted file mode 100644 index 86f47c4..0000000 --- a/infra/config/generated/builders/try/linux-bootstrap/properties.textpb +++ /dev/null
@@ -1,88 +0,0 @@ -{ - "$build/chromium_tests_builder_config": { - "builder_config": { - "builder_db": { - "entries": [ - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "COMPILE_AND_TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - } - } - }, - { - "builder_id": { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - }, - "builder_spec": { - "builder_group": "infra", - "execution_mode": "TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64 - }, - "legacy_gclient_config": { - "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - } - } - } - ] - }, - "builder_ids": [ - { - "bucket": "ci", - "builder": "linux-bootstrap", - "project": "chromium" - } - ], - "builder_ids_in_scope_for_testing": [ - { - "bucket": "ci", - "builder": "linux-bootstrap-tests", - "project": "chromium" - } - ] - } - }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.infra", - "recipe": "chromium_trybot" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac-rel-compilator/properties.textpb b/infra/config/generated/builders/try/mac-rel-compilator/properties.textpb index 493f328..034541a 100644 --- a/infra/config/generated/builders/try/mac-rel-compilator/properties.textpb +++ b/infra/config/generated/builders/try/mac-rel-compilator/properties.textpb
@@ -18,7 +18,7 @@ "builder_group": "tryserver.chromium.mac", "orchestrator": { "builder_group": "tryserver.chromium.mac", - "builder_name": "mac-rel-orchestrator" + "builder_name": "mac-rel" }, "recipe": "chromium/compilator" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac-rel-orchestrator/properties.textpb b/infra/config/generated/builders/try/mac-rel-orchestrator/properties.textpb deleted file mode 100644 index b8bdcac..0000000 --- a/infra/config/generated/builders/try/mac-rel-orchestrator/properties.textpb +++ /dev/null
@@ -1,24 +0,0 @@ -{ - "$build/chromium_orchestrator": { - "compilator": "mac-rel-compilator", - "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649" - }, - "$build/code_coverage": { - "use_clang_coverage": true - }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.chromium.mac", - "recipe": "chromium/orchestrator" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac-rel/properties.textpb b/infra/config/generated/builders/try/mac-rel/properties.textpb index 162b672..b8bdcac 100644 --- a/infra/config/generated/builders/try/mac-rel/properties.textpb +++ b/infra/config/generated/builders/try/mac-rel/properties.textpb
@@ -1,9 +1,13 @@ { + "$build/chromium_orchestrator": { + "compilator": "mac-rel-compilator", + "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649" + }, "$build/code_coverage": { "use_clang_coverage": true }, "$build/goma": { - "jobs": 150, + "enable_ats": true, "rpc_extra_params": "?prod", "server_host": "goma.chromium.org", "use_luci_auth": true @@ -16,5 +20,5 @@ ] }, "builder_group": "tryserver.chromium.mac", - "recipe": "chromium_trybot" + "recipe": "chromium/orchestrator" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/win-bootstrap/properties.textpb b/infra/config/generated/builders/try/win-bootstrap/properties.textpb deleted file mode 100644 index f6dde095..0000000 --- a/infra/config/generated/builders/try/win-bootstrap/properties.textpb +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "$build/goma": { - "enable_ats": false, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.infra", - "recipe": "chromium_trybot" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/win10_chromium_x64_20h2_fyi_rel_ng/properties.textpb b/infra/config/generated/builders/try/win10_chromium_x64_20h2_fyi_rel_ng/properties.textpb deleted file mode 100644 index b8b797a..0000000 --- a/infra/config/generated/builders/try/win10_chromium_x64_20h2_fyi_rel_ng/properties.textpb +++ /dev/null
@@ -1,24 +0,0 @@ -{ - "$build/code_coverage": { - "coverage_test_types": [ - "unit", - "overall" - ], - "use_clang_coverage": true - }, - "$build/goma": { - "enable_ats": false, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.chromium.win", - "recipe": "chromium_trybot" -} \ No newline at end of file
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index 4a3de488..8786b21 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -485,9 +485,6 @@ * [linux_chromium_tsan_rel_ng_rts](https://ci.chromium.org/p/chromium/builders/try/linux_chromium_tsan_rel_ng_rts) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""linux_chromium_tsan_rel_ng_rts"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux_chromium_tsan_rel_ng_rts"")) * Experiment percentage: 5.0 -* [mac-rel-orchestrator](https://ci.chromium.org/p/chromium/builders/try/mac-rel-orchestrator) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""mac-rel-orchestrator"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac-rel-orchestrator"")) - * Experiment percentage: 1.0 - * [mac11-arm64-rel](https://ci.chromium.org/p/chromium/builders/try/mac11-arm64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""mac11-arm64-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac11-arm64-rel"")) * Experiment percentage: 100.0
diff --git a/infra/config/generated/luci/chops-weetbix-dev.cfg b/infra/config/generated/luci/chops-weetbix-dev.cfg index f98e6a5a..cead963 100644 --- a/infra/config/generated/luci/chops-weetbix-dev.cfg +++ b/infra/config/generated/luci/chops-weetbix-dev.cfg
@@ -53,6 +53,8 @@ } } priority_hysteresis_percent: 50 + monorail_hostname: "monorail-staging.appspot.com" + display_prefix: "crbug.com" } realms {
diff --git a/infra/config/generated/luci/chops-weetbix.cfg b/infra/config/generated/luci/chops-weetbix.cfg index a6c1cea..154a32c5 100644 --- a/infra/config/generated/luci/chops-weetbix.cfg +++ b/infra/config/generated/luci/chops-weetbix.cfg
@@ -43,6 +43,8 @@ } } priority_hysteresis_percent: 50 + monorail_hostname: "bugs.chromium.org" + display_prefix: "crbug.com" } realms {
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index b0c9a08..235db8a4 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -268,6 +268,10 @@ includable_only: true } builders { + name: "chromium/try/android-11-x86-rel-compilator" + includable_only: true + } + builders { name: "chromium/try/android-12-x64-fyi-rel" includable_only: true } @@ -541,10 +545,6 @@ includable_only: true } builders { - name: "chromium/try/android_clang_dbg_recipe" - includable_only: true - } - builders { name: "chromium/try/android_compile_dbg" location_regexp: ".*" location_regexp_exclude: ".+/[+]/docs/.+" @@ -1232,10 +1232,6 @@ includable_only: true } builders { - name: "chromium/try/linux-bootstrap" - includable_only: true - } - builders { name: "chromium/try/linux-cfm-rel" location_regexp: ".+/[+]/chromeos/components/chromebox_for_meetings/.+" location_regexp: ".+/[+]/chromeos/dbus/chromebox_for_meetings/.+" @@ -1646,13 +1642,6 @@ includable_only: true } builders { - name: "chromium/try/mac-rel-orchestrator" - experiment_percentage: 1 - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { name: "chromium/try/mac-rel-rts" includable_only: true } @@ -1833,10 +1822,6 @@ includable_only: true } builders { - name: "chromium/try/win-bootstrap" - includable_only: true - } - builders { name: "chromium/try/win-celab-try-rel" includable_only: true } @@ -1903,10 +1888,6 @@ includable_only: true } builders { - name: "chromium/try/win10_chromium_x64_20h2_fyi_rel_ng" - includable_only: true - } - builders { name: "chromium/try/win10_chromium_x64_dbg_ng" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index d3887edf..a2381400d 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -919,7 +919,7 @@ name: "Android FYI Release (NVIDIA Shield TV)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1005,7 +1005,7 @@ name: "Android FYI Release (Nexus 5)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1091,7 +1091,7 @@ name: "Android FYI Release (Nexus 5X)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1177,7 +1177,7 @@ name: "Android FYI Release (Nexus 9)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1263,7 +1263,7 @@ name: "Android FYI Release (Pixel 2)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1349,7 +1349,7 @@ name: "Android FYI Release (Pixel 4)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1435,7 +1435,7 @@ name: "Android FYI SkiaRenderer GL (Nexus 5X)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -1521,7 +1521,7 @@ name: "Android FYI SkiaRenderer Vulkan (Pixel 2)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.ci" @@ -3399,11 +3399,12 @@ builders { name: "Comparison Windows" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:Comparison Windows" + dimensions: "builderless:1" dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/main" @@ -6455,6 +6456,178 @@ } } builders { + name: "GPU FYI Android arm Builder" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.gpu.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/GPU FYI Android arm Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.gpu.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium.gpu"' + ' ]' + '}' + execution_timeout_secs: 21600 + build_numbers: YES + service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { + name: "GPU FYI Android arm64 Builder" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.gpu.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.gpu.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium.gpu"' + ' ]' + '}' + execution_timeout_secs: 21600 + build_numbers: YES + service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "GPU FYI Lacros x64 Builder" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -19424,178 +19597,6 @@ } } builders { - name: "ToTWinCFI" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/ToTWinCFI/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "chromium.clang",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium",' - ' "sheriff_rotations": [' - ' "chromium.clang"' - ' ]' - '}' - execution_timeout_secs: 50400 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ToTWinCFI64" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/ToTWinCFI64/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "chromium.clang",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium",' - ' "sheriff_rotations": [' - ' "chromium.clang"' - ' ]' - '}' - execution_timeout_secs: 50400 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "ToTWindowsCoverage" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -22479,88 +22480,6 @@ } } builders { - name: "Win10 Tests x64 20h2" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:Win10 Tests x64 20h2" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/Win10 Tests x64 20h2/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "chromium.fyi",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "Win10 x64 Debug (NVIDIA)" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -24567,6 +24486,10 @@ build_numbers: YES service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { key: "luci.use_realms" value: 100 } @@ -30268,6 +30191,89 @@ } } builders { + name: "fuchsia-fyi-x64-wst" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "fuchsia-official" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:fuchsia-official" @@ -34068,172 +34074,6 @@ } } builders { - name: "linux-bootstrap" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/linux-bootstrap/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "infra",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-bootstrap-tests" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/linux-bootstrap-tests/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "infra",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "linux-cfm-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -41493,172 +41333,6 @@ } } builders { - name: "win-bootstrap" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/win-bootstrap/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "infra",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-bootstrap-tests" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/win-bootstrap-tests/properties.textpb",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "infra",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "win-celab-builder-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:win-celab-builder-rel" @@ -45182,26 +44856,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Android ARM 32-bit Goma RBE Staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45228,26 +44909,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Android ARM 32-bit Goma RBE ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45274,26 +44962,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Android ARM 32-bit Goma RBE ToT (ATS)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45320,26 +45015,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE Staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45366,26 +45068,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE Staging (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45412,26 +45121,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE Staging (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45458,26 +45174,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE Staging (dbg) (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45504,26 +45227,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45550,26 +45280,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Linux Goma RBE ToT (ATS)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45596,26 +45333,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Mac Goma RBE Staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45642,26 +45386,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Mac Goma RBE Staging (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45688,26 +45439,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Mac Goma RBE Staging (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45734,26 +45492,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Mac Goma RBE ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -45780,26 +45545,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE ATS Staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45826,26 +45598,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE ATS Staging (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45872,26 +45651,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE ATS ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45918,26 +45704,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE Staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -45964,26 +45757,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE Staging (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -46010,26 +45810,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium Win Goma RBE ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 14400 @@ -46056,28 +45863,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Chromium iOS Goma RBE ToT/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' - ' "recipe": "chromium",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 caches { @@ -46108,26 +45921,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Linux Builder Goma RBE Canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46155,26 +45975,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Linux Builder Goma RBE Latest Client/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46201,26 +46028,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Mac Builder (dbg) Goma RBE Canary (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46247,26 +46081,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Mac Builder (dbg) Goma RBE Latest Client (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46292,26 +46133,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Mac M1 Builder (dbg) Goma RBE Canary (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46338,26 +46186,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder (dbg) Goma RBE ATS Canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46384,26 +46239,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder (dbg) Goma RBE ATS Latest Client/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46430,26 +46292,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder (dbg) Goma RBE Canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46476,26 +46345,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder (dbg) Goma RBE Latest Client/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46522,26 +46398,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder Goma RBE ATS Canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46568,26 +46451,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder Goma RBE ATS Latest Client/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46614,26 +46504,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder Goma RBE Canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46660,26 +46557,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder Goma RBE Canary (clobber)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46706,26 +46610,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/Win Builder Goma RBE Latest Client/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46753,26 +46664,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/android-archive-dbg-goma-rbe-ats-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46800,26 +46718,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/android-archive-dbg-goma-rbe-ats-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46847,26 +46772,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/android-archive-dbg-goma-rbe-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46894,26 +46826,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/android-archive-dbg-goma-rbe-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46941,26 +46880,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/chromeos-amd64-generic-rel-goma-rbe-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -46988,26 +46934,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/chromeos-amd64-generic-rel-goma-rbe-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47034,26 +46987,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?staging",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/chromeos-amd64-generic-rel-goma-rbe-staging/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -47080,26 +47040,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?tot",' - ' "server_host": "staging-goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/chromeos-amd64-generic-rel-goma-rbe-tot/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 10800 @@ -47125,27 +47092,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/ios-device-goma-rbe-canary-clobber/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' - ' "recipe": "chromium",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 caches { @@ -47174,27 +47148,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/ios-device-goma-rbe-latest-clobber/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' - ' "recipe": "chromium",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 caches { @@ -47225,26 +47206,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/linux-archive-rel-goma-rbe-ats-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47272,26 +47260,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/linux-archive-rel-goma-rbe-ats-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47319,26 +47314,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/linux-archive-rel-goma-rbe-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47366,26 +47368,33 @@ dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/linux-archive-rel-goma-rbe-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47412,26 +47421,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-canary/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47458,26 +47474,33 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.ci" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 80,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-latest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.goma.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 36000 @@ -47913,26 +47936,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-10-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48000,26 +48030,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-10-x86-fyi-rel-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48080,34 +48117,135 @@ builders { name: "android-11-x86-rel" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "builder:android-11-x86-rel" + dimensions: "cores:4" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-11-x86-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' - ' "recipe": "chromium_trybot"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium/orchestrator"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-11-x86-rel-compilator\">android-11-x86-rel-compilator</a>." + } + builders { + name: "android-11-x86-rel-compilator" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:android-11-x86-rel-compilator" + dimensions: "cores:32" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:1" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-11-x86-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -48163,6 +48301,7 @@ use_invocation_timestamp: true } } + description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-11-x86-rel\">android-11-x86-rel</a>." } builders { name: "android-12-x64-fyi-rel" @@ -48174,26 +48313,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-12-x64-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48427,26 +48573,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-asan/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48514,26 +48667,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-bfcache-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48703,26 +48863,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-arm-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48790,26 +48957,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48877,26 +49051,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -48964,26 +49145,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-asan-arm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49051,26 +49239,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-kitkat-arm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49138,26 +49333,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-lollipop-arm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49225,26 +49427,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-marshmallow-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49312,26 +49521,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49399,26 +49615,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49486,26 +49709,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-dbg-11-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49573,26 +49803,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-dbg-oreo-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49660,26 +49897,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-dbg-pie-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -49747,26 +49991,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-cronet-x86-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50008,26 +50259,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-inverse-fieldtrials-pie-x86-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50094,37 +50352,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "android-marshmallow-arm64-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_java_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -50193,38 +50447,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_java_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-arm64-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.android",' - ' "builder_name": "android-marshmallow-arm64-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -50293,34 +50542,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_java_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-arm64-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50387,37 +50635,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "android-marshmallow-x86-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_java_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-x86-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -50486,38 +50730,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_java_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-x86-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.android",' - ' "builder_name": "android-marshmallow-x86-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -50586,26 +50825,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-x86-rel-non-cq/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50673,27 +50919,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-marshmallow-x86-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50761,26 +51013,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50848,26 +51107,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-opus-arm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -50935,26 +51201,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-oreo-arm64-cts-networkservice-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51022,26 +51295,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51109,30 +51389,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-coverage-experimental-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51200,30 +51483,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-coverage-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51290,27 +51576,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51377,30 +51669,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "android-pie-arm64-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -51469,31 +51764,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.android",' - ' "builder_name": "android-pie-arm64-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -51562,27 +51859,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51650,26 +51953,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-arm64-wpt-rel-non-cq/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51737,27 +52047,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-pie-x86-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51825,26 +52141,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-rust-arm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.rust",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51912,26 +52235,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-web-platform-pie-x86-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -51999,26 +52329,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-weblayer-10-x86-rel-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52086,26 +52423,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-weblayer-marshmallow-x86-rel-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52173,26 +52517,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-weblayer-pie-x86-rel-tests/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52260,26 +52611,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-weblayer-pie-x86-wpt-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52347,26 +52705,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-weblayer-pie-x86-wpt-smoketest/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52434,26 +52799,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-marshmallow-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52521,26 +52893,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-nougat-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52608,26 +52987,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52695,26 +53081,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52782,26 +53175,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-pie-arm64-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52869,26 +53269,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-webview-pie-x86-wpt-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -52955,27 +53362,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_angle_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.angle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53043,26 +53456,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_archive_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53130,27 +53550,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_arm64_dbg_recipe/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53218,26 +53644,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_blink_rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53305,114 +53738,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_cfi_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_clang_dbg_recipe" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53479,27 +53831,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_compile_dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53567,26 +53925,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_compile_x64_dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53654,26 +54019,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_compile_x86_dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53740,26 +54112,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_cronet/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53827,26 +54206,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_mojo/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -53914,26 +54300,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_n5x_swarming_dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54000,27 +54393,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -54088,26 +54487,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android_unswarmed_pixel_aosp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54378,26 +54784,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/cast_shell_android/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54465,26 +54878,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/cast_shell_audio_linux/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54551,26 +54971,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/cast_shell_linux/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54638,26 +55065,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/cast_shell_linux_arm64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54725,26 +55159,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/cast_shell_linux_dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54812,26 +55253,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54899,26 +55347,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -54985,30 +55440,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "chromeos-amd64-generic-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -55077,30 +55535,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.chromiumos",' - ' "builder_name": "chromeos-amd64-generic-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -55168,26 +55629,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55255,26 +55723,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55435,26 +55910,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-kevin-compile-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55522,26 +56004,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-kevin-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55689,26 +56178,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-linux-x64-deps-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55774,25 +56270,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-mac-x64-deps-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55858,25 +56362,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-try-mac-amd-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -55942,25 +56454,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.uhd630.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-try-mac-intel-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56026,26 +56546,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-try-win10-x64-asan-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56111,26 +56638,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-try-win10-x86-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56196,26 +56730,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-win10-x64-deps-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56281,26 +56822,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/dawn-win10-x86-deps-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56367,27 +56915,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-angle-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.angle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56538,26 +57092,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-arm64-cast/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56716,26 +57277,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-compile-x64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56890,26 +57458,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-fyi-arm64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -56977,26 +57552,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-fyi-arm64-femu/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57064,26 +57646,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-fyi-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57151,26 +57740,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-fyi-x64-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57238,26 +57834,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-fyi-x64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57325,26 +57928,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57411,26 +58021,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-x64-cast/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57497,26 +58114,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia_arm64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57583,26 +58207,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia_x64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57669,26 +58300,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia_x64_rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -57755,26 +58393,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nexus5.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-l-nexus-5-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -57838,26 +58483,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nexus5x.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-m-nexus-5x-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -57921,26 +58573,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nexus5x.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-m-nexus-5x-skgl-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58004,26 +58663,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nexus9.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-m-nexus-9-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58087,26 +58753,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nvidia.shield.tv.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-n-nvidia-shield-tv-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58170,26 +58843,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.pixel2.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-p-pixel-2-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58253,26 +58933,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.pixel2.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-p-pixel-2-skv-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58336,26 +59023,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.pixel4.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-android-r-pixel-4-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58419,26 +59113,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.chromeos.amd64.generic.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-chromeos-amd64-generic/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58502,26 +59203,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.chromeos.kevin.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-chromeos-kevin/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58585,26 +59293,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-lacros-amd-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58668,26 +59383,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-lacros-intel-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58751,26 +59473,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-amd-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58834,26 +59563,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-intel-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -58917,26 +59653,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-intel-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59000,26 +59743,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-intel-sk-dawn-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59083,26 +59833,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-intel-skv/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59166,26 +59923,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-nvidia-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59249,26 +60013,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-nvidia-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59332,26 +60103,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-nvidia-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59415,26 +60193,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-nvidia-skv/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59498,26 +60283,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-linux-nvidia-tsn/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59580,25 +60372,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.pro.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-amd-pro-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59661,25 +60461,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-amd-retina-asan/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59742,25 +60550,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-amd-retina-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59823,25 +60639,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-amd-retina-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59904,25 +60728,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-amd-retina-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -59985,25 +60817,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.arm64.apple.m1.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-arm64-apple-m1-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60066,25 +60906,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-intel-asan/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60147,25 +60995,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-intel-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60228,25 +61084,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-intel-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60309,25 +61173,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-intel-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60390,25 +61262,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60471,25 +61351,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 43200 @@ -60552,25 +61440,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60634,26 +61530,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-amd-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60717,26 +61620,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-intel-exp-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60800,26 +61710,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-intel-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60883,26 +61800,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-dbg-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -60966,26 +61890,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-dx12vk-dbg-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61049,26 +61980,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-dx12vk-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61132,26 +62070,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-exp-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61215,26 +62160,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-rel-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61298,26 +62250,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61381,26 +62340,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win10-nvidia-sk-dawn-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61464,26 +62430,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win7.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win7-amd-rel-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61547,26 +62520,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win7.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win7-nvidia-rel-32/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61630,26 +62610,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win7.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-win7-nvidia-rel-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61713,26 +62700,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.android.nexus5x.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-android-m-nexus-5x-64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61796,26 +62790,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-linux-nvidia-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61879,26 +62880,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.gpu.linux.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-linux-nvidia-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -61961,25 +62969,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.retina.amd.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-mac-amd-retina-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -62042,25 +63058,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.gpu.mac.mini.intel.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-mac-intel-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -62124,26 +63148,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.gpu.win10.nvidia.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/gpu-try-win10-nvidia-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -62288,27 +63319,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-catalyst/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62377,27 +63415,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-device/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62466,38 +63511,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_exclude_sources": "ios_test_files_and_test_utils",' - ' "coverage_test_types": [' - ' "overall",' - ' "unit"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/flakiness": {' - ' "check_for_flakiness": true' - ' },' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62566,30 +63607,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/flakiness": {' - ' "check_for_flakiness": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-cronet/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62658,38 +63703,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_exclude_sources": "ios_test_files_and_test_utils",' - ' "coverage_test_types": [' - ' "overall",' - ' "unit"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/flakiness": {' - ' "check_for_flakiness": true' - ' },' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-full-configs/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62758,27 +63799,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62847,27 +63895,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-multi-window/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -62936,27 +63991,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-noncq/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63025,34 +64087,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_exclude_sources": "ios_test_files_and_test_utils",' - ' "coverage_test_types": [' - ' "unit"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios-simulator-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63121,27 +64183,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios14-beta-simulator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63210,27 +64279,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios14-sdk-simulator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63299,27 +64375,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios15-beta-simulator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63388,27 +64471,34 @@ dimensions: "os:Mac-11" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/ios15-sdk-simulator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot",' - ' "xcode_build_version": "13a233"' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 @@ -63478,26 +64568,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/lacros-amd64-generic-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -63564,26 +64661,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/lacros-arm-generic-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -63651,26 +64755,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/layout_test_leak_detection/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -63738,26 +64849,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/leak_detection_linux/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -63824,30 +64942,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-1mbu-compile-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' - ' "bot_update_experiments": [' - ' "no_sync"' - ' ],' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -63997,27 +65118,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-angle-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.angle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64168,26 +65295,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-annotator-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64255,26 +65389,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-autofill-assistant/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64342,26 +65483,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-bfcache-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64429,27 +65577,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-bionic-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64517,26 +65671,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-heap-concurrent-marking-tsan-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64604,26 +65765,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-heap-verification-try/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64691,26 +65859,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-optional-highdpi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64778,26 +65953,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64865,26 +66047,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-v8-oilpan/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -64952,93 +66141,6 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.linux",' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-bootstrap" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" cmd: "bootstrapper" @@ -65055,7 +66157,7 @@ ' }' ' },' ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/try/linux-bootstrap/properties.textpb",' + ' "properties_file": "infra/config/generated/builders/try/linux-blink-web-tests-force-accessibility-rel/properties.textpb",' ' "top_level_project": {' ' "ref": "refs/heads/main",' ' "repo": {' @@ -65064,7 +66166,7 @@ ' }' ' }' ' },' - ' "builder_group": "tryserver.infra",' + ' "builder_group": "tryserver.chromium.linux",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' @@ -65133,26 +66235,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-cfm-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65220,26 +66329,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-annotator-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65306,26 +66422,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-compile-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65393,26 +66516,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65480,26 +66610,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-inverse-fieldtrials-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65567,30 +66704,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true,' - ' "use_javascript_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-js-code-coverage/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -65657,37 +66797,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "linux-chromeos-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -65756,38 +66892,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.chromiumos",' - ' "builder_name": "linux-chromeos-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -66030,26 +67161,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-dawn-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66117,26 +67255,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-dcheck-off-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66204,26 +67349,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-example-builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66291,26 +67443,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-extended-tracing-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66378,20 +67537,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-gcc-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66459,26 +67631,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-headless-shell-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66546,26 +67725,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-inverse-fieldtrials-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66633,26 +67819,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66720,26 +67913,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66807,27 +68007,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66895,34 +68101,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-rel-code-coverage/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -66990,27 +68195,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67078,26 +68289,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-version-skew-fyi/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67165,26 +68383,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-layout-tests-edit-ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67338,26 +68563,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-mbi-mode-per-render-process-host-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67425,26 +68657,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-mbi-mode-per-site-instance-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67512,26 +68751,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67599,26 +68845,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-perfetto-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67874,30 +69127,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -67965,26 +69221,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-rust-x64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.rust",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68051,30 +69314,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-stable-filter-combined-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68141,30 +69407,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-stable-filter-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68232,26 +69501,33 @@ dimensions: "pool:luci.chromium.swangle.chromium.linux.x64.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-swangle-chromium-try-x64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -68476,26 +69752,33 @@ dimensions: "pool:luci.chromium.swangle.deps.linux.x64.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-swangle-try-x64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 7200 @@ -68560,27 +69843,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-trusty-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68648,26 +69937,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-viz-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68734,26 +70030,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-wayland-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68821,26 +70124,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-webkit-msan-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68908,26 +70218,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-wpt-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -68995,26 +70312,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-wpt-identity-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69082,26 +70406,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-wpt-input-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69169,27 +70500,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-xenial-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69257,26 +70594,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_android_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69344,26 +70688,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_analysis/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69431,26 +70782,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_archive_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69517,30 +70875,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "linux_chromium_asan_rel_ng-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_asan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -69609,31 +70970,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_asan_rel_ng-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.linux",' - ' "builder_name": "linux_chromium_asan_rel_ng"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -69702,27 +71065,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_asan_rel_ng_rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -69790,26 +71159,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_cfi_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 25200 @@ -69877,27 +71253,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_chromeos_asan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 25200 @@ -69965,27 +71347,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_chromeos_msan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70140,26 +71528,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_clobber_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70227,26 +71622,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_compile_dbg_32_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70313,27 +71715,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_compile_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70405,26 +71813,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_compile_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70492,26 +71907,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70583,27 +72005,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_msan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -70670,30 +72098,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "linux_chromium_tsan_rel_ng-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -70762,31 +72193,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_tsan_rel_ng-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.linux",' - ' "builder_name": "linux_chromium_tsan_rel_ng"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -70854,27 +72287,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_tsan_rel_ng_rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -70942,26 +72381,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_chromium_ubsan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71029,26 +72475,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_layout_tests_layout_ng_disabled/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71116,26 +72569,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_mojo/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71203,26 +72663,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_mojo_chromeos/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71289,26 +72756,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_optional_gpu_tests_rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -71457,26 +72931,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux_vr/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71623,25 +73104,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-dawn-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71708,25 +73197,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-inverse-fieldtrials-fyi-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71792,25 +73289,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 108000 @@ -71877,25 +73382,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-osxbeta-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -71957,221 +73470,38 @@ name: "mac-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:mac-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-11" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.mac",' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac-rel-compilator" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:mac-rel-compilator" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-11" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.mac",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.mac",' - ' "builder_name": "mac-rel-orchestrator"' - ' },' - ' "recipe": "chromium/compilator"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-orchestrator\">mac-rel-orchestrator</a>." - } - builders { - name: "mac-rel-orchestrator" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:mac-rel-orchestrator" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "mac-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -72231,6 +73561,100 @@ description_html: "This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-compilator\">mac-rel-compilator</a>." } builders { + name: "mac-rel-compilator" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:mac-rel-compilator" + dimensions: "cpu:x86-64" + dimensions: "os:Mac-11" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:1" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium/compilator"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel\">mac-rel</a>." + } + builders { name: "mac-rel-rts" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:mac-rel-rts" @@ -72239,29 +73663,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-rel-rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72327,25 +73755,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.swangle.chromium.mac.x64.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-swangle-chromium-try-x64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -72408,25 +73844,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-updater-try-builder-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.updater",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72492,25 +73936,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac-updater-try-builder-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.updater",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72577,25 +74029,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac10.12-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72662,25 +74122,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac10.13-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72747,25 +74215,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac10.14-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72832,25 +74308,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac10.15-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -72917,30 +74401,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "mac11-arm64-rel-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac11-arm64-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -73008,30 +74495,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac11-arm64-rel-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.mac",' - ' "builder_name": "mac11-arm64-rel"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 @@ -73099,25 +74589,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac11.0-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73184,25 +74682,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac11.0.arm64-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73269,25 +74775,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_10.11_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73354,25 +74868,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_10.12_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73439,25 +74961,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_10.13_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73524,25 +75054,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_10.14_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73609,25 +75147,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_10.15_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73694,25 +75240,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_11.0_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73779,25 +75333,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_archive_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73864,26 +75426,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_asan_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -73950,26 +75519,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -74036,25 +75612,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_compile_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -74121,25 +75705,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_chromium_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -74205,25 +75797,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/mac_optional_gpu_tests_rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.mac",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -74451,26 +76051,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/network_service_linux/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.linux",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -74884,26 +76491,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/try-nougat-phone-tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -75220,26 +76834,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-annotator-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -75307,94 +76928,6 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.win",' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-bootstrap" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" cmd: "bootstrapper" @@ -75411,7 +76944,7 @@ ' }' ' },' ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/try/win-bootstrap/properties.textpb",' + ' "properties_file": "infra/config/generated/builders/try/win-asan/properties.textpb",' ' "top_level_project": {' ' "ref": "refs/heads/main",' ' "repo": {' @@ -75420,7 +76953,7 @@ ' }' ' }' ' },' - ' "builder_group": "tryserver.infra",' + ' "builder_group": "tryserver.chromium.win",' ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' @@ -75574,26 +77107,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-dawn-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.dawn",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -75747,26 +77287,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -75834,26 +77381,33 @@ dimensions: "pool:luci.chromium.swangle.chromium.win.x86.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-swangle-chromium-try-x86/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -76238,26 +77792,33 @@ dimensions: "pool:luci.chromium.swangle.win.x64.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-swangle-try-x64/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 7200 @@ -76322,26 +77883,33 @@ dimensions: "pool:luci.chromium.swangle.deps.win.x86.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-swangle-try-x86/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.swangle",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 7200 @@ -76406,26 +77974,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-updater-try-builder-dbg/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.updater",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -76493,26 +78068,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win-updater-try-builder-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.updater",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -76580,26 +78162,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10.20h2-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -76667,119 +78256,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win10_chromium_x64_20h2_fyi_rel_ng" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:win10_chromium_x64_20h2_fyi_rel_ng" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10-19042" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -76847,26 +78350,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -76933,37 +78443,33 @@ dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/chromium_orchestrator": {' - ' "compilator": "win10_chromium_x64_rel_ng-compilator",' - ' "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' - ' },' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/orchestrator"' '}' execution_timeout_secs: 14400 @@ -77032,44 +78538,39 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "coverage_test_types": [' - ' "unit",' - ' "overall"' - ' ],' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng-compilator/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' - ' "orchestrator": {' - ' "builder_group": "tryserver.chromium.win",' - ' "builder_name": "win10_chromium_x64_rel_ng"' - ' },' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium/compilator"' '}' execution_timeout_secs: 14400 expiration_secs: 7200 grace_period { - seconds: 180 + seconds: 240 } caches { name: "win_toolchain" @@ -77131,26 +78632,33 @@ dimensions: "os:Windows" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng_exp/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77217,30 +78725,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.try" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/code_coverage": {' - ' "use_clang_coverage": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win10_chromium_x64_rel_ng_rts/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77308,26 +78819,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win32-official/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -77395,26 +78913,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win7-blink-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.blink",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77482,27 +79007,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "jobs": 300,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win7-rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 16200 @@ -77570,26 +79101,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_archive/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77657,27 +79195,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:1" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "jobs": 150,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_chromium_compile_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77745,26 +79289,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_chromium_compile_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77832,26 +79383,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_chromium_dbg_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -77919,26 +79477,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_chromium_x64_rel_ng/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -78006,26 +79571,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_mojo/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -78093,26 +79665,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_optional_gpu_tests_rel/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 21600 @@ -78260,26 +79839,33 @@ dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/win_x64_archive/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "tryserver.chromium.win",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium_trybot"' '}' execution_timeout_secs: 14400 @@ -78360,27 +79946,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Android Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78405,21 +79997,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Android Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78444,27 +80048,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Linux Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78489,21 +80099,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Linux Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78528,26 +80150,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Mac" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Mac Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78572,21 +80201,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Mac" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Mac Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78611,27 +80252,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Windows" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Win Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78656,21 +80303,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Windows" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Win10 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78695,21 +80354,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Windows" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Win7 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78734,21 +80405,33 @@ dimensions: "cpu:x86-64" dimensions: "os:Windows" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc/WebRTC Chromium Win8 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc",' - ' "perf_dashboard_machine_group": "ChromiumWebRTC",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78789,26 +80472,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78833,26 +80523,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Builder (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78877,26 +80574,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Builder ARM64 (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78921,20 +80625,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78959,20 +80676,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -78997,26 +80727,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Linux Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79041,26 +80778,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Linux Builder (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79085,20 +80829,33 @@ dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Linux Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79123,25 +80880,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79166,25 +80931,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79209,20 +80982,33 @@ dimensions: "os:Mac" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79247,26 +81033,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Win Builder/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79291,26 +81084,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Win Builder (dbg)/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79335,20 +81135,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Win10 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79373,20 +81186,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Win7 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 @@ -79411,20 +81237,33 @@ dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.webrtc.fyi" exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" } properties: '{' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Win8 Tester/properties.textpb",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' ' },' ' "builder_group": "chromium.webrtc.fyi",' + ' "led_builder_is_bootstrapped": true,' ' "recipe": "chromium"' '}' execution_timeout_secs: 7200
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index efce2307..2618c5e 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -1701,24 +1701,14 @@ short_name: "asan" } builders { - name: "buildbucket/luci.chrome.ci/fuchsia-perf-fyi" - category: "fyi" - short_name: "ast-perf" - } - builders { - name: "buildbucket/luci.chrome.ci/fuchsia-fyi-astro" - category: "fyi" - short_name: "astro" - } - builders { name: "buildbucket/luci.chrome.ci/fuchsia-builder-perf-fyi" category: "fyi" short_name: "builder-perf" } builders { - name: "buildbucket/luci.chrome.ci/fuchsia-perf-sherlock-fyi" + name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-wst" category: "fyi" - short_name: "shk-perf" + short_name: "wst" } builders { name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-rel" @@ -1731,6 +1721,26 @@ short_name: "x64-dbg" } builders { + name: "buildbucket/luci.chrome.ci/fuchsia-fyi-astro" + category: "astro" + short_name: "gpu" + } + builders { + name: "buildbucket/luci.chrome.ci/fuchsia-perf-fyi" + category: "astro" + short_name: "perf" + } + builders { + name: "buildbucket/luci.chrome.ci/fuchsia-fyi-sherlock" + category: "sherlock" + short_name: "gpu" + } + builders { + name: "buildbucket/luci.chrome.ci/fuchsia-perf-sherlock-fyi" + category: "sherlock" + short_name: "perf" + } + builders { name: "buildbucket/luci.chromium.ci/ToTFuchsiaOfficial" category: "misc" short_name: "clang-off" @@ -2356,6 +2366,12 @@ id: "try" name: "Chromium CQ Console" builders { + name: "buildbucket/luci.chromium.try/android-11-x86-rel" + } + builders { + name: "buildbucket/luci.chromium.try/android-11-x86-rel-compilator" + } + builders { name: "buildbucket/luci.chromium.try/android-binary-size" } builders { @@ -2551,9 +2567,6 @@ name: "buildbucket/luci.chromium.try/mac-rel-compilator" } builders { - name: "buildbucket/luci.chromium.try/mac-rel-orchestrator" - } - builders { name: "buildbucket/luci.chromium.try/mac-updater-try-builder-dbg" } builders { @@ -4924,16 +4937,6 @@ short_name: "ToT" } builders { - name: "buildbucket/luci.chromium.ci/ToTWinCFI" - category: "CFI|Win" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium.ci/ToTWinCFI64" - category: "CFI|Win" - short_name: "x64" - } - builders { name: "buildbucket/luci.chromium.ci/ToTChromeOS (dbg)" category: "ToT ChromeOS" short_name: "dbg" @@ -6276,6 +6279,11 @@ short_name: "rel" } builders { + name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-wst" + category: "fuchsia|x64" + short_name: "wst" + } + builders { name: "buildbucket/luci.chromium.ci/ios-asan" category: "iOS" short_name: "asan" @@ -6440,10 +6448,6 @@ category: "win10" } builders { - name: "buildbucket/luci.chromium.ci/Win10 Tests x64 20h2" - category: "win10|20h2" - } - builders { name: "buildbucket/luci.chromium.ci/win32-arm64-rel" category: "win32|arm64" } @@ -8274,6 +8278,16 @@ short_name: "P2" } builders { + name: "buildbucket/luci.chromium.ci/GPU FYI Android arm Builder" + category: "Android|Builder" + short_name: "arm" + } + builders { + name: "buildbucket/luci.chromium.ci/GPU FYI Android arm64 Builder" + category: "Android|Builder" + short_name: "arm64" + } + builders { name: "buildbucket/luci.chromium.ci/Android FYI Release (Pixel 4)" category: "Android|R32|QCOM" short_name: "P4" @@ -13289,26 +13303,6 @@ repo_url: "https://chromium.googlesource.com/chromium/src" refs: "regexp:refs/heads/main" manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium.ci/linux-bootstrap" - category: "bootstrap|linux" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-bootstrap-tests" - category: "bootstrap|linux" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium.ci/win-bootstrap" - category: "bootstrap|win" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium.ci/win-bootstrap-tests" - category: "bootstrap|win" - short_name: "tst" - } header { oncalls { name: "Chromium" @@ -13929,6 +13923,9 @@ name: "buildbucket/luci.chromium.try/android-11-x86-rel" } builders { + name: "buildbucket/luci.chromium.try/android-11-x86-rel-compilator" + } + builders { name: "buildbucket/luci.chromium.try/android-12-x64-fyi-rel" } builders { @@ -14106,9 +14103,6 @@ name: "buildbucket/luci.chromium.try/android_cfi_rel_ng" } builders { - name: "buildbucket/luci.chromium.try/android_clang_dbg_recipe" - } - builders { name: "buildbucket/luci.chromium.try/android_compile_dbg" } builders { @@ -14514,9 +14508,6 @@ name: "buildbucket/luci.chromium.try/linux-blink-web-tests-force-accessibility-rel" } builders { - name: "buildbucket/luci.chromium.try/linux-bootstrap" - } - builders { name: "buildbucket/luci.chromium.try/linux-cfm-rel" } builders { @@ -14757,9 +14748,6 @@ name: "buildbucket/luci.chromium.try/mac-rel-compilator" } builders { - name: "buildbucket/luci.chromium.try/mac-rel-orchestrator" - } - builders { name: "buildbucket/luci.chromium.try/mac-rel-rts" } builders { @@ -14871,9 +14859,6 @@ name: "buildbucket/luci.chromium.try/win-asan" } builders { - name: "buildbucket/luci.chromium.try/win-bootstrap" - } - builders { name: "buildbucket/luci.chromium.try/win-celab-try-rel" } builders { @@ -14919,9 +14904,6 @@ name: "buildbucket/luci.chromium.try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng" } builders { - name: "buildbucket/luci.chromium.try/win10_chromium_x64_20h2_fyi_rel_ng" - } - builders { name: "buildbucket/luci.chromium.try/win10_chromium_x64_dbg_ng" } builders { @@ -15055,6 +15037,9 @@ name: "buildbucket/luci.chromium.try/android-11-x86-rel" } builders { + name: "buildbucket/luci.chromium.try/android-11-x86-rel-compilator" + } + builders { name: "buildbucket/luci.chromium.try/android-12-x64-fyi-rel" } builders { @@ -15217,9 +15202,6 @@ name: "buildbucket/luci.chromium.try/android_cfi_rel_ng" } builders { - name: "buildbucket/luci.chromium.try/android_clang_dbg_recipe" - } - builders { name: "buildbucket/luci.chromium.try/android_compile_dbg" } builders { @@ -15871,9 +15853,6 @@ name: "buildbucket/luci.chromium.try/mac-rel-compilator" } builders { - name: "buildbucket/luci.chromium.try/mac-rel-orchestrator" - } - builders { name: "buildbucket/luci.chromium.try/mac-rel-rts" } builders { @@ -16067,9 +16046,6 @@ name: "buildbucket/luci.chromium.try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng" } builders { - name: "buildbucket/luci.chromium.try/win10_chromium_x64_20h2_fyi_rel_ng" - } - builders { name: "buildbucket/luci.chromium.try/win10_chromium_x64_dbg_ng" } builders { @@ -16119,12 +16095,6 @@ consoles { id: "tryserver.infra" name: "tryserver.infra" - builders { - name: "buildbucket/luci.chromium.try/linux-bootstrap" - } - builders { - name: "buildbucket/luci.chromium.try/win-bootstrap" - } builder_view_only: true } logo_url: "https://storage.googleapis.com/chrome-infra-public/logo/chromium.svg"
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg index 236d7c6..aaeadaf 100644 --- a/infra/config/generated/luci/luci-notify.cfg +++ b/infra/config/generated/luci/luci-notify.cfg
@@ -2857,6 +2857,19 @@ } notifiers { notifications { + on_change: true + email { + recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" + } + } + builders { + bucket: "ci" + name: "fuchsia-fyi-x64-wst" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { on_occurrence: FAILURE failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b" email {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 7b2686c..409ebba 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -148,6 +148,10 @@ job { id: "Android FYI Release (NVIDIA Shield TV)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -158,6 +162,10 @@ job { id: "Android FYI Release (Nexus 5)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -168,6 +176,10 @@ job { id: "Android FYI Release (Nexus 5X)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -178,6 +190,10 @@ job { id: "Android FYI Release (Nexus 9)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -188,6 +204,10 @@ job { id: "Android FYI Release (Pixel 2)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -198,6 +218,10 @@ job { id: "Android FYI Release (Pixel 4)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -208,6 +232,10 @@ job { id: "Android FYI SkiaRenderer GL (Nexus 5X)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -218,6 +246,10 @@ job { id: "Android FYI SkiaRenderer Vulkan (Pixel 2)" realm: "ci" + acls { + role: TRIGGERER + granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" + } acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" @@ -1098,6 +1130,26 @@ } } job { + id: "GPU FYI Android arm Builder" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "GPU FYI Android arm Builder" + } +} +job { + id: "GPU FYI Android arm64 Builder" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "GPU FYI Android arm64 Builder" + } +} +job { id: "GPU FYI Lacros x64 Builder" realm: "ci" acl_sets: "ci" @@ -2989,26 +3041,6 @@ } } job { - id: "ToTWinCFI" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "ToTWinCFI" - } -} -job { - id: "ToTWinCFI64" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "ToTWinCFI64" - } -} -job { id: "ToTWindowsCoverage" realm: "ci" acl_sets: "ci" @@ -3843,20 +3875,6 @@ } } job { - id: "Win10 Tests x64 20h2" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Win10 Tests x64 20h2" - } -} -job { id: "Win10 x64 Debug (NVIDIA)" realm: "ci" acls { @@ -4935,6 +4953,16 @@ } } job { + id: "fuchsia-fyi-x64-wst" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "fuchsia-fyi-x64-wst" + } +} +job { id: "fuchsia-official" realm: "ci" acl_sets: "ci" @@ -5480,31 +5508,6 @@ } } job { - id: "linux-bootstrap" - realm: "ci" - schedule: "triggered" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "linux-bootstrap" - } -} -job { - id: "linux-bootstrap-tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "linux-bootstrap-tests" - } -} -job { id: "linux-cfm-rel" realm: "ci" acl_sets: "ci" @@ -6487,31 +6490,6 @@ } } job { - id: "win-bootstrap" - realm: "ci" - schedule: "triggered" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "win-bootstrap" - } -} -job { - id: "win-bootstrap-tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "win-bootstrap-tests" - } -} -job { id: "win-celab-builder-rel" realm: "ci" schedule: "0 0,6,12,18 * * *" @@ -6947,14 +6925,6 @@ triggers: "Afl Upload Linux ASan" triggers: "Android ASAN (dbg)" triggers: "Android ASAN (dbg) (reclient)" - triggers: "Android FYI Release (NVIDIA Shield TV)" - triggers: "Android FYI Release (Nexus 5)" - triggers: "Android FYI Release (Nexus 5X)" - triggers: "Android FYI Release (Nexus 9)" - triggers: "Android FYI Release (Pixel 2)" - triggers: "Android FYI Release (Pixel 4)" - triggers: "Android FYI SkiaRenderer GL (Nexus 5X)" - triggers: "Android FYI SkiaRenderer Vulkan (Pixel 2)" triggers: "Android Release (Nexus 5X)" triggers: "Android WebView P FYI (rel)" triggers: "Android arm Builder (dbg)" @@ -6991,6 +6961,8 @@ triggers: "Deterministic Linux (dbg)" triggers: "Fuchsia ARM64" triggers: "Fuchsia x64" + triggers: "GPU FYI Android arm Builder" + triggers: "GPU FYI Android arm64 Builder" triggers: "GPU FYI Lacros x64 Builder" triggers: "GPU FYI Linux Builder" triggers: "GPU FYI Linux Builder (dbg)" @@ -7094,8 +7066,6 @@ triggers: "ToTWin64(dll)" triggers: "ToTWin64PGO" triggers: "ToTWinASanLibfuzzer" - triggers: "ToTWinCFI" - triggers: "ToTWinCFI64" triggers: "ToTWindowsCoverage" triggers: "ToTiOS" triggers: "ToTiOSDevice" @@ -7177,6 +7147,7 @@ triggers: "fuchsia-fyi-x64-asan" triggers: "fuchsia-fyi-x64-dbg" triggers: "fuchsia-fyi-x64-rel" + triggers: "fuchsia-fyi-x64-wst" triggers: "fuchsia-official" triggers: "fuchsia-x64-cast" triggers: "fuchsia-x64-dbg"
diff --git a/infra/config/generators/scheduler-noop-jobs.star b/infra/config/generators/scheduler-noop-jobs.star index 8546efd..4bee49e 100644 --- a/infra/config/generators/scheduler-noop-jobs.star +++ b/infra/config/generators/scheduler-noop-jobs.star
@@ -23,11 +23,6 @@ # the branches "mac-osxbeta-rel": branches.DESKTOP_EXTENDED_STABLE_MILESTONE, - # This tester is triggered by 'Win x64 Builder', but it is an FYI builder - # and not mirrored by any branched try builders, so we do not need to run it - # on the branches - "Win10 Tests x64 20h2": branches.STANDARD_MILESTONE, - # These Android testers are triggered by 'Android arm Builder (dbg)', but we # don't have sufficient capacity of devices with older Android versions, so # we do not run them on the branches
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index debecce..4465e174 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -385,7 +385,7 @@ fully_qualified_builder_dimension = args.DEFAULT, cores = args.DEFAULT, cpu = args.DEFAULT, - bootstrap = False, + bootstrap = True, builder_group = args.DEFAULT, builder_spec = None, mirrors = None,
diff --git a/infra/config/lib/ci.star b/infra/config/lib/ci.star index caa996c2..32706cf 100644 --- a/infra/config/lib/ci.star +++ b/infra/config/lib/ci.star
@@ -31,7 +31,6 @@ *, name, branch_selector = branches.MAIN, - bootstrap = True, console_view_entry = None, main_console_view = args.DEFAULT, cq_mirrors_console_view = args.DEFAULT, @@ -49,13 +48,6 @@ branch_selector: A branch selector value controlling whether the builder definition is executed. See branches.star for more information. - bootstrap: a boolean indicating whether the builder should have its - properties bootstrapped. If True, the builder's properties will be - written to a separate file and its definition will be updated with - new properties and executable that cause a bootstrapping binary to - be used. The build's default values for properties will be taken - from the properties file at the version that the build will check - out. console_view_entry: A `consoles.console_view_entry` struct or a list of them describing console view entries to create for the builder. See `consoles.console_view_entry` for details. @@ -151,7 +143,6 @@ builders.builder( name = name, branch_selector = branch_selector, - bootstrap = bootstrap, console_view_entry = console_view_entry, resultdb_bigquery_exports = merged_resultdb_bigquery_exports, sheriff_rotations = sheriff_rotations,
diff --git a/infra/config/recipes.star b/infra/config/recipes.star index 1add677..9abf88c0 100644 --- a/infra/config/recipes.star +++ b/infra/config/recipes.star
@@ -85,6 +85,7 @@ build_recipe( name = "recipe:android/avd_packager", + use_python3 = True, ) build_recipe(
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 7ade4e88..27e0b39 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -104,7 +104,7 @@ title = "Fuchsia Sheriff Console", ordering = { "*type*": consoles.ordering(short_names = ["a64", "x64"]), - None: ["ci", "fyi", "misc"], + None: ["ci", "fyi", "astro", "sherlock", "misc"], "chromium.mac": "*type*", "chromium.fyi|13": "*type*", }, @@ -118,10 +118,11 @@ short_name = short_name, ) for name, category, short_name in ( ("fuchsia-fyi-arm64-size", "fyi", "a64-size"), - ("fuchsia-fyi-astro", "fyi", "astro"), + ("fuchsia-fyi-astro", "astro", "gpu"), + ("fuchsia-fyi-sherlock", "sherlock", "gpu"), ("fuchsia-builder-perf-fyi", "fyi", "builder-perf"), - ("fuchsia-perf-fyi", "fyi", "ast-perf"), - ("fuchsia-perf-sherlock-fyi", "fyi", "shk-perf"), + ("fuchsia-perf-fyi", "astro", "perf"), + ("fuchsia-perf-sherlock-fyi", "sherlock", "perf"), ("fuchsia-x64", "ci", "x64-chrome"), )]
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.star b/infra/config/subprojects/chromium/ci/chromium.android.star index 688b5cc..d91a4381 100644 --- a/infra/config/subprojects/chromium/ci/chromium.android.star +++ b/infra/config/subprojects/chromium/ci/chromium.android.star
@@ -509,6 +509,7 @@ ), ) +# TODO(crbug.com/1137474): Update the console view config once on CQ ci.builder( name = "android-11-x86-rel", console_view_entry = consoles.console_view_entry(
diff --git a/infra/config/subprojects/chromium/ci/chromium.clang.star b/infra/config/subprojects/chromium/ci/chromium.clang.star index 68edba1..a1821a7 100644 --- a/infra/config/subprojects/chromium/ci/chromium.clang.star +++ b/infra/config/subprojects/chromium/ci/chromium.clang.star
@@ -359,24 +359,6 @@ ) ci.builder( - name = "ToTWinCFI", - console_view_entry = consoles.console_view_entry( - category = "CFI|Win", - short_name = "x86", - ), - os = os.WINDOWS_ANY, -) - -ci.builder( - name = "ToTWinCFI64", - console_view_entry = consoles.console_view_entry( - category = "CFI|Win", - short_name = "x64", - ), - os = os.WINDOWS_ANY, -) - -ci.builder( name = "ToTWindowsCoverage", console_view_entry = consoles.console_view_entry( category = "ToT Code Coverage",
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 3cec4cb..d6023cdf 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -239,6 +239,24 @@ ) ci.builder( + name = "fuchsia-fyi-x64-wst", + console_view_entry = [ + consoles.console_view_entry( + category = "fuchsia|x64", + short_name = "wst", + ), + consoles.console_view_entry( + branch_selector = branches.MAIN, + console_view = "sheriff.fuchsia", + category = "fyi", + short_name = "wst", + ), + ], + notifies = ["cr-fuchsia"], + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, +) + +ci.builder( name = "lacros-amd64-generic-rel-fyi", console_view_entry = consoles.console_view_entry( category = "lacros", @@ -582,6 +600,7 @@ ci.builder( name = "Comparison Windows", + builderless = True, console_view_entry = consoles.console_view_entry( category = "win", short_name = "re", @@ -626,6 +645,7 @@ os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, reclient_jobs = 400, reclient_instance = rbe_instance.DEFAULT, + reclient_ensure_verified = True, ) # End - Reclient migration, phase 2, block 1 shadow builders @@ -1123,17 +1143,6 @@ ) ci.builder( - name = "Win10 Tests x64 20h2", - console_view_entry = consoles.console_view_entry( - category = "win10|20h2", - ), - goma_backend = None, - main_console_view = None, - os = os.WINDOWS_10, - triggered_by = ["ci/Win x64 Builder"], -) - -ci.builder( name = "win32-arm64-rel", console_view_entry = consoles.console_view_entry( category = "win32|arm64",
diff --git a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star index 653d9cb..89fa9f4 100644 --- a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
@@ -55,89 +55,76 @@ kwargs.setdefault("execution_timeout", ci.DEFAULT_EXECUTION_TIMEOUT) return ci.gpu.windows_builder(name = name, **kwargs) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (NVIDIA Shield TV)", console_view_entry = consoles.console_view_entry( category = "Android|N64|NVDA", short_name = "STV", ), + triggered_by = ["GPU FYI Android arm64 Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (Nexus 5)", console_view_entry = consoles.console_view_entry( category = "Android|L32", short_name = "N5", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (Nexus 5X)", console_view_entry = consoles.console_view_entry( category = "Android|M64|QCOM", short_name = "N5X", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm64 Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (Nexus 9)", console_view_entry = consoles.console_view_entry( category = "Android|M64|NVDA", short_name = "N9", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm64 Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (Pixel 2)", console_view_entry = consoles.console_view_entry( category = "Android|P32|QCOM", short_name = "P2", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI Release (Pixel 4)", console_view_entry = consoles.console_view_entry( category = "Android|R32|QCOM", short_name = "P4", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI SkiaRenderer GL (Nexus 5X)", console_view_entry = consoles.console_view_entry( category = "Android|skgl|M64", short_name = "N5X", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm64 Builder"], ) -ci.gpu.linux_builder( +ci.thin_tester( name = "Android FYI SkiaRenderer Vulkan (Pixel 2)", console_view_entry = consoles.console_view_entry( category = "Android|skv|P32", short_name = "P2", ), - goma_backend = None, - reclient_jobs = rbe_jobs.DEFAULT, - reclient_instance = rbe_instance.DEFAULT, + triggered_by = ["GPU FYI Android arm Builder"], ) ci.gpu.linux_builder( @@ -160,6 +147,28 @@ ) ci.gpu.linux_builder( + name = "GPU FYI Android arm Builder", + console_view_entry = consoles.console_view_entry( + category = "Android|Builder", + short_name = "arm", + ), + goma_backend = None, + reclient_jobs = rbe_jobs.DEFAULT, + reclient_instance = rbe_instance.DEFAULT, +) + +ci.gpu.linux_builder( + name = "GPU FYI Android arm64 Builder", + console_view_entry = consoles.console_view_entry( + category = "Android|Builder", + short_name = "arm64", + ), + goma_backend = None, + reclient_jobs = rbe_jobs.DEFAULT, + reclient_instance = rbe_instance.DEFAULT, +) + +ci.gpu.linux_builder( name = "GPU FYI Lacros x64 Builder", console_view_entry = consoles.console_view_entry( category = "Lacros|Builder", @@ -173,6 +182,9 @@ category = "Linux|Builder", short_name = "rel", ), + goma_backend = None, + reclient_instance = rbe_instance.DEFAULT, + reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI, ) ci.gpu.linux_builder( @@ -181,6 +193,9 @@ category = "Linux|Builder", short_name = "dbg", ), + goma_backend = None, + reclient_instance = rbe_instance.DEFAULT, + reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI, ) ci.gpu.linux_builder(
diff --git a/infra/config/subprojects/chromium/ci/infra.star b/infra/config/subprojects/chromium/ci/infra.star index d3a9bd6..0126162 100644 --- a/infra/config/subprojects/chromium/ci/infra.star +++ b/infra/config/subprojects/chromium/ci/infra.star
@@ -3,7 +3,6 @@ # found in the LICENSE file. """Definitions of builders in the infra builder group.""" -load("//lib/builder_config.star", "builder_config") load("//lib/builders.star", "goma", "os") load("//lib/ci.star", "ci") load("//lib/consoles.star", "consoles") @@ -22,70 +21,3 @@ consoles.console_view( name = "infra", ) - -ci.builder( - name = "linux-bootstrap", - bootstrap = True, - builder_spec = builder_config.builder_spec( - chromium_config = builder_config.chromium_config( - config = "chromium", - apply_configs = ["mb"], - build_config = builder_config.build_config.RELEASE, - target_bits = 64, - ), - gclient_config = builder_config.gclient_config( - config = "chromium", - ), - ), - console_view_entry = consoles.console_view_entry( - category = "bootstrap|linux", - short_name = "bld", - ), - schedule = "triggered", - triggered_by = [], -) - -ci.builder( - name = "linux-bootstrap-tests", - bootstrap = True, - builder_spec = builder_config.builder_spec( - execution_mode = builder_config.execution_mode.TEST, - parent = "ci/linux-bootstrap", - chromium_config = builder_config.chromium_config( - config = "chromium", - apply_configs = ["mb"], - build_config = builder_config.build_config.RELEASE, - target_bits = 64, - ), - gclient_config = builder_config.gclient_config( - config = "chromium", - ), - ), - console_view_entry = consoles.console_view_entry( - category = "bootstrap|linux", - short_name = "tst", - ), -) - -ci.builder( - name = "win-bootstrap", - bootstrap = True, - builderless = True, - console_view_entry = consoles.console_view_entry( - category = "bootstrap|win", - short_name = "bld", - ), - os = os.WINDOWS_10, - schedule = "triggered", - triggered_by = [], -) - -ci.builder( - name = "win-bootstrap-tests", - bootstrap = True, - console_view_entry = consoles.console_view_entry( - category = "bootstrap|win", - short_name = "tst", - ), - triggered_by = ["ci/win-bootstrap"], -)
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index f842f7b..823ee81 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -29,8 +29,18 @@ name = "android-10-arm64-rel", ) -try_.builder( +try_.orchestrator_pair_builders( name = "android-11-x86-rel", + # TODO(crbug.com/1137474): Enable it on branch after running on CQ + #branch_selector = branches.STANDARD_MILESTONE, + main_list_view = "try", + orchestrator_cores = 4, + # TODO(crbug.com/1137474): Enable it 5% experimentally once it works fine + # under orchestrator. + orchestrator_tryjob = None, + compilator_cores = 32, + compilator_goma_jobs = goma.jobs.J300, + compilator_name = "android-11-x86-rel-compilator", ) try_.builder( @@ -367,11 +377,6 @@ ) try_.builder( - name = "android_clang_dbg_recipe", - goma_jobs = goma.jobs.J300, -) - -try_.builder( name = "android_compile_dbg", branch_selector = branches.STANDARD_MILESTONE, builderless = not settings.is_main,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star index c86f82d..0e2e06f 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -58,7 +58,6 @@ try_.builder( name = "chromeos-arm-generic-rel", branch_selector = branches.CROS_LTS_MILESTONE, - bootstrap = True, mirrors = ["ci/chromeos-arm-generic-rel"], builderless = not settings.is_main, main_list_view = "try",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star index dfaf996..2bd0b52 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -305,7 +305,6 @@ try_.orchestrator_pair_builders( name = "linux-rel", - bootstrap = True, branch_selector = branches.STANDARD_MILESTONE, main_list_view = "try", use_clang_coverage = True,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index 5fbb7616..0bc1d49 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -7,7 +7,6 @@ load("//lib/builders.star", "cpu", "goma", "os", "xcode") load("//lib/try.star", "try_") load("//lib/consoles.star", "consoles") -load("//project.star", "settings") try_.defaults.set( builder_group = "tryserver.chromium.mac", @@ -43,25 +42,13 @@ os = os.MAC_DEFAULT, ) -try_.builder( +try_.orchestrator_pair_builders( name = "mac-rel", branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE, - builderless = not settings.is_main, - use_clang_coverage = True, - goma_jobs = goma.jobs.J150, - main_list_view = "try", - os = os.MAC_DEFAULT, - tryjob = try_.job(), -) - -try_.orchestrator_pair_builders( - name = "mac-rel-orchestrator", main_list_view = "try", use_clang_coverage = True, orchestrator_cores = 2, - orchestrator_tryjob = try_.job( - experiment_percentage = 1, - ), + orchestrator_tryjob = try_.job(), compilator_goma_jobs = goma.jobs.J150, os = os.MAC_DEFAULT, compilator_name = "mac-rel-compilator", @@ -77,7 +64,7 @@ compilator_goma_jobs = goma.jobs.J150, os = os.MAC_11, compilator_name = "mac11-arm64-rel-compilator", - # TODO (crbug/1271287): Revert when root issue is fixed + # TODO (crbug.com/1245171): Revert when root issue is fixed compilator_grace_period = 4 * time.minute, )
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star index 56e15f6..6f7b91a 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -101,14 +101,6 @@ ) try_.builder( - name = "win10_chromium_x64_20h2_fyi_rel_ng", - builderless = False, - use_clang_coverage = True, - coverage_test_types = ["unit", "overall"], - os = os.WINDOWS_10_20h2, -) - -try_.builder( name = "win10_chromium_x64_dbg_ng", os = os.WINDOWS_10, ) @@ -129,8 +121,8 @@ compilator_cores = 32, compilator_goma_jobs = goma.jobs.J300, compilator_name = "win10_chromium_x64_rel_ng-compilator", - # TODO (crbug/1271287): Revert when root issue is fixed - compilator_grace_period = 3 * time.minute, + # TODO (crbug.com/1245171): Revert when root issue is fixed + compilator_grace_period = 4 * time.minute, ) try_.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.infra.star b/infra/config/subprojects/chromium/try/tryserver.infra.star index 2f24a27b..74567df 100644 --- a/infra/config/subprojects/chromium/try/tryserver.infra.star +++ b/infra/config/subprojects/chromium/try/tryserver.infra.star
@@ -3,7 +3,7 @@ # found in the LICENSE file. """Definitions of builders in the tryserver.infra builder group.""" -load("//lib/builders.star", "goma", "os") +load("//lib/builders.star", "goma") load("//lib/try.star", "try_") load("//lib/consoles.star", "consoles") @@ -20,20 +20,3 @@ consoles.list_view( name = "tryserver.infra", ) - -try_.builder( - name = "linux-bootstrap", - bootstrap = True, - mirrors = [ - "ci/linux-bootstrap", - "ci/linux-bootstrap-tests", - ], - os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, -) - -try_.builder( - name = "win-bootstrap", - bootstrap = True, - builderless = True, - os = os.WINDOWS_10, -)
diff --git a/infra/config/subprojects/findit/findit.star b/infra/config/subprojects/findit/findit.star index 8a622d5..385c7ba 100644 --- a/infra/config/subprojects/findit/findit.star +++ b/infra/config/subprojects/findit/findit.star
@@ -60,7 +60,6 @@ # longer overridable with Buildbucket V2 builder( name = "findit-rerun", - bootstrap = True, executable = "recipe:findit/chromium/single_revision", goma_backend = goma.backend.RBE_PROD, reclient_instance = rbe_instance.DEFAULT,
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index cb30203..7c887b5 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2129,7 +2129,7 @@ Passwords In Other Apps </message> <message name="IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_CAPTION" desc="The caption label below subtitle of the view that teaches users to turn off iOS auto-fill from Chrome password manager"> - To turn off, open <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph> and go to Passwords. + To turn off, open <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph> and go to AutoFill Passwords. </message> <message name="IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_SHORTENED_STEP_1" desc="Text of the row indicating the first step of shortened instruction of of turning on iOS auto-fill from Chrome password manager [iOS only]"> Open AutoFill Password Settings
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_CAPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_CAPTION.png.sha1 index 6b8e94d..9ffcdaf 100644 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_CAPTION.png.sha1 +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORDS_IN_OTHER_APPS_CAPTION.png.sha1
@@ -1 +1 @@ -a269f5ba85cef7a3ca71afe45b34ff0362e03320 \ No newline at end of file +964c3476f94e91a1ce2619631d1bdee82433ef6f \ No newline at end of file
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.h b/ios/chrome/browser/browser_state/test_chrome_browser_state.h index dbc1b9f..1459165a 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.h +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.h
@@ -79,6 +79,7 @@ // !!!!!!!! WARNING: THIS IS GENERALLY NOT SAFE TO CALL! !!!!!!!! // Creates the history service. + // TODO(crbug.com/1106699): Remove when all callers are migrated. bool CreateHistoryService() WARN_UNUSED_RESULT; // Returns the preferences as a TestingPrefServiceSyncable if possible or
diff --git a/ios/chrome/browser/commerce/BUILD.gn b/ios/chrome/browser/commerce/BUILD.gn index f3f3b2d..f2eb4c3a 100644 --- a/ios/chrome/browser/commerce/BUILD.gn +++ b/ios/chrome/browser/commerce/BUILD.gn
@@ -16,6 +16,7 @@ "//components/prefs:prefs", "//components/unified_consent:unified_consent", "//ios/chrome/browser", + "//ios/chrome/browser:pref_names", "//ios/chrome/browser/browser_state:browser_state", "//ios/chrome/browser/optimization_guide:optimization_guide", "//ios/chrome/browser/signin:signin", @@ -40,6 +41,7 @@ "//components/optimization_guide/core:test_support", "//components/sync_preferences:test_support", "//components/unified_consent:unified_consent", + "//ios/chrome/browser:pref_names", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/optimization_guide:optimization_guide", "//ios/chrome/browser/optimization_guide:unit_tests",
diff --git a/ios/chrome/browser/commerce/price_alert_util.h b/ios/chrome/browser/commerce/price_alert_util.h index 8a8044b0..7da257e 100644 --- a/ios/chrome/browser/commerce/price_alert_util.h +++ b/ios/chrome/browser/commerce/price_alert_util.h
@@ -18,4 +18,9 @@ // Returns true if the flag controlling price alerts is enabled. BOOL IsPriceAlertsEnabled(); +// Returns true if the flag controlling price alerts is enabled and +// the user opt out is enabled. This enables us to experiment with +// different experiences. +BOOL IsPriceAlertsWithOptOutEnabled(); + #endif // IOS_CHROME_BROWSER_COMMERCE_PRICE_ALERT_UTIL_H_
diff --git a/ios/chrome/browser/commerce/price_alert_util.mm b/ios/chrome/browser/commerce/price_alert_util.mm index 22bb387..2fe6815 100644 --- a/ios/chrome/browser/commerce/price_alert_util.mm +++ b/ios/chrome/browser/commerce/price_alert_util.mm
@@ -5,8 +5,9 @@ #import "ios/chrome/browser/commerce/price_alert_util.h" #include "components/prefs/pref_service.h" -#include "components/unified_consent/pref_names.h" +#include "components/unified_consent/url_keyed_data_collection_consent_helper.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" @@ -18,6 +19,7 @@ namespace { const char kPriceTrackingWithOptimizationGuideParam[] = "price_tracking_with_optimization_guide"; +const char kPriceTrackingOptOutParam[] = "price_tracking_opt_out"; } // namespace bool IsPriceAlertsEligible(web::BrowserState* browser_state) { @@ -28,13 +30,16 @@ ChromeBrowserState::FromBrowserState(browser_state); AuthenticationService* authentication_service = AuthenticationServiceFactory::GetForBrowserState(chrome_browser_state); - if (!authentication_service || !authentication_service->HasPrimaryIdentity( - signin::ConsentLevel::kSignin)) { + DCHECK(authentication_service); + if (!authentication_service->HasPrimaryIdentity( + signin::ConsentLevel::kSignin)) { return false; } - const PrefService& prefs = *chrome_browser_state->GetPrefs(); - if (!prefs.GetBoolean( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled)) { + PrefService* pref_service = chrome_browser_state->GetPrefs(); + if (!unified_consent::UrlKeyedDataCollectionConsentHelper:: + NewAnonymizedDataCollectionConsentHelper(pref_service) + ->IsEnabled() || + !pref_service->GetBoolean(prefs::kTrackPricesOnTabsEnabled)) { return false; } return true; @@ -45,3 +50,10 @@ kCommercePriceTracking, kPriceTrackingWithOptimizationGuideParam, /** default_value */ false); } + +bool IsPriceAlertsWithOptOutEnabled() { + return IsPriceAlertsEnabled() && + base::GetFieldTrialParamByFeatureAsBool(kCommercePriceTracking, + kPriceTrackingOptOutParam, + /** default_value */ false); +}
diff --git a/ios/chrome/browser/commerce/price_alert_util_unittest.mm b/ios/chrome/browser/commerce/price_alert_util_unittest.mm index b17b6d6d..16c91c17 100644 --- a/ios/chrome/browser/commerce/price_alert_util_unittest.mm +++ b/ios/chrome/browser/commerce/price_alert_util_unittest.mm
@@ -9,6 +9,7 @@ #include "components/unified_consent/pref_names.h" #include "components/unified_consent/unified_consent_service.h" #import "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" #import "ios/chrome/browser/signin/authentication_service_fake.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" @@ -52,6 +53,11 @@ enabled); } + void SetUserSetting(bool enabled) { + browser_state_->GetPrefs()->SetBoolean(prefs::kTrackPricesOnTabsEnabled, + enabled); + } + void SetFeatureFlag(bool enabled) { if (enabled) { scoped_feature_list_.InitAndEnableFeatureWithParameters( @@ -123,3 +129,19 @@ SetMSBB(true); EXPECT_FALSE(IsPriceAlertsEligible(&fake_browser_state)); } + +TEST_F(PriceAlertUtilTest, TestUserSettingOn) { + SignIn(); + SetFeatureFlag(true); + SetMSBB(true); + SetUserSetting(true); + EXPECT_TRUE(IsPriceAlertsEligible(browser_state_.get())); +} + +TEST_F(PriceAlertUtilTest, TestUserSettingOff) { + SignIn(); + SetFeatureFlag(true); + SetMSBB(true); + SetUserSetting(false); + EXPECT_FALSE(IsPriceAlertsEligible(browser_state_.get())); +}
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 3983830..5aedcce 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -180,12 +180,22 @@ base::size(kAutofillUseMobileLabelDisambiguationShowOne), nullptr}}; const FeatureEntry::FeatureParam kCommercePriceTrackingWithOptimizationGuide[] = - {{"price_tracking_with_optimization_guide", "true"}}; + {{"price_tracking_with_optimization_guide", "true"}, + {"price_tracking_opt_out", "false"}}; + +const FeatureEntry::FeatureParam + kCommercePriceTrackingWithOptimizationGuideAndOptOut[] = { + {"price_tracking_with_optimization_guide", "true"}, + {"price_tracking_opt_out", "true"}}; const FeatureEntry::FeatureVariation kCommercePriceTrackingVariations[] = { {"Price Tracking with Optimization Guide", kCommercePriceTrackingWithOptimizationGuide, - base::size(kCommercePriceTrackingWithOptimizationGuide), nullptr}}; + base::size(kCommercePriceTrackingWithOptimizationGuide), nullptr}, + {"Price Tracking with Optimization Guide and Opt Out", + kCommercePriceTrackingWithOptimizationGuideAndOptOut, + base::size(kCommercePriceTrackingWithOptimizationGuideAndOptOut), + nullptr}}; const FeatureEntry::FeatureParam kDefaultBrowserFullscreenPromoExperimentRemindMeLater[] = {
diff --git a/ios/chrome/browser/history/history_service_factory.cc b/ios/chrome/browser/history/history_service_factory.cc index 8fbd08c1a..cc45ac8 100644 --- a/ios/chrome/browser/history/history_service_factory.cc +++ b/ios/chrome/browser/history/history_service_factory.cc
@@ -22,6 +22,25 @@ namespace ios { +namespace { + +std::unique_ptr<KeyedService> BuildHistoryService(web::BrowserState* context) { + ChromeBrowserState* browser_state = + ChromeBrowserState::FromBrowserState(context); + std::unique_ptr<history::HistoryService> history_service( + new history::HistoryService( + std::make_unique<HistoryClientImpl>( + ios::BookmarkModelFactory::GetForBrowserState(browser_state)), + nullptr)); + if (!history_service->Init(history::HistoryDatabaseParamsForPath( + browser_state->GetStatePath()))) { + return nullptr; + } + return history_service; +} + +} // namespace + // static history::HistoryService* HistoryServiceFactory::GetForBrowserState( ChromeBrowserState* browser_state, @@ -58,6 +77,12 @@ return instance.get(); } +// static +HistoryServiceFactory::TestingFactory +HistoryServiceFactory::GetDefaultFactory() { + return base::BindRepeating(&BuildHistoryService); +} + HistoryServiceFactory::HistoryServiceFactory() : BrowserStateKeyedServiceFactory( "HistoryService", @@ -70,18 +95,7 @@ std::unique_ptr<KeyedService> HistoryServiceFactory::BuildServiceInstanceFor( web::BrowserState* context) const { - ChromeBrowserState* browser_state = - ChromeBrowserState::FromBrowserState(context); - std::unique_ptr<history::HistoryService> history_service( - new history::HistoryService( - std::make_unique<HistoryClientImpl>( - ios::BookmarkModelFactory::GetForBrowserState(browser_state)), - nullptr)); - if (!history_service->Init(history::HistoryDatabaseParamsForPath( - browser_state->GetStatePath()))) { - return nullptr; - } - return history_service; + return BuildHistoryService(context); } web::BrowserState* HistoryServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/history/history_service_factory.h b/ios/chrome/browser/history/history_service_factory.h index 41a7ca7..9799a22 100644 --- a/ios/chrome/browser/history/history_service_factory.h +++ b/ios/chrome/browser/history/history_service_factory.h
@@ -30,6 +30,9 @@ ServiceAccessType access_type); static HistoryServiceFactory* GetInstance(); + // Returns the default factory, useful in tests where it's null by default. + static TestingFactory GetDefaultFactory(); + HistoryServiceFactory(const HistoryServiceFactory&) = delete; HistoryServiceFactory& operator=(const HistoryServiceFactory&) = delete;
diff --git a/ios/chrome/browser/history/history_tab_helper_unittest.mm b/ios/chrome/browser/history/history_tab_helper_unittest.mm index f60c3bd..6093eebde 100644 --- a/ios/chrome/browser/history/history_tab_helper_unittest.mm +++ b/ios/chrome/browser/history/history_tab_helper_unittest.mm
@@ -30,8 +30,10 @@ public: void SetUp() override { TestChromeBrowserState::Builder test_cbs_builder; + test_cbs_builder.AddTestingFactory( + ios::HistoryServiceFactory::GetInstance(), + ios::HistoryServiceFactory::GetDefaultFactory()); chrome_browser_state_ = test_cbs_builder.Build(); - ASSERT_TRUE(chrome_browser_state_->CreateHistoryService()); web_state_.SetBrowserState(chrome_browser_state_.get()); HistoryTabHelper::CreateForWebState(&web_state_);
diff --git a/ios/chrome/browser/link_to_text/link_to_text_tab_helper.mm b/ios/chrome/browser/link_to_text/link_to_text_tab_helper.mm index 74b53ff..19bf4bb 100644 --- a/ios/chrome/browser/link_to_text/link_to_text_tab_helper.mm +++ b/ios/chrome/browser/link_to_text/link_to_text_tab_helper.mm
@@ -41,6 +41,7 @@ enum class ShouldOfferResult { kSuccess = 0, kBlockListed = 2, + kUnableToInvokeJavaScript = 3, kSelectionEmpty = 6, kUserEditing = 7, kTextInputNotFound = 8, @@ -48,7 +49,6 @@ // Deprecated. Do not reuse, change, or remove these values. kRejectedInJavaScript = 1, - kUnableToInvokeJavaScript = 3, kWebLayerTaskTimeout = 4, kDispatchedTimeout = 5,
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc index 3ba0fc8..8f91ae2 100644 --- a/ios/chrome/browser/pref_names.cc +++ b/ios/chrome/browser/pref_names.cc
@@ -106,6 +106,10 @@ // Boolean that is true when Suggest support is enabled. const char kSearchSuggestEnabled[] = "search.suggest_enabled"; +// Boolean indicating if displaying price drops for shopping URLs on Tabs +// in the Tab Switching UI is enabled. +const char kTrackPricesOnTabsEnabled[] = "track_prices_on_tabs.enabled"; + // An integer set to one of the NetworkPredictionSetting enum values indicating // network prediction settings. const char kNetworkPredictionSetting[] =
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index 4c20c50..9ad430f 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -33,6 +33,7 @@ extern const char kNTPContentSuggestionsEnabled[]; extern const char kPrintingEnabled[]; extern const char kSearchSuggestEnabled[]; +extern const char kTrackPricesOnTabsEnabled[]; extern const char kNetworkPredictionSetting[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 0589690..9a0f24a5 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -253,6 +253,10 @@ registry->RegisterBooleanPref( translate::prefs::kOfferTranslateEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kTrackPricesOnTabsEnabled, true, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterStringPref(prefs::kDefaultCharset, l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index c535725..9324b4e8 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -216,6 +216,7 @@ ":signin_presenter", "//base", "//base/test:test_support", + "//components/signin/public/base", "//ios/chrome/app/strings", "//ios/chrome/browser/ui/authentication/cells:constants", "//ios/chrome/browser/ui/authentication/signin:constants",
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey.h b/ios/chrome/browser/ui/authentication/signin_earl_grey.h index 30a78776..fcd58754 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey.h +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey.h
@@ -13,6 +13,10 @@ @protocol GREYMatcher; @class FakeChromeIdentity; +namespace signin { +enum class ConsentLevel; +} + #define SigninEarlGrey \ [SigninEarlGreyImpl invokedFromFile:@"" __FILE__ lineNumber:__LINE__] @@ -48,6 +52,10 @@ // profile. - (void)verifySignedInWithFakeIdentity:(FakeChromeIdentity*)fakeIdentity; +// Induces a GREYAssert if the user is not signed in with |expectedEmail|. +- (void)verifyPrimaryAccountWithEmail:(NSString*)expectedEmail + consent:(signin::ConsentLevel)consent; + // Induces a GREYAssert if an identity is signed in. - (void)verifySignedOut;
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey.mm index fc5599e..0d9d1508 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey.mm +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" #import "base/test/ios/wait_util.h" +#import "components/signin/public/base/consent_level.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h" #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h" #include "ios/chrome/grit/ios_strings.h" @@ -79,6 +80,34 @@ [fakeIdentity.gaiaID isEqualToString:primaryAccountGaiaID], errorStr); } +- (void)verifyPrimaryAccountWithEmail:(NSString*)expectedEmail + consent:(signin::ConsentLevel)consent { + EG_TEST_HELPER_ASSERT_TRUE(expectedEmail.length, @"Need to give an identity"); + + // Required to avoid any problem since the following test is not dependant + // to UI, and the previous action has to be totally finished before going + // through the assert. + GREYAssert(WaitUntilConditionOrTimeout( + base::test::ios::kWaitForActionTimeout, + ^bool { + NSString* primaryAccountEmail = [SigninEarlGreyAppInterface + primaryAccountEmailWithConsent:consent]; + return primaryAccountEmail.length > 0; + }), + @"Sign in did not complete."); + GREYWaitForAppToIdle(@"App failed to idle"); + + NSString* primaryAccountEmail = + [SigninEarlGreyAppInterface primaryAccountEmailWithConsent:consent]; + + NSString* errorStr = [NSString + stringWithFormat:@"Unexpected email of the signed in user [expected = " + @"\"%@\", actual = \"%@\", consent %d]", + expectedEmail, primaryAccountEmail, consent]; + EG_TEST_HELPER_ASSERT_TRUE( + [expectedEmail isEqualToString:primaryAccountEmail], errorStr); +} + - (void)verifySignedOut { // Required to avoid any problem since the following test is not dependant to // UI, and the previous action has to be totally finished before going through
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h b/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h index 57157ee..3722374 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h
@@ -10,6 +10,10 @@ @class FakeChromeIdentity; @protocol GREYMatcher; +namespace signin { +enum class ConsentLevel; +} + // SigninEarlGreyAppInterface contains the app-side implementation for // helpers that primarily work via direct model access. These helpers are // compiled into the app binary and can be called from either app or test code. @@ -40,9 +44,9 @@ // If there is no signed-in account returns an empty string. + (NSString*)primaryAccountGaiaID; -// Returns the email of the signed-in account. +// Returns the email of the primary account base on |consentLevel|. // If there is no signed-in account returns an empty string. -+ (NSString*)primaryAccountEmail; ++ (NSString*)primaryAccountEmailWithConsent:(signin::ConsentLevel)consentLevel; // Checks that no identity is signed in. + (BOOL)isSignedOut;
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.mm index 957586c..73fa9f9 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.mm +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.mm
@@ -78,12 +78,12 @@ return base::SysUTF8ToNSString(info.gaia); } -+ (NSString*)primaryAccountEmail { ++ (NSString*)primaryAccountEmailWithConsent:(signin::ConsentLevel)consentLevel { ChromeBrowserState* browserState = chrome_test_util::GetOriginalBrowserState(); CoreAccountInfo info = IdentityManagerFactory::GetForBrowserState(browserState) - ->GetPrimaryAccountInfo(signin::ConsentLevel::kSync); + ->GetPrimaryAccountInfo(consentLevel); return base::SysUTF8ToNSString(info.email); }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn index 093950b61..ec92581 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -53,6 +53,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/favicon", "//ios/chrome/browser/main", + "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/passwords", "//ios/chrome/browser/sync", "//ios/chrome/browser/ui:feature_flags", @@ -123,6 +124,7 @@ "//ios/chrome/browser", "//ios/chrome/browser/autofill/manual_fill:manual_fill", "//ios/chrome/browser/favicon", + "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/autofill/manual_fill/resources:mf_keyboard", "//ios/chrome/browser/ui/list_model:list_model",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_mediator.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_mediator.mm index 1976229..fc77bcc 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_mediator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_mediator.mm
@@ -17,6 +17,7 @@ #import "components/password_manager/ios/password_generation_provider.h" #import "ios/chrome/browser/autofill/manual_fill/passwords_fetcher.h" #import "ios/chrome/browser/favicon/favicon_loader.h" +#import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/passwords/password_tab_helper.h" #import "ios/chrome/browser/sync/sync_setup_service.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_action_cell.h" @@ -332,10 +333,10 @@ #pragma mark - TableViewFaviconDataSource -- (void)faviconForURL:(const GURL&)URL +- (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { DCHECK(completion); - self.faviconLoader->FaviconForPageUrlOrHost(URL, gfx::kFaviconSize, + self.faviconLoader->FaviconForPageUrlOrHost(URL.gurl, gfx::kFaviconSize, completion); }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm index 56686a9..53c92b6 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm
@@ -8,6 +8,7 @@ #include "base/mac/foundation_util.h" #include "base/metrics/histogram_macros.h" #include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_action_cell.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.h" @@ -193,8 +194,9 @@ base::mac::ObjCCastStrict<ManualFillPasswordCell>(cell); NSString* itemIdentifier = passwordItem.uniqueIdentifier; + CrURL* crurl = [[CrURL alloc] initWithGURL:passwordItem.faviconURL]; [self.imageDataSource - faviconForURL:passwordItem.faviconURL + faviconForURL:crurl completion:^(FaviconAttributes* attributes) { // Only set favicon if the cell hasn't been reused. if ([passwordCell.uniqueIdentifier isEqualToString:itemIdentifier]) {
diff --git a/ios/chrome/browser/ui/history/history_mediator.mm b/ios/chrome/browser/ui/history/history_mediator.mm index a2ee1a4..70b0613 100644 --- a/ios/chrome/browser/ui/history/history_mediator.mm +++ b/ios/chrome/browser/ui/history/history_mediator.mm
@@ -6,6 +6,7 @@ #import "ios/chrome/browser/favicon/favicon_loader.h" #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h" +#import "ios/chrome/browser/net/crurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -40,10 +41,10 @@ #pragma mark - TableViewFaviconDataSource -- (void)faviconForURL:(const GURL&)URL +- (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { self.faviconLoader->FaviconForPageUrl( - URL, kFaviconWidthHeight, kFaviconMinWidthHeight, + URL.gurl, kFaviconWidthHeight, kFaviconMinWidthHeight, /*fallback_to_google_server=*/false, ^(FaviconAttributes* attributes) { completion(attributes); });
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm index d5c1083..d81e9f3b 100644 --- a/ios/chrome/browser/ui/history/history_table_view_controller.mm +++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -664,8 +664,9 @@ base::mac::ObjCCastStrict<HistoryEntryItem>(item); TableViewURLCell* URLCell = base::mac::ObjCCastStrict<TableViewURLCell>(cellToReturn); + CrURL* crurl = [[CrURL alloc] initWithGURL:URLItem.URL]; [self.imageDataSource - faviconForURL:URLItem.URL + faviconForURL:crurl completion:^(FaviconAttributes* attributes) { // Only set favicon if the cell hasn't been reused. if ([URLCell.cellUniqueIdentifier
diff --git a/ios/chrome/browser/ui/infobars/modals/BUILD.gn b/ios/chrome/browser/ui/infobars/modals/BUILD.gn index ff25df6..d461945 100644 --- a/ios/chrome/browser/ui/infobars/modals/BUILD.gn +++ b/ios/chrome/browser/ui/infobars/modals/BUILD.gn
@@ -35,6 +35,7 @@ "//components/translate/core/browser", "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/infobars:public", + "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/passwords:public", "//ios/chrome/browser/ui/autofill:autofill_message", "//ios/chrome/browser/ui/autofill:autofill_metrics",
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm index 2b3e608..cffe6e0 100644 --- a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm
@@ -10,6 +10,7 @@ #include "base/metrics/user_metrics_action.h" #import "components/autofill/core/common/autofill_features.h" #include "ios/chrome/browser/infobars/infobar_metrics_recorder.h" +#import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/autofill/cells/target_account_item.h" #import "ios/chrome/browser/ui/autofill/save_card_infobar_metrics_recorder.h" #import "ios/chrome/browser/ui/autofill/save_card_message_with_links.h" @@ -330,8 +331,8 @@ for (SaveCardMessageWithLinks* message in self.legalMessages) { [message.linkRanges enumerateObjectsUsingBlock:^( NSValue* rangeValue, NSUInteger i, BOOL* stop) { - [linkCell setLinkURL:message.linkURLs[i] - forRange:rangeValue.rangeValue]; + CrURL* crurl = [[CrURL alloc] initWithGURL:message.linkURLs[i]]; + [linkCell setLinkURL:crurl forRange:rangeValue.rangeValue]; }]; } linkCell.delegate = self; @@ -374,8 +375,8 @@ #pragma mark - TableViewTextLinkCellDelegate - (void)tableViewTextLinkCell:(TableViewTextLinkCell*)cell - didRequestOpenURL:(const GURL&)URL { - [self.saveCardModalDelegate dismissModalAndOpenURL:URL]; + didRequestOpenURL:(CrURL*)URL { + [self.saveCardModalDelegate dismissModalAndOpenURL:URL.gurl]; } #pragma mark - Private Methods
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn index 9904074..b0cbfdf 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -22,7 +22,10 @@ configs += [ "//build/config/compiler:enable_arc" ] - deps = [ "//base" ] + deps = [ + "//base", + "//ios/chrome/browser/ui/infobars:constants", + ] } source_set("coordinators") {
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm index eb167d96..cef7440a 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm
@@ -3,6 +3,7 @@ // found in the LICENSE file. #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h" +#import "ios/chrome/browser/ui/infobars/infobar_constants.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -25,11 +26,13 @@ return base::GetFieldTrialParamByFeatureAsDouble( kEnableLongMessageDuration, kDefaultPresentationMessagesDurationFeatureParam, - 15 /*default to 15 second*/); + kInfobarBannerDefaultPresentationDurationInSeconds + /*default to banner's default duration*/); } double GetLongPresentationMessageDuration() { return base::GetFieldTrialParamByFeatureAsDouble( kEnableLongMessageDuration, kLongPresentationMessagesDurationFeatureParam, - 20 /*default to 20 second*/); + kInfobarBannerLongPresentationDurationInSeconds + /*default to banner's long duration*/); }
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index e395284..e23792bf 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -27,6 +27,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/favicon", "//ios/chrome/browser/main", + "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/sessions", "//ios/chrome/browser/signin", "//ios/chrome/browser/sync", @@ -83,6 +84,7 @@ "//ios/chrome/browser/drag_and_drop", "//ios/chrome/browser/main:public", "//ios/chrome/browser/metrics:metrics_internal", + "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/sessions", "//ios/chrome/browser/sessions:serialisation", "//ios/chrome/browser/signin",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm index 7c0f1909..2574fdd 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm
@@ -11,6 +11,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/favicon/favicon_loader.h" #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h" +#import "ios/chrome/browser/net/crurl.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" #include "ios/chrome/browser/sync/session_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service.h" @@ -162,12 +163,12 @@ #pragma mark - TableViewFaviconDataSource -- (void)faviconForURL:(const GURL&)URL +- (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { FaviconLoader* faviconLoader = IOSChromeFaviconLoaderFactory::GetForBrowserState(self.browserState); faviconLoader->FaviconForPageUrl( - URL, kFaviconWidthHeight, kFaviconMinWidthHeight, + URL.gurl, kFaviconWidthHeight, kFaviconMinWidthHeight, /*fallback_to_google_server=*/false, ^(FaviconAttributes* attributes) { completion(attributes); });
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 8c47f86..44de30c6 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -23,6 +23,7 @@ #import "ios/chrome/browser/drag_and_drop/table_view_url_drag_drop_handler.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" +#import "ios/chrome/browser/net/crurl.h" #include "ios/chrome/browser/sessions/live_tab_context_browser_agent.h" #include "ios/chrome/browser/sessions/session_util.h" #include "ios/chrome/browser/signin/authentication_service_factory.h" @@ -1026,8 +1027,9 @@ TableViewURLCell* URLCell = base::mac::ObjCCastStrict<TableViewURLCell>(cell); NSString* itemIdentifier = URLItem.uniqueIdentifier; + CrURL* crurl = [[CrURL alloc] initWithGURL:URLItem.URL]; [self.imageDataSource - faviconForURL:URLItem.URL + faviconForURL:crurl completion:^(FaviconAttributes* attributes) { // Only set favicon if the cell hasn't been reused. if ([URLCell.cellUniqueIdentifier isEqualToString:itemIdentifier]) {
diff --git a/ios/chrome/browser/ui/settings/google_services/BUILD.gn b/ios/chrome/browser/ui/settings/google_services/BUILD.gn index 14fda12d6..815a07cb 100644 --- a/ios/chrome/browser/ui/settings/google_services/BUILD.gn +++ b/ios/chrome/browser/ui/settings/google_services/BUILD.gn
@@ -49,6 +49,7 @@ "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/commerce:commerce", "//ios/chrome/browser/main:public", "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/policy:policy_util",
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index fbbd0ba..2afa276 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -16,6 +16,7 @@ #include "components/sync/driver/sync_service.h" #include "components/unified_consent/pref_names.h" #include "ios/chrome/browser/application_context.h" +#import "ios/chrome/browser/commerce/price_alert_util.h" #import "ios/chrome/browser/policy/policy_util.h" #include "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/signin/authentication_service.h" @@ -56,6 +57,8 @@ NSString* const kBetterSearchAndBrowsingItemAccessibilityID = @"betterSearchAndBrowsingItem_switch"; +NSString* const kTrackPricesOnTabsItemAccessibilityID = + @"trackPricesOnTabsItem_switch"; // List of sections. typedef NS_ENUM(NSInteger, SectionIdentifier) { @@ -78,6 +81,7 @@ BetterSearchAndBrowsingItemType, BetterSearchAndBrowsingManagedItemType, PasswordLeakCheckSwitchItemType, + TrackPricesOnTabsItemType, }; // TODO(crbug.com/1244632): Use the Authentication Service sign-in status API @@ -170,6 +174,11 @@ // Account manager service to retrieve Chrome identities. @property(nonatomic, assign) ChromeAccountManagerService* accountManagerService; +// Preference value for displaying price drop annotations on Tabs for shopping +// URLs in the Tab Switching UI as price drops are identified. +@property(nonatomic, strong, readonly) + PrefBackedBoolean* trackPricesOnTabsPreference; + @end @implementation GoogleServicesSettingsMediator @@ -212,6 +221,10 @@ prefName:unified_consent::prefs:: kUrlKeyedAnonymizedDataCollectionEnabled]; _anonymizedDataCollectionPreference.observer = self; + _trackPricesOnTabsPreference = [[PrefBackedBoolean alloc] + initWithPrefService:userPrefService + prefName:prefs::kTrackPricesOnTabsEnabled]; + _trackPricesOnTabsPreference.observer = self; _accountManagerService = accountManagerService; } return self; @@ -224,13 +237,12 @@ textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_TEXT detailStringID: - IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_DETAIL - dataType:0]; + IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_DETAIL]; } // Disables "Allow Chrome Sign-in" switch with a disclosure that the // setting has been disabled by the organization. return [self - TableViewInfoButtonItemType:AllowChromeSigninItemType + tableViewInfoButtonItemType:AllowChromeSigninItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_TEXT detailStringID: @@ -312,6 +324,10 @@ case PasswordLeakCheckSwitchItemType: [self updateLeakCheckItem]; break; + case TrackPricesOnTabsItemType: + base::mac::ObjCCast<SyncSwitchItem>(item).on = + self.trackPricesOnTabsPreference.value; + break; } } if (notifyConsumer) { @@ -341,7 +357,7 @@ if (self.userPrefService->IsManagedPreference( prefs::kSearchSuggestEnabled)) { TableViewInfoButtonItem* autocompleteItem = [self - TableViewInfoButtonItemType:AutocompleteSearchesAndURLsManagedItemType + tableViewInfoButtonItemType:AutocompleteSearchesAndURLsManagedItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_TEXT detailStringID: @@ -355,14 +371,13 @@ textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_TEXT detailStringID: - IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_DETAIL - dataType:0]; + IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_DETAIL]; [items addObject:autocompleteItem]; } if (self.userPrefService->IsManagedPreference( prefs::kSafeBrowsingEnabled)) { TableViewInfoButtonItem* safeBrowsingManagedItem = [self - TableViewInfoButtonItemType:AutocompleteSearchesAndURLsManagedItemType + tableViewInfoButtonItemType:AutocompleteSearchesAndURLsManagedItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_TEXT detailStringID: @@ -376,8 +391,7 @@ textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_TEXT detailStringID: - IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_DETAIL - dataType:0]; + IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_DETAIL]; safeBrowsingItem.accessibilityIdentifier = kSafeBrowsingItemAccessibilityIdentifier; [items addObject:safeBrowsingItem]; @@ -386,7 +400,7 @@ if (self.localPrefService->IsManagedPreference( metrics::prefs::kMetricsReportingEnabled)) { TableViewInfoButtonItem* improveChromeItem = [self - TableViewInfoButtonItemType:ImproveChromeManagedItemType + tableViewInfoButtonItemType:ImproveChromeManagedItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT detailStringID: @@ -400,14 +414,13 @@ textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT detailStringID: - IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_DETAIL - dataType:0]; + IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_DETAIL]; [items addObject:improveChromeItem]; } if (self.userPrefService->IsManagedPreference( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled)) { TableViewInfoButtonItem* betterSearchAndBrowsingItem = [self - TableViewInfoButtonItemType:BetterSearchAndBrowsingManagedItemType + tableViewInfoButtonItemType:BetterSearchAndBrowsingManagedItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_TEXT detailStringID: @@ -423,12 +436,33 @@ textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_TEXT detailStringID: - IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_DETAIL - dataType:0]; + IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_DETAIL]; betterSearchAndBrowsingItem.accessibilityIdentifier = kBetterSearchAndBrowsingItemAccessibilityID; [items addObject:betterSearchAndBrowsingItem]; } + if (IsPriceAlertsWithOptOutEnabled()) { + if (self.userPrefService->IsManagedPreference( + prefs::kTrackPricesOnTabsEnabled)) { + TableViewInfoButtonItem* trackPricesOnTabsItem = [self + tableViewInfoButtonItemType:TrackPricesOnTabsItemType + textStringID:IDS_IOS_TRACK_PRICES_ON_TABS + detailStringID:IDS_IOS_TRACK_PRICES_ON_TABS_DESCRIPTION + status:self.trackPricesOnTabsPreference + controllable:self.trackPricesOnTabsPreference]; + trackPricesOnTabsItem.accessibilityIdentifier = + kTrackPricesOnTabsItemAccessibilityID; + [items addObject:trackPricesOnTabsItem]; + } else { + SyncSwitchItem* trackPricesOnTabsItem = [self + switchItemWithItemType:TrackPricesOnTabsItemType + textStringID:IDS_IOS_TRACK_PRICES_ON_TABS + detailStringID:IDS_IOS_TRACK_PRICES_ON_TABS_DESCRIPTION]; + trackPricesOnTabsItem.accessibilityIdentifier = + kTrackPricesOnTabsItemAccessibilityID; + [items addObject:trackPricesOnTabsItem]; + } + } _nonPersonalizedItems = items; } @@ -452,21 +486,20 @@ #pragma mark - Private -// Creates a SyncSwitchItem instance. +// Creates an item with a switch toggle. - (SyncSwitchItem*)switchItemWithItemType:(NSInteger)itemType textStringID:(int)textStringID - detailStringID:(int)detailStringID - dataType:(NSInteger)dataType { + detailStringID:(int)detailStringID { SyncSwitchItem* switchItem = [[SyncSwitchItem alloc] initWithType:itemType]; switchItem.text = GetNSString(textStringID); if (detailStringID) switchItem.detailText = GetNSString(detailStringID); - switchItem.dataType = dataType; return switchItem; } -// Create a TableViewInfoButtonItem instance. -- (TableViewInfoButtonItem*)TableViewInfoButtonItemType:(NSInteger)itemType +// Create a TableViewInfoButtonItem instance used for items that the user is +// not allowed to switch on or off (enterprise reason for example). +- (TableViewInfoButtonItem*)tableViewInfoButtonItemType:(NSInteger)itemType textStringID:(int)textStringID detailStringID:(int)detailStringID status:(BOOL)status @@ -599,6 +632,9 @@ // Update the item. [self updateLeakCheckItem]; break; + case TrackPricesOnTabsItemType: + self.trackPricesOnTabsPreference.value = value; + break; case AutocompleteSearchesAndURLsManagedItemType: case SafeBrowsingManagedItemType: case BetterSearchAndBrowsingManagedItemType:
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_egtest.mm index a32a7a5a..bc430ec3 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_egtest.mm
@@ -58,7 +58,7 @@ // Matcher for turn off instructions. id<GREYMatcher> PasswordsInOtherAppsTurnOffInstruction() { NSString* turnOffInstructionText = - @"To turn off, open Settings and go to Passwords."; + @"To turn off, open Settings and go to AutoFill Passwords."; return grey_text(turnOffInstructionText); }
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm index 108a1bb9..3599150f 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm
@@ -248,7 +248,7 @@ imageHeightConstraint.active = YES; } -- (void)viewWillDisappear:(BOOL)animated { +- (void)viewDidDisappear:(BOOL)animated { if (self.navigationBar) { self.navigationItem.rightBarButtonItem = nil; [self.navigationBar setBackgroundImage:nil
diff --git a/ios/chrome/browser/ui/settings/resources/BUILD.gn b/ios/chrome/browser/ui/settings/resources/BUILD.gn index 15df4a9f..8dbd4864 100644 --- a/ios/chrome/browser/ui/settings/resources/BUILD.gn +++ b/ios/chrome/browser/ui/settings/resources/BUILD.gn
@@ -127,8 +127,6 @@ "settings_passwords.imageset/Contents.json", "settings_passwords.imageset/settings_passwords@2x.png", "settings_passwords.imageset/settings_passwords@3x.png", - "settings_passwords.imageset/settings_passwords_dark@2x.png", - "settings_passwords.imageset/settings_passwords_dark@3x.png", ] }
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json index 60d77c0..ac1d571 100644 --- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json +++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json
@@ -9,28 +9,6 @@ "idiom" : "universal", "filename" : "settings_passwords@3x.png", "scale" : "3x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "filename" : "settings_passwords_dark@2x.png", - "scale" : "2x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "filename" : "settings_passwords_dark@3x.png", - "scale" : "3x" } ], "info" : {
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png deleted file mode 100644 index 2d16bd3e..0000000 --- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png deleted file mode 100644 index 3f2824cf..0000000 --- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.h index 12b1988..2098c42 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.h
@@ -10,14 +10,14 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_cell.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" -class GURL; +@class CrURL; @class TableViewTextLinkCell; // Delegate for TableViewTextLinkCell. @protocol TableViewTextLinkCellDelegate<NSObject> // Notifies the delegate that |URL| should be opened. - (void)tableViewTextLinkCell:(TableViewTextLinkCell*)cell - didRequestOpenURL:(const GURL&)URL; + didRequestOpenURL:(CrURL*)URL; @end // TableViewTextLinkItem contains the model data for a TableViewTextLinkCell. @@ -25,7 +25,7 @@ // Text being stored by this item. @property(nonatomic, readwrite, strong) NSString* text; // URL link being stored by this item. If empty or not valid no URL will be set. -@property(nonatomic, assign) GURL linkURL; +@property(nonatomic, readwrite, strong) CrURL* linkURL; @end // TableViewCell that displays a text label that might contain a link. @@ -37,9 +37,9 @@ @property(nonatomic, weak) id<TableViewTextLinkCellDelegate> delegate; // Sets the |URL| link on the cell's label if the corresponding item's |linkURL| // is valid and |textLabel| contains the proper LINK delimiters. -- (void)setLinkURL:(const GURL&)URL; +- (void)setLinkURL:(CrURL*)URL; // Sets the |URL| link on the cell's label for |range|. -- (void)setLinkURL:(const GURL&)URL forRange:(NSRange)range; +- (void)setLinkURL:(CrURL*)URL forRange:(NSRange)range; @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm index f8d892b..0577827 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm
@@ -6,13 +6,12 @@ #include "base/ios/ns_range.h" #include "base/mac/foundation_util.h" +#import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/string_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" -#import "net/base/mac/url_conversions.h" -#include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -39,7 +38,7 @@ base::mac::ObjCCastStrict<TableViewTextLinkCell>(tableCell); cell.textView.text = self.text; cell.selectionStyle = UITableViewCellSelectionStyleNone; - if (!self.linkURL.is_empty()) + if (self.linkURL && !self.linkURL.gurl.is_empty()) [cell setLinkURL:self.linkURL]; } @@ -90,8 +89,10 @@ return self; } -- (void)setLinkURL:(const GURL&)URL { - if (URL.is_valid()) { +- (void)setLinkURL:(CrURL*)URL { + if (!URL) + return; + if (URL.gurl.is_valid()) { UITextView* textView = self.textView; DCHECK(textView.text.length > 0); // Attribute form of the font/color given to the text view on init. @@ -102,8 +103,10 @@ } } -- (void)setLinkURL:(const GURL&)URL forRange:(NSRange)range { - if (URL.is_valid()) { +- (void)setLinkURL:(CrURL*)URL forRange:(NSRange)range { + if (!URL) + return; + if (URL.gurl.is_valid()) { NSMutableAttributedString* text = [[NSMutableAttributedString alloc] initWithAttributedString:self.textView.attributedText]; [text addAttributes:[self linkAttributesForURL:URL] range:range]; @@ -111,9 +114,8 @@ } } -- (NSDictionary<NSAttributedStringKey, id>*)linkAttributesForURL: - (const GURL&)URL { - NSURL* linkURL = net::NSURLWithGURL(URL); +- (NSDictionary<NSAttributedStringKey, id>*)linkAttributesForURL:(CrURL*)URL { + NSURL* linkURL = URL.nsurl; return @{ NSForegroundColorAttributeName : [UIColor colorNamed:kBlueColor], NSLinkAttributeName : linkURL, @@ -131,8 +133,8 @@ interaction:(UITextItemInteraction)interaction { DCHECK(self.textView == textView); DCHECK(URL); - [self.delegate tableViewTextLinkCell:self - didRequestOpenURL:net::GURLWithNSURL(URL)]; + CrURL* crurl = [[CrURL alloc] initWithNSURL:URL]; + [self.delegate tableViewTextLinkCell:self didRequestOpenURL:crurl]; // Returns NO as the app is handling the opening of the URL. return NO; }
diff --git a/ios/chrome/browser/ui/table_view/table_view_favicon_data_source.h b/ios/chrome/browser/ui/table_view/table_view_favicon_data_source.h index 4cc2d46..b35d27f 100644 --- a/ios/chrome/browser/ui/table_view/table_view_favicon_data_source.h +++ b/ios/chrome/browser/ui/table_view/table_view_favicon_data_source.h
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> -class GURL; +@class CrURL; @class FaviconAttributes; // Protocol that Tableview UI uses to retrieve favicons for its cells. @@ -19,7 +19,7 @@ // returned synchronously and the actual favicon returned asynchronously. In // another example, the image returned synchronously may be the actual favicon, // so there is no need to call the completion block. -- (void)faviconForURL:(const GURL&)URL +- (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion; @end
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 9c7b72a..4455ce1 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -33c774d1165dfbe1e1f1ffba538be3d028a30d98 \ No newline at end of file +ab61b1584b8ee40ccdabb7052f78a80478fd74a8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index ece602e..562a3b69 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -a2f6b3b7472b69323095e44d4677508daeb087e3 \ No newline at end of file +e050f90827d2a8f7bcf16b1d5ade39f7b0b0b66d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 631a9e54..faf582e 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -a82c92ed6c29981919bc8a820ae86a4cd7bc03b4 \ No newline at end of file +deb34b8fe0369bfa165a63e415a5f9d4b192f1fd \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 4cb689d..37b93d0 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -f4e9855e45a9cf6fb9f621d56cb39024be0956f6 \ No newline at end of file +d361175787737ff39daf72a7cc676d4e1890b0d4 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index bde9df6..dbd546b 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -260246487f5beafc875a78a50e3e7fa7c7a33bfa \ No newline at end of file +08b127fa5490eb3d8bf87ccc41cdb1f225056de0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index 53542f4..58a4670 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b4b369562bd3188468d275ec116ce8514deb581f \ No newline at end of file +c4a1f75d5014e3a2851452ae9655a249643ffd43 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index fa31d75..a3c2767f 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -4d3c89b3a390e98862b516bde26b2bd211191a02 \ No newline at end of file +933a1346fa66d65e050f6ab44780459bdc6e8f0a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 8a63527a..389a3b1 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -4c7c08ced5babeff7798e6605f3d6afecc9ff79b \ No newline at end of file +073582da92383173b91571e0ec7f835dc4a4a9cc \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index a2e116e3..d91335ed 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -6e378836f0fc8e51d3ec4e00dc6456a0c2a9f41f \ No newline at end of file +47409fdf53f95a41c81c4a988ff8cb77c6cc15a0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index e218df1..312682d 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -2023831c08b9a748916059604e49033cee44aaee \ No newline at end of file +eb9a5df504043e4ff28cec69702c10914e9007c6 \ No newline at end of file
diff --git a/ios/web/common/features.h b/ios/web/common/features.h index 23449f4..b1251721 100644 --- a/ios/web/common/features.h +++ b/ios/web/common/features.h
@@ -90,6 +90,10 @@ // When true, the new download API should be used. bool IsNewDownloadAPIEnabled(); +// When true, user control for camera and/or microphone access should be +// enabled. +bool IsMediaPermissionsControlEnabled(); + } // namespace features } // namespace web
diff --git a/ios/web/common/features.mm b/ios/web/common/features.mm index 0f773ac..39a7fb98 100644 --- a/ios/web/common/features.mm +++ b/ios/web/common/features.mm
@@ -86,5 +86,12 @@ return false; } +bool IsMediaPermissionsControlEnabled() { + if (@available(iOS 15, *)) { + return base::FeatureList::IsEnabled(kMediaPermissionsControl); + } + return false; +} + } // namespace features } // namespace web
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn index 2ef525c4..3fe5f734 100644 --- a/ios/web/public/BUILD.gn +++ b/ios/web/public/BUILD.gn
@@ -9,6 +9,7 @@ ":web_state_observer", "//ios/web/public/favicon", "//ios/web/public/navigation", + "//ios/web/public/permissions", "//ios/web/public/thread", "//ios/web/public/ui", "//net",
diff --git a/ios/web/public/permissions/BUILD.gn b/ios/web/public/permissions/BUILD.gn new file mode 100644 index 0000000..a76da51 --- /dev/null +++ b/ios/web/public/permissions/BUILD.gn
@@ -0,0 +1,8 @@ +# 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("permissions") { + sources = [ "permissions.h" ] + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/ios/web/public/permissions/README.md b/ios/web/public/permissions/README.md new file mode 100644 index 0000000..cb5ced44 --- /dev/null +++ b/ios/web/public/permissions/README.md
@@ -0,0 +1,3 @@ +This directory contains two enums: + - Permission specifies different data or device hardwares that the app/site needs access permissions to; currently we have camera and microphone. + - PermissionState specifies whether the user has granted the site permission to use a certain type of permission.
diff --git a/ios/web/public/permissions/permissions.h b/ios/web/public/permissions/permissions.h new file mode 100644 index 0000000..5fe99fc --- /dev/null +++ b/ios/web/public/permissions/permissions.h
@@ -0,0 +1,33 @@ +// 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 IOS_WEB_PUBLIC_PERMISSIONS_PERMISSIONS_H_ +#define IOS_WEB_PUBLIC_PERMISSIONS_PERMISSIONS_H_ + +namespace web { + +// Enum specifying different data or device hardwares that the app/site needs +// access permissions to. +enum class Permission { + CAMERA = 0, + MICROPHONE = 1, +}; + +// Enum specifying whether a subject of permission is accessible and allowed. +enum class PermissionState { + // The device has not granted the site access to the requested permission. + // When this is the state of a given permission, the app is unable to change + // it to ALLOWED or BLOCKED. + NOT_ACCESSIBLE = 0, + // The site has access to the requested permission and is able to use it when + // needed. + ALLOWED = 1, + // The site has access to the requested permission, but the user has disabled + // or blocked the subject of permission so it cannot be used. + BLOCKED = 2, +}; + +} // namespace web + +#endif // IOS_WEB_PUBLIC_PERMISSIONS_PERMISSIONS_H_
diff --git a/ios/web/public/test/fakes/BUILD.gn b/ios/web/public/test/fakes/BUILD.gn index cb05348..d9d35c2 100644 --- a/ios/web/public/test/fakes/BUILD.gn +++ b/ios/web/public/test/fakes/BUILD.gn
@@ -16,6 +16,7 @@ "//ios/web/public/download", "//ios/web/public/find_in_page", "//ios/web/public/js_messaging", + "//ios/web/public/permissions", "//ios/web/public/security", "//ios/web/public/session", "//ios/web/public/test:util",
diff --git a/ios/web/public/test/fakes/fake_web_state.h b/ios/web/public/test/fakes/fake_web_state.h index b39d727..b52f1e1 100644 --- a/ios/web/public/test/fakes/fake_web_state.h +++ b/ios/web/public/test/fakes/fake_web_state.h
@@ -15,6 +15,7 @@ #include "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/navigation/navigation_manager.h" #import "ios/web/public/navigation/web_state_policy_decider.h" +#import "ios/web/public/permissions/permissions.h" #import "ios/web/public/web_state.h" #include "ios/web/public/web_state_observer.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -91,6 +92,12 @@ bool SetSessionStateData(NSData* data) override; NSData* SessionStateData() override; + PermissionState GetStateForPermission(Permission permission) const override + API_AVAILABLE(ios(15.0)); + void SetStateForPermission(PermissionState state, + Permission permission) override + API_AVAILABLE(ios(15.0)); + void AddPolicyDecider(WebStatePolicyDecider* decider) override; void RemovePolicyDecider(WebStatePolicyDecider* decider) override; void DidChangeVisibleSecurityState() override; @@ -182,6 +189,9 @@ base::RepeatingCallbackList<ScriptCommandCallbackSignature> callback_list_; absl::optional<ScriptCommandCallback> last_added_callback_; std::string last_command_prefix_; + PermissionState camera_permission_state_ = PermissionState::NOT_ACCESSIBLE; + PermissionState microphone_permission_state_ = + PermissionState::NOT_ACCESSIBLE; // A list of observers notified when page state changes. Weak references. base::ObserverList<WebStateObserver, true>::Unchecked observers_;
diff --git a/ios/web/public/test/fakes/fake_web_state.mm b/ios/web/public/test/fakes/fake_web_state.mm index e1fb84a..1d78ede0 100644 --- a/ios/web/public/test/fakes/fake_web_state.mm +++ b/ios/web/public/test/fakes/fake_web_state.mm
@@ -501,6 +501,29 @@ return nil; } +PermissionState FakeWebState::GetStateForPermission( + Permission permission) const { + switch (permission) { + case Permission::CAMERA: + return camera_permission_state_; + case Permission::MICROPHONE: + return microphone_permission_state_; + } + return PermissionState::NOT_ACCESSIBLE; +} + +void FakeWebState::SetStateForPermission(PermissionState state, + Permission permission) { + switch (permission) { + case Permission::CAMERA: + camera_permission_state_ = state; + return; + case Permission::MICROPHONE: + microphone_permission_state_ = state; + return; + } +} + FakeWebStateWithPolicyCache::FakeWebStateWithPolicyCache( BrowserState* browser_state) : FakeWebState(),
diff --git a/ios/web/public/web_state.h b/ios/web/public/web_state.h index 6a6bee1..eb2a648 100644 --- a/ios/web/public/web_state.h +++ b/ios/web/public/web_state.h
@@ -49,6 +49,8 @@ class BrowserState; class NavigationManager; +enum class Permission; +enum class PermissionState; class SessionCertificatePolicyCache; class WebFrame; class WebFramesManager; @@ -433,6 +435,14 @@ virtual bool SetSessionStateData(NSData* data) = 0; virtual NSData* SessionStateData() = 0; + // Gets or sets the web state's permission for a specific type, for example + // camera or microphone, on the device. + virtual PermissionState GetStateForPermission(Permission permission) const + API_AVAILABLE(ios(15.0)) = 0; + virtual void SetStateForPermission(PermissionState state, + Permission permission) + API_AVAILABLE(ios(15.0)) = 0; + protected: friend class WebStatePolicyDecider;
diff --git a/ios/web/public/web_state_observer.h b/ios/web/public/web_state_observer.h index 39cad3b..6b2db80 100644 --- a/ios/web/public/web_state_observer.h +++ b/ios/web/public/web_state_observer.h
@@ -5,6 +5,8 @@ #ifndef IOS_WEB_PUBLIC_WEB_STATE_OBSERVER_H_ #define IOS_WEB_PUBLIC_WEB_STATE_OBSERVER_H_ +#include <CoreFoundation/CFBase.h> + #include <stddef.h> #include <string> @@ -14,6 +16,7 @@ struct FaviconURL; class NavigationContext; +enum class Permission; class WebFrame; class WebState; @@ -123,6 +126,11 @@ virtual void FaviconUrlUpdated(WebState* web_state, const std::vector<FaviconURL>& candidates) {} + // Invoked when the state of a certain permission has changed. + virtual void PermissionStateChanged(WebState* web_state, + Permission permission) + API_AVAILABLE(ios(15.0)) {} + // Called when a frame was created or navigated to a new document. // Receivers can keep references to |web_frame| until // |WebFrameWillBecomeUnavailable| is called but must not assume that the
diff --git a/ios/web/public/web_state_observer_bridge.h b/ios/web/public/web_state_observer_bridge.h index ffe35b17..8e43d6b 100644 --- a/ios/web/public/web_state_observer_bridge.h +++ b/ios/web/public/web_state_observer_bridge.h
@@ -13,6 +13,7 @@ namespace web { class NavigationContext; +enum class Permission; } // Observes page lifecycle events from Objective-C. To use as a @@ -65,6 +66,11 @@ didUpdateFaviconURLCandidates: (const std::vector<web::FaviconURL>&)candidates; +// Invoked by WebStateObserverBridge::PermissionStateChanged. +- (void)webState:(web::WebState*)webState + didChangeStateForPermission:(web::Permission)permission + API_AVAILABLE(ios(15.0)); + // Invoked by WebStateObserverBridge::WebFrameDidBecomeAvailable. - (void)webState:(web::WebState*)webState frameDidBecomeAvailable:(web::WebFrame*)webFrame; @@ -120,6 +126,9 @@ void DidChangeVisibleSecurityState(web::WebState* web_state) override; void FaviconUrlUpdated(web::WebState* web_state, const std::vector<FaviconURL>& candidates) override; + void PermissionStateChanged(web::WebState* web_state, + web::Permission permission) override + API_AVAILABLE(ios(15.0)); void WebFrameDidBecomeAvailable(WebState* web_state, WebFrame* web_frame) override; void WebFrameWillBecomeUnavailable(WebState* web_state,
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index 1711266..5cc873a 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -18,6 +18,8 @@ namespace web { enum class NavigationInitiationType; +enum class Permission; +enum class PermissionState; enum class WKNavigationState; } // namespace web @@ -193,6 +195,13 @@ - (BOOL)setSessionStateData:(NSData*)data; - (NSData*)sessionStateData; +// Gets and sets the web state's state of a permission; for example, the one to +// use the camera on the device. Only works on iOS 15+. +- (web::PermissionState)stateForPermission:(web::Permission)permission + API_AVAILABLE(ios(15.0)); +- (void)setState:(web::PermissionState)state + forPermission:(web::Permission)permission API_AVAILABLE(ios(15.0)); + // Injects the windowID into the main frame of the current webpage. // TODO(crbug.com/905939): Remove WindowID. - (void)injectWindowID;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 3a1705a..fb5d2c0 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -43,6 +43,7 @@ #import "ios/web/public/deprecated/crw_js_injection_evaluator.h" #import "ios/web/public/deprecated/crw_js_injection_receiver.h" #include "ios/web/public/js_messaging/web_frame_util.h" +#import "ios/web/public/permissions/permissions.h" #import "ios/web/public/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/ui/page_display_state.h" #import "ios/web/public/web_client.h" @@ -467,11 +468,19 @@ } - (NSDictionary*)WKWebViewObservers { - return @{ - @"serverTrust" : @"webViewSecurityFeaturesDidChange", - @"hasOnlySecureContent" : @"webViewSecurityFeaturesDidChange", - @"title" : @"webViewTitleDidChange", - }; + NSMutableDictionary<NSString*, NSString*>* observers = + [[NSMutableDictionary alloc] initWithDictionary:@{ + @"serverTrust" : @"webViewSecurityFeaturesDidChange", + @"hasOnlySecureContent" : @"webViewSecurityFeaturesDidChange", + @"title" : @"webViewTitleDidChange", + }]; + if (web::features::IsMediaPermissionsControlEnabled()) { + [observers addEntriesFromDictionary:@{ + @"cameraCaptureState" : @"webViewCameraCaptureStateDidChange", + @"microphoneCaptureState" : @"webViewMicrophoneCaptureStateDidChange", + }]; + } + return observers; } - (GURL)currentURL { @@ -884,6 +893,63 @@ return NO; } +#if !TARGET_OS_MACCATALYST +- (web::PermissionState)stateForPermission:(web::Permission)permission { + WKMediaCaptureState captureState; + switch (permission) { + case web::Permission::CAMERA: + captureState = self.webView.cameraCaptureState; + break; + case web::Permission::MICROPHONE: + captureState = self.webView.microphoneCaptureState; + break; + } + switch (captureState) { + case WKMediaCaptureStateActive: + return web::PermissionState::ALLOWED; + case WKMediaCaptureStateMuted: + return web::PermissionState::BLOCKED; + case WKMediaCaptureStateNone: + return web::PermissionState::NOT_ACCESSIBLE; + } +} + +- (void)setState:(web::PermissionState)state + forPermission:(web::Permission)permission { + WKMediaCaptureState captureState; + switch (state) { + case web::PermissionState::ALLOWED: + captureState = WKMediaCaptureStateActive; + break; + case web::PermissionState::BLOCKED: + captureState = WKMediaCaptureStateMuted; + break; + case web::PermissionState::NOT_ACCESSIBLE: + captureState = WKMediaCaptureStateNone; + break; + } + switch (permission) { + case web::Permission::CAMERA: + [self.webView setCameraCaptureState:captureState completionHandler:nil]; + break; + case web::Permission::MICROPHONE: + [self.webView setMicrophoneCaptureState:captureState + completionHandler:nil]; + break; + } +} +#else +// Stub getter implementation for mac catalyst build. +- (web::PermissionState)stateForPermission:(web::Permission)permission { + return web::PermissionState::NOT_ACCESSIBLE; +} + +// Stub setter implementation for mac catalyst build. +- (void)setState:(web::PermissionState)state + forPermission:(web::Permission)permission { +} +#endif + - (NSData*)sessionStateData { if (@available(iOS 15, *)) { return self.webView.interactionState; @@ -1701,6 +1767,16 @@ } } +// Called when WKWebView cameraCaptureState property has changed. +- (void)webViewCameraCaptureStateDidChange API_AVAILABLE(ios(15.0)) { + self.webStateImpl->OnStateChangedForPermission(web::Permission::CAMERA); +} + +// Called when WKWebView microphoneCaptureState property has changed. +- (void)webViewMicrophoneCaptureStateDidChange API_AVAILABLE(ios(15.0)) { + self.webStateImpl->OnStateChangedForPermission(web::Permission::MICROPHONE); +} + #pragma mark - CRWWebViewHandlerDelegate - (web::WebStateImpl*)webStateImplForWebViewHandler:
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index 0118f2b..dd86140b 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -41,6 +41,8 @@ struct FaviconURL; class NavigationContextImpl; class NavigationManager; +enum class Permission; +enum class PermissionState; class SessionCertificatePolicyCacheImpl; class WebFrame; @@ -116,6 +118,11 @@ // Called when new FaviconURL candidates are received. void OnFaviconUrlUpdated(const std::vector<FaviconURL>& candidates); + // Notifies web state observers when any of the web state's permission has + // changed. + void OnStateChangedForPermission(Permission permission) + API_AVAILABLE(ios(15.0)); + // Returns the NavigationManager for this WebState. NavigationManagerImpl& GetNavigationManagerImpl(); @@ -304,6 +311,10 @@ void CloseWebState() final; bool SetSessionStateData(NSData* data) final; NSData* SessionStateData() final; + PermissionState GetStateForPermission(Permission permission) const final + API_AVAILABLE(ios(15.0)); + void SetStateForPermission(PermissionState state, Permission permission) final + API_AVAILABLE(ios(15.0)); protected: // WebState:
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index d1fe946..a202f80c 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -11,6 +11,7 @@ #import "base/feature_list.h" #import "ios/web/common/features.h" #import "ios/web/public/js_messaging/web_frame.h" +#import "ios/web/public/permissions/permissions.h" #import "ios/web/session/session_certificate_policy_cache_impl.h" #import "ios/web/web_state/global_web_state_event_tracker.h" #import "ios/web/web_state/web_state_impl_realized_web_state.h" @@ -140,6 +141,10 @@ RealizedState()->OnFaviconUrlUpdated(candidates); } +void WebStateImpl::OnStateChangedForPermission(Permission permission) { + RealizedState()->OnStateChangedForPermission(permission); +} + NavigationManagerImpl& WebStateImpl::GetNavigationManagerImpl() { return RealizedState()->GetNavigationManager(); } @@ -548,6 +553,17 @@ return LIKELY(pimpl_) ? pimpl_->SessionStateData() : nil; } +PermissionState WebStateImpl::GetStateForPermission( + Permission permission) const { + return LIKELY(pimpl_) ? pimpl_->GetStateForPermission(permission) + : PermissionState::NOT_ACCESSIBLE; +} + +void WebStateImpl::SetStateForPermission(PermissionState state, + Permission permission) { + RealizedState()->SetStateForPermission(state, permission); +} + void WebStateImpl::AddPolicyDecider(WebStatePolicyDecider* decider) { // Despite the name, ObserverList is actually generic, so it is used for // deciders. This makes the call here odd looking, but it's really just
diff --git a/ios/web/web_state/web_state_impl_realized_web_state.h b/ios/web/web_state/web_state_impl_realized_web_state.h index 8d87f3c9..310f936c 100644 --- a/ios/web/web_state/web_state_impl_realized_web_state.h +++ b/ios/web/web_state/web_state_impl_realized_web_state.h
@@ -171,6 +171,12 @@ void CloseWebState(); bool SetSessionStateData(NSData* data); NSData* SessionStateData() const; + PermissionState GetStateForPermission(Permission permission) const + API_AVAILABLE(ios(15.0)); + void SetStateForPermission(PermissionState state, Permission permission) + API_AVAILABLE(ios(15.0)); + void OnStateChangedForPermission(Permission permission) + API_AVAILABLE(ios(15.0)); // NavigationManagerDelegate: void ClearDialogs() final;
diff --git a/ios/web/web_state/web_state_impl_realized_web_state.mm b/ios/web/web_state/web_state_impl_realized_web_state.mm index 65a60c8..0702725 100644 --- a/ios/web/web_state/web_state_impl_realized_web_state.mm +++ b/ios/web/web_state/web_state_impl_realized_web_state.mm
@@ -802,6 +802,24 @@ return [web_controller_ sessionStateData]; } +PermissionState WebStateImpl::RealizedWebState::GetStateForPermission( + Permission permission) const { + return [web_controller_ stateForPermission:permission]; +} + +void WebStateImpl::RealizedWebState::SetStateForPermission( + PermissionState state, + Permission permission) { + [web_controller_ setState:state forPermission:permission]; +} + +void WebStateImpl::RealizedWebState::OnStateChangedForPermission( + Permission permission) { + for (auto& observer : observers()) { + observer.PermissionStateChanged(owner_, permission); + } +} + #pragma mark - NavigationManagerDelegate implementation void WebStateImpl::RealizedWebState::ClearDialogs() {
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm index 7060024c..6ac937f 100644 --- a/ios/web/web_state/web_state_observer_bridge.mm +++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -10,6 +10,8 @@ namespace web { +enum class Permission; + WebStateObserverBridge::WebStateObserverBridge(id<CRWWebStateObserver> observer) : observer_(observer) {} @@ -123,6 +125,15 @@ } } +void WebStateObserverBridge::PermissionStateChanged( + web::WebState* web_state, + web::Permission permission) { + SEL selector = @selector(webState:didChangeStateForPermission:); + if ([observer_ respondsToSelector:selector]) { + [observer_ webState:web_state didChangeStateForPermission:permission]; + } +} + void WebStateObserverBridge::WebFrameDidBecomeAvailable( web::WebState* web_state, web::WebFrame* web_frame) {
diff --git a/ios/web/web_state/web_state_observer_bridge_unittest.mm b/ios/web/web_state/web_state_observer_bridge_unittest.mm index 94a18891..1e9732d 100644 --- a/ios/web/web_state/web_state_observer_bridge_unittest.mm +++ b/ios/web/web_state/web_state_observer_bridge_unittest.mm
@@ -247,6 +247,11 @@ EXPECT_EQ(url.icon_sizes[0].height(), actual_url.icon_sizes[0].height()); } +// Tests |webState:didChangeStateForPermission:| forwarding. +TEST_F(WebStateObserverBridgeTest, PermissionStateChanged) { + // TODO(crbug.com/1284709): Implement this test. +} + // Tests |renderProcessGoneForWebState:| forwarding. TEST_F(WebStateObserverBridgeTest, RenderProcessGone) { ASSERT_FALSE([observer_ renderProcessGoneInfo]);
diff --git a/media/base/audio_point_unittest.cc b/media/base/audio_point_unittest.cc index 0970ef27..bd91e44 100644 --- a/media/base/audio_point_unittest.cc +++ b/media/base/audio_point_unittest.cc
@@ -11,10 +11,8 @@ namespace { TEST(PointTest, PointsToString) { - std::vector<Point> points(1, Point(1, 0, 0.01f)); - points.push_back(Point(0, 2, 0.02f)); - EXPECT_EQ("1.000000,0.000000,0.010000, 0.000000,2.000000,0.020000", - PointsToString(points)); + std::vector<Point> points = {Point(1, 0, 0.01f), Point(0, 2, 0.02f)}; + EXPECT_EQ("1,0,0.01, 0,2,0.02", PointsToString(points)); EXPECT_EQ("", PointsToString(std::vector<Point>())); }
diff --git a/media/base/media.cc b/media/base/media.cc index 6d75db7..ef6ffe8 100644 --- a/media/base/media.cc +++ b/media/base/media.cc
@@ -10,6 +10,7 @@ #include "base/allocator/buildflags.h" #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/no_destructor.h" #include "base/trace_event/trace_event.h" #include "media/base/media_switches.h" #include "media/media_buildflags.h" @@ -56,9 +57,9 @@ ~MediaInitializer() = delete; }; -static MediaInitializer* GetMediaInstance() { - static MediaInitializer* instance = new MediaInitializer(); - return instance; +static const MediaInitializer& GetMediaInstance() { + static const base::NoDestructor<MediaInitializer> instance; + return *instance; } void InitializeMediaLibrary() {
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc index b0fcd44..80482330 100644 --- a/media/base/mime_util_internal.cc +++ b/media/base/mime_util_internal.cc
@@ -573,7 +573,7 @@ // valid codecs to be used with HLS mime types. DCHECK(!base::EndsWith(mime_type_lower_case, "mpegurl", base::CompareCase::SENSITIVE)); - FALLTHROUGH; + [[fallthrough]]; case PCM: case MP3: case MPEG4_AAC:
diff --git a/media/base/status.h b/media/base/status.h index 3b6a1b53..8b27fc0 100644 --- a/media/base/status.h +++ b/media/base/status.h
@@ -106,6 +106,21 @@ } }; +template <typename, typename> +struct OkStatusDetectorHelper { + constexpr static bool has_ok = false; +}; + +// Matches <T,T> if T::kOk exists. +template <typename T> +struct OkStatusDetectorHelper<T, decltype(T::kOk)> { + constexpr static bool has_ok = true; +}; + +// Does T have a T::kOk? +template <typename T> +constexpr bool DoesHaveOkCode = OkStatusDetectorHelper<T, T>::has_ok; + } // namespace internal // See media/base/status.md for details and instructions for using TypedStatus. @@ -116,6 +131,23 @@ static_assert(std::is_same<decltype(T::Group), StatusGroupType()>::value, "TypedStatus Traits::Group() must return StatusGroupType."); + // Check that, if there is both `kOk` and a default value, that the default + // value is `kOk`. + constexpr static bool verify_default_okayness() { + // Fancy new (c++17) thing: remember that 'if constexpr' short-circuits at + // compile-time, so the later clauses don't have to be compilable if the + // the earlier ones match. Specifically, it's okay to reference `kOk` even + // if `T::Codes` doesn't have `kOk`, since we check for it first. + if constexpr (!internal::DoesHaveOkCode<typename T::Codes>) + return true; + else if constexpr (!internal::StatusTraitsHelper<T>::DefaultEnumValue()) + return true; + else + return T::DefaultEnumValue() == T::Codes::kOk; + } + static_assert(verify_default_okayness(), + "If kOk is defined, then either no default, or default==kOk"); + public: // Convenience aliases to allow, e.g., MyStatusType::Codes::kGreatDisturbance. using Traits = T; @@ -155,8 +187,15 @@ return *this; } - // DEPRECATED: check code() == ok value. - bool is_ok() const { return !data_; } + // If `Codes` has a `kOk` value, then check return true if we're `kOk`. If + // there is no `kOk`, or if we're some other value, then return false. + bool is_ok() const { + if constexpr (internal::DoesHaveOkCode<Codes>) { + return code() == Codes::kOk; + } else { + return false; + } + } Codes code() const { if (!data_) @@ -252,15 +291,11 @@ // Implicit constructors allow returning |OtherType| or |TypedStatus| // directly. Or(TypedStatus<T>&& error) : error_(std::move(error)) { - // |T| must either not have a default code, or not be default - DCHECK(!internal::StatusTraitsHelper<Traits>::DefaultEnumValue() || - *internal::StatusTraitsHelper<Traits>::DefaultEnumValue() != - code()); + // `error_` must not be `kOk`, if there is such a value. + DCHECK(!error_->is_ok()); } Or(const TypedStatus<T>& error) : error_(error) { - DCHECK(!internal::StatusTraitsHelper<Traits>::DefaultEnumValue() || - *internal::StatusTraitsHelper<Traits>::DefaultEnumValue() != - code()); + DCHECK(!error_->is_ok()); } Or(OtherType&& value) : value_(std::move(value)) {} @@ -268,8 +303,7 @@ Or(typename T::Codes code, const base::Location& location = base::Location::Current()) : error_(TypedStatus<T>(code, "", location)) { - DCHECK(!internal::StatusTraitsHelper<Traits>::DefaultEnumValue() || - *internal::StatusTraitsHelper<Traits>::DefaultEnumValue() != code); + DCHECK(!error_->is_ok()); } // Move- and copy- construction and assignment are okay. @@ -281,12 +315,19 @@ bool has_value() const { return value_.has_value(); } bool has_error() const { return error_.has_value(); } + // If we have an error, verify that `code` matches. If we have a value, + // then this should match if an only if `code` is `kOk`. If there is no + // `kOk`, then it does not match even if we have a value. inline bool operator==(typename T::Codes code) const { - return code == this->code(); + if constexpr (internal::DoesHaveOkCode<typename T::Codes>) { + return code == this->code(); + } else { + return error_ ? code == error_->code() : false; + } } inline bool operator!=(typename T::Codes code) const { - return code != this->code(); + return !(*this == code); } // Return the error, if we have one. @@ -310,11 +351,14 @@ typename T::Codes code() const { DCHECK(error_ || value_); // It is invalid to call |code()| on an |Or| with a value that - // is specialized in a TypedStatus with no DefaultEnumValue. - DCHECK(error_ || - internal::StatusTraitsHelper<Traits>::DefaultEnumValue()); - return error_ ? error_->code() - : *internal::StatusTraitsHelper<Traits>::DefaultEnumValue(); + // is specialized in a TypedStatus with no `kOk`. Instead, you should + // explicitly call has_error() / error().code(). + static_assert(internal::DoesHaveOkCode<typename T::Codes>, + "Cannot call Or::code() if there is no kOk code."); + // TODO: should this DCHECK(error_) if we don't have kOk? It's not as + // strong as the static_assert, but maybe we want to allow this for types + // that don't have `kOk`. + return error_ ? error_->code() : T::Codes::kOk; } template <typename FnType,
diff --git a/media/base/status_unittest.cc b/media/base/status_unittest.cc index 6c6a536a..77ba3b1 100644 --- a/media/base/status_unittest.cc +++ b/media/base/status_unittest.cc
@@ -32,12 +32,26 @@ } // namespace internal -enum class NoDefaultType : StatusCodeType { kFoo = 0, kBar = 1, kBaz = 2 }; +enum class NoDefaultNoOkType : StatusCodeType { kFoo = 0, kBar = 1, kBaz = 2 }; -struct NoDefaultTypeTraits { - using Codes = NoDefaultType; +struct NoDefaultNoOkTypeTraits { + using Codes = NoDefaultNoOkType; static constexpr StatusGroupType Group() { - return "GroupWithNoDefaultTypeForTests"; + return "GroupWithNoDefaultNoOkTypeForTests"; + } +}; + +enum class NoDefaultHasOkType : StatusCodeType { + kOk = 0, + kFoo = 1, + kBar = 2, + kBaz = 3 +}; + +struct NoDefaultHasOkTypeTraits { + using Codes = NoDefaultHasOkType; + static constexpr StatusGroupType Group() { + return "GroupWithNoDefaultHasOkTypeForTests"; } }; @@ -53,9 +67,13 @@ public: Status DontFail() { return OkStatus(); } + // Return a failure, with a line number. Record the lower and upper line + // number limits so that we can make sure that the error's line is bounded. + constexpr static int lower_line_limit_ = __LINE__; Status FailEasily() { return Status(StatusCode::kCodeOnlyForTesting, "Message"); } + constexpr static int upper_line_limit_ = __LINE__; Status FailRecursively(unsigned int count) { if (!count) { @@ -143,8 +161,11 @@ const auto& stack = actual.FindListPath("stack")->GetList(); ASSERT_EQ(stack[0].DictSize(), 2ul); // line and file - // This is a bit fragile, since it's dependent on the file layout. - ASSERT_EQ(stack[0].FindIntPath("line").value_or(-1), 57); + // This is a bit fragile, since it's dependent on the file layout. Just check + // that it's somewhere in the `FailEasily`` function. + int line = stack[0].FindIntPath("line").value_or(-1); + ASSERT_GT(line, lower_line_limit_); + ASSERT_LT(line, upper_line_limit_); ASSERT_THAT(*stack[0].FindStringPath("file"), HasSubstr("status_unittest.cc")); } @@ -302,24 +323,74 @@ EXPECT_EQ(status_or.code(), StatusCode::kOk); } -TEST_F(StatusTest, TypedStatusWithNoDefault) { - using NDStatus = TypedStatus<NoDefaultTypeTraits>; +TEST_F(StatusTest, TypedStatusWithNoDefaultAndNoOk) { + using NDStatus = TypedStatus<NoDefaultNoOkTypeTraits>; - NDStatus foo = NoDefaultType::kFoo; - EXPECT_EQ(foo.code(), NoDefaultType::kFoo); + NDStatus foo = NDStatus::Codes::kFoo; + EXPECT_EQ(foo.code(), NDStatus::Codes::kFoo); + EXPECT_FALSE(foo.is_ok()); - NDStatus bar = NoDefaultType::kBar; - EXPECT_EQ(bar.code(), NoDefaultType::kBar); + NDStatus bar = NDStatus::Codes::kBar; + EXPECT_EQ(bar.code(), NDStatus::Codes::kBar); + EXPECT_FALSE(bar.is_ok()); - NDStatus::Or<std::string> err = NoDefaultType::kBaz; + NDStatus::Or<std::string> err = NDStatus::Codes::kBaz; NDStatus::Or<std::string> ok = std::string("kBaz"); EXPECT_TRUE(err.has_error()); - EXPECT_EQ(err.code(), NoDefaultType::kBaz); + EXPECT_FALSE(err.has_value()); + // One cannot call err.code() without an okay type. + EXPECT_EQ(std::move(err).error().code(), NDStatus::Codes::kBaz); + EXPECT_FALSE(ok.has_error()); + EXPECT_TRUE(ok.has_value()); + // One cannot call ok.code() without an okay type. base::Value actual = MediaSerialize(bar); - EXPECT_EQ(*actual.FindIntPath("code"), 1); + EXPECT_EQ(*actual.FindIntPath("code"), static_cast<int>(bar.code())); +} + +TEST_F(StatusTest, TypedStatusWithNoDefaultHasOk) { + using NDStatus = TypedStatus<NoDefaultHasOkTypeTraits>; + + NDStatus foo = NDStatus::Codes::kFoo; + EXPECT_EQ(foo.code(), NDStatus::Codes::kFoo); + EXPECT_FALSE(foo.is_ok()); + + NDStatus bar = NDStatus::Codes::kBar; + EXPECT_EQ(bar.code(), NDStatus::Codes::kBar); + EXPECT_FALSE(bar.is_ok()); + + NDStatus bat = NDStatus::Codes::kOk; + EXPECT_EQ(bat.code(), NDStatus::Codes::kOk); + EXPECT_TRUE(bat.is_ok()); + + NDStatus::Or<std::string> err = NDStatus::Codes::kBaz; + NDStatus::Or<std::string> ok = std::string("kBaz"); + + EXPECT_TRUE(err.has_error()); + EXPECT_FALSE(err.has_value()); + EXPECT_EQ(err.code(), NDStatus::Codes::kBaz); + + EXPECT_FALSE(ok.has_error()); + EXPECT_TRUE(ok.has_value()); + EXPECT_EQ(ok.code(), NDStatus::Codes::kOk); + + base::Value actual = MediaSerialize(bar); + EXPECT_EQ(*actual.FindIntPath("code"), static_cast<int>(bar.code())); +} + +TEST_F(StatusTest, Okayness) { + EXPECT_FALSE( + TypedStatus<NoDefaultNoOkTypeTraits>(NoDefaultNoOkTypeTraits::Codes::kFoo) + .is_ok()); + + EXPECT_FALSE(TypedStatus<NoDefaultHasOkTypeTraits>( + NoDefaultHasOkTypeTraits::Codes::kFoo) + .is_ok()); + EXPECT_TRUE(TypedStatus<NoDefaultHasOkTypeTraits>( + NoDefaultHasOkTypeTraits::Codes::kOk) + .is_ok()); } TEST_F(StatusTest, StatusOrEqOp) { @@ -395,7 +466,7 @@ } TEST_F(StatusTest, OrTypeMappingToOtherOrType) { - using A = TypedStatus<NoDefaultTypeTraits>; + using A = TypedStatus<NoDefaultNoOkTypeTraits>; using B = TypedStatus<MapValueCodeTraits>; auto unwrap = [](std::unique_ptr<int> ptr) -> A::Or<int> {
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc index 65f3ce9..f7868a6 100644 --- a/media/base/supported_types.cc +++ b/media/base/supported_types.cc
@@ -62,7 +62,7 @@ } switch (profile) { case HEVCPROFILE_MAIN: - FALLTHROUGH; + [[fallthrough]]; case HEVCPROFILE_MAIN10: return true; case HEVCPROFILE_MAIN_STILL_PICTURE:
diff --git a/media/base/video_types.cc b/media/base/video_types.cc index 56b39a1..00b263d 100644 --- a/media/base/video_types.cc +++ b/media/base/video_types.cc
@@ -179,7 +179,7 @@ switch (format) { case PIXEL_FORMAT_UNKNOWN: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case PIXEL_FORMAT_I420: case PIXEL_FORMAT_YV12: case PIXEL_FORMAT_I422:
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc index 260b6517..2075bd6 100644 --- a/media/capture/video/win/video_capture_device_factory_win.cc +++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -358,7 +358,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); switch (device_descriptor.capture_api) { case VideoCaptureApi::WIN_MEDIA_FOUNDATION: - FALLTHROUGH; + [[fallthrough]]; case VideoCaptureApi::WIN_MEDIA_FOUNDATION_SENSOR: { DCHECK(PlatformSupportsMediaFoundation()); ComPtr<IMFMediaSource> source;
diff --git a/media/capture/video/win/video_capture_device_mf_win.cc b/media/capture/video/win/video_capture_device_mf_win.cc index bee7a7f..f184bde 100644 --- a/media/capture/video/win/video_capture_device_mf_win.cc +++ b/media/capture/video/win/video_capture_device_mf_win.cc
@@ -25,6 +25,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/platform_thread.h" #include "base/win/scoped_co_mem.h" #include "base/win/windows_version.h" #include "media/capture/mojom/image_capture_types.h"
diff --git a/media/cast/sender/video_encoder_unittest.cc b/media/cast/sender/video_encoder_unittest.cc index a499614..1eb21ee 100644 --- a/media/cast/sender/video_encoder_unittest.cc +++ b/media/cast/sender/video_encoder_unittest.cc
@@ -28,6 +28,7 @@ #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_MAC) +#include "base/threading/platform_thread.h" #include "media/cast/sender/h264_vt_encoder.h" #endif
diff --git a/media/cdm/library_cdm/clear_key_cdm/ffmpeg_cdm_audio_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/ffmpeg_cdm_audio_decoder.cc index 8a78682..e4fc3f46 100644 --- a/media/cdm/library_cdm/clear_key_cdm/ffmpeg_cdm_audio_decoder.cc +++ b/media/cdm/library_cdm/clear_key_cdm/ffmpeg_cdm_audio_decoder.cc
@@ -248,7 +248,7 @@ return cdm::kDecodeError; case FFmpegDecodingLoop::DecodeStatus::kFrameProcessingFailed: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case FFmpegDecodingLoop::DecodeStatus::kDecodeFrameFailed: DLOG(WARNING) << " failed to decode an audio buffer: " << timestamp.InMicroseconds();
diff --git a/media/filters/dav1d_video_decoder_unittest.cc b/media/filters/dav1d_video_decoder_unittest.cc index ac1a456..61f51fc5 100644 --- a/media/filters/dav1d_video_decoder_unittest.cc +++ b/media/filters/dav1d_video_decoder_unittest.cc
@@ -114,7 +114,7 @@ break; case StatusCode::kAborted: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; default: DCHECK(output_frames_.empty()); return status;
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc index 029f25ce..76b30ab 100644 --- a/media/filters/ffmpeg_video_decoder_unittest.cc +++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -135,7 +135,7 @@ break; case StatusCode::kAborted: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; default: DCHECK(output_frames_.empty()); return status;
diff --git a/media/filters/gav1_video_decoder_unittest.cc b/media/filters/gav1_video_decoder_unittest.cc index bfd57f6..ee67114f 100644 --- a/media/filters/gav1_video_decoder_unittest.cc +++ b/media/filters/gav1_video_decoder_unittest.cc
@@ -139,7 +139,7 @@ break; case StatusCode::kAborted: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; default: DCHECK(output_frames_.empty()); return status;
diff --git a/media/filters/memory_data_source.h b/media/filters/memory_data_source.h index 4b6b344d..2a279fe 100644 --- a/media/filters/memory_data_source.h +++ b/media/filters/memory_data_source.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include <atomic> #include <string> #include "base/compiler_specific.h"
diff --git a/media/filters/video_decoder_stream_unittest.cc b/media/filters/video_decoder_stream_unittest.cc index 7d396d3..e1bea9b 100644 --- a/media/filters/video_decoder_stream_unittest.cc +++ b/media/filters/video_decoder_stream_unittest.cc
@@ -477,7 +477,7 @@ case DEMUXER_READ_CONFIG_CHANGE: EXPECT_MEDIA_LOG(HasSubstr("decoder config changed")) .Times(testing::AtLeast(1)); - FALLTHROUGH; + [[fallthrough]]; case DEMUXER_READ_NORMAL: demuxer_stream_->SatisfyRead(); break;
diff --git a/media/filters/vpx_video_decoder_unittest.cc b/media/filters/vpx_video_decoder_unittest.cc index 8f2eeee..8103eae 100644 --- a/media/filters/vpx_video_decoder_unittest.cc +++ b/media/filters/vpx_video_decoder_unittest.cc
@@ -101,7 +101,7 @@ break; case StatusCode::kAborted: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; default: DCHECK(output_frames_.empty()); return status;
diff --git a/media/formats/hls/items_fuzzer.cc b/media/formats/hls/items_fuzzer.cc index c7a88c9..3b63416 100644 --- a/media/formats/hls/items_fuzzer.cc +++ b/media/formats/hls/items_fuzzer.cc
@@ -42,8 +42,8 @@ if (result.has_error()) { // Ensure that this was an error this function is expected to return - CHECK(result.code() == media::hls::ParseStatusCode::kReachedEOF || - result.code() == media::hls::ParseStatusCode::kInvalidEOL); + CHECK(result == media::hls::ParseStatusCode::kReachedEOF || + result == media::hls::ParseStatusCode::kInvalidEOL); // Ensure that `manifest` is still a substring of the previous manifest CHECK(IsSubstring(iterator.SourceForTesting(),
diff --git a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc index 621bd8b..3b463a2 100644 --- a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc +++ b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc
@@ -132,7 +132,7 @@ config_changed = true; } } - FALLTHROUGH; + [[fallthrough]]; default: slice_units.push_back(nalu); data_size += config_.length_size + nalu.size;
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index adf918d..71377faf 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -311,6 +311,16 @@ "//ui/gfx/geometry", ] + if (is_win || use_vaapi) { + sources += [ + "vp9_svc_layers.cc", + "vp9_svc_layers.h", + "vpx_rate_control.cc", + "vpx_rate_control.h", + ] + configs += [ "//third_party/libvpx:libvpx_config" ] + deps += [ "//third_party/libvpx:libvpxrc" ] + } if (use_libgav1_parser) { sources += [ "av1_decoder.cc", @@ -527,6 +537,10 @@ if (is_mac) { deps += [ "//media/gpu/mac:unit_tests" ] } + + if (is_win || use_vaapi) { + sources += [ "vp9_svc_layers_unittest.cc" ] + } } # TODO(crbug.com/1006266): consider using |use_chromeos_video_acceleration|.
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc index f20e8d2..70c6599 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc
@@ -1206,8 +1206,7 @@ // Driver may not have implemented V4L2_CID_JPEG_ACTIVE_MARKER. // Ignore any error and assume the driver implements the JPEG stream // the way we want it. - IOCTL_OR_ERROR_RETURN_VALUE(VIDIOC_QUERY_EXT_CTRL, &queryctrl, true, - "VIDIOC_QUERY_EXT_CTRL"); + device_->Ioctl(VIDIOC_QUERY_EXT_CTRL, &queryctrl); // Ask for JPEG markers we want. Since not all may be implemented, // ask for the common subset of what we want and what is supported. @@ -1215,8 +1214,7 @@ ctrl.value = queryctrl.maximum & (V4L2_JPEG_ACTIVE_MARKER_APP0 | V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT); - IOCTL_OR_ERROR_RETURN_VALUE(VIDIOC_S_EXT_CTRLS, &ctrls, true, - "VIDIOC_S_EXT_CTRLS"); + device_->Ioctl(VIDIOC_S_EXT_CTRLS, &ctrls); break; default:
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index 955872c..78ac788 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -72,14 +72,10 @@ "vp8_vaapi_video_decoder_delegate.h", "vp8_vaapi_video_encoder_delegate.cc", "vp8_vaapi_video_encoder_delegate.h", - "vp9_svc_layers.cc", - "vp9_svc_layers.h", "vp9_vaapi_video_decoder_delegate.cc", "vp9_vaapi_video_decoder_delegate.h", "vp9_vaapi_video_encoder_delegate.cc", "vp9_vaapi_video_encoder_delegate.h", - "vpx_rate_control.cc", - "vpx_rate_control.h", ] if (enable_platform_hevc_decoding) { sources += [ @@ -228,7 +224,6 @@ "vaapi_video_decode_accelerator_unittest.cc", "vaapi_video_encode_accelerator_unittest.cc", "vaapi_wrapper_unittest.cc", - "vp9_svc_layers_unittest.cc", "vp9_vaapi_video_encoder_delegate_unittest.cc", ] configs += [ "//third_party/libvpx:libvpx_config" ]
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 4a5842523..102307d6 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -46,10 +46,10 @@ #include "media/gpu/vaapi/vaapi_utils.h" #include "media/gpu/vaapi/vaapi_wrapper.h" #include "media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h" -#include "media/gpu/vaapi/vp9_svc_layers.h" #include "media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h" #include "media/gpu/vp8_reference_frame_vector.h" #include "media/gpu/vp9_reference_frame_vector.h" +#include "media/gpu/vp9_svc_layers.h" #define NOTIFY_ERROR(error, msg) \ do { \
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc index be23abf..6dd57aee 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
@@ -15,9 +15,9 @@ #include "media/gpu/gpu_video_encode_accelerator_helpers.h" #include "media/gpu/vaapi/vaapi_utils.h" #include "media/gpu/vaapi/vaapi_wrapper.h" -#include "media/gpu/vaapi/vp9_svc_layers.h" #include "media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h" #include "media/gpu/vp9_picture.h" +#include "media/gpu/vp9_svc_layers.h" #include "media/video/fake_gpu_memory_buffer.h" #include "media/video/video_encode_accelerator.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h index 9c5d621..ef81c52 100644 --- a/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/vp8_vaapi_video_encoder_delegate.h
@@ -10,9 +10,9 @@ #include "media/base/video_bitrate_allocation.h" #include "media/gpu/vaapi/vaapi_video_encoder_delegate.h" -#include "media/gpu/vaapi/vpx_rate_control.h" #include "media/gpu/vp8_picture.h" #include "media/gpu/vp8_reference_frame_vector.h" +#include "media/gpu/vpx_rate_control.h" #include "media/parsers/vp8_parser.h" namespace libvpx {
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc index 0cd9d29..c2f44d8 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
@@ -17,7 +17,8 @@ #include "media/gpu/macros.h" #include "media/gpu/vaapi/vaapi_common.h" #include "media/gpu/vaapi/vaapi_wrapper.h" -#include "media/gpu/vaapi/vp9_svc_layers.h" +#include "media/gpu/vp9_svc_layers.h" +#include "media/gpu/vpx_rate_control.h" #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h" namespace media {
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h index b840b58..6bcbc27 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h
@@ -13,9 +13,9 @@ #include "media/base/video_bitrate_allocation.h" #include "media/filters/vp9_parser.h" #include "media/gpu/vaapi/vaapi_video_encoder_delegate.h" -#include "media/gpu/vaapi/vpx_rate_control.h" #include "media/gpu/vp9_picture.h" #include "media/gpu/vp9_reference_frame_vector.h" +#include "media/gpu/vpx_rate_control.h" namespace libvpx { struct VP9FrameParamsQpRTC;
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc index fd153d85..1c52aaf 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
@@ -19,8 +19,8 @@ #include "media/gpu/gpu_video_encode_accelerator_helpers.h" #include "media/gpu/vaapi/vaapi_common.h" #include "media/gpu/vaapi/vaapi_wrapper.h" -#include "media/gpu/vaapi/vp9_svc_layers.h" -#include "media/gpu/vaapi/vpx_rate_control.h" +#include "media/gpu/vp9_svc_layers.h" +#include "media/gpu/vpx_rate_control.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/media/gpu/vp9_picture.h b/media/gpu/vp9_picture.h index 04ac8c9f..1ce652d 100644 --- a/media/gpu/vp9_picture.h +++ b/media/gpu/vp9_picture.h
@@ -17,7 +17,7 @@ class V4L2VP9Picture; class VaapiVP9Picture; -class VP9Picture : public CodecPicture { +class MEDIA_GPU_EXPORT VP9Picture : public CodecPicture { public: VP9Picture();
diff --git a/media/gpu/vp9_reference_frame_vector.h b/media/gpu/vp9_reference_frame_vector.h index 4685e58..0d18d154 100644 --- a/media/gpu/vp9_reference_frame_vector.h +++ b/media/gpu/vp9_reference_frame_vector.h
@@ -10,6 +10,7 @@ #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" #include "media/filters/vp9_parser.h" +#include "media/gpu/media_gpu_export.h" namespace media { @@ -17,7 +18,7 @@ // This class encapsulates VP9-specific reference frame management code. This // class is thread afine. -class Vp9ReferenceFrameVector { +class MEDIA_GPU_EXPORT Vp9ReferenceFrameVector { public: Vp9ReferenceFrameVector();
diff --git a/media/gpu/vaapi/vp9_svc_layers.cc b/media/gpu/vp9_svc_layers.cc similarity index 99% rename from media/gpu/vaapi/vp9_svc_layers.cc rename to media/gpu/vp9_svc_layers.cc index ead67ca..5cc607f 100644 --- a/media/gpu/vaapi/vp9_svc_layers.cc +++ b/media/gpu/vp9_svc_layers.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/gpu/vaapi/vp9_svc_layers.h" +#include "media/gpu/vp9_svc_layers.h" #include <bitset>
diff --git a/media/gpu/vaapi/vp9_svc_layers.h b/media/gpu/vp9_svc_layers.h similarity index 95% rename from media/gpu/vaapi/vp9_svc_layers.h rename to media/gpu/vp9_svc_layers.h index 2b4c415..47d87bc 100644 --- a/media/gpu/vaapi/vp9_svc_layers.h +++ b/media/gpu/vp9_svc_layers.h
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_ -#define MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_ +#ifndef MEDIA_GPU_VP9_SVC_LAYERS_H_ +#define MEDIA_GPU_VP9_SVC_LAYERS_H_ #include <stdint.h> #include <vector> #include "media/filters/vp9_parser.h" +#include "media/gpu/media_gpu_export.h" #include "media/video/video_encode_accelerator.h" namespace media { @@ -22,7 +23,7 @@ // temporal layer sizes must be unchanged. The temporal layer sizes among // spatial layers must be identical. Temporal layers and spatial layers are // described in https://tools.ietf.org/html/draft-ietf-payload-vp9-10#section-3. -class VP9SVCLayers { +class MEDIA_GPU_EXPORT VP9SVCLayers { public: struct FrameConfig; @@ -99,5 +100,4 @@ }; } // namespace media - -#endif // MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_ +#endif // MEDIA_GPU_VP9_SVC_LAYERS_H_
diff --git a/media/gpu/vaapi/vp9_svc_layers_unittest.cc b/media/gpu/vp9_svc_layers_unittest.cc similarity index 99% rename from media/gpu/vaapi/vp9_svc_layers_unittest.cc rename to media/gpu/vp9_svc_layers_unittest.cc index fb01ff9..0b441774 100644 --- a/media/gpu/vaapi/vp9_svc_layers_unittest.cc +++ b/media/gpu/vp9_svc_layers_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/gpu/vaapi/vp9_svc_layers.h" +#include "media/gpu/vp9_svc_layers.h" #include <algorithm> #include <array>
diff --git a/media/gpu/vaapi/vpx_rate_control.cc b/media/gpu/vpx_rate_control.cc similarity index 92% rename from media/gpu/vaapi/vpx_rate_control.cc rename to media/gpu/vpx_rate_control.cc index b26748a..931eba3 100644 --- a/media/gpu/vaapi/vpx_rate_control.cc +++ b/media/gpu/vpx_rate_control.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/gpu/vaapi/vpx_rate_control.h" +#include "media/gpu/vpx_rate_control.h" #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h"
diff --git a/media/gpu/vaapi/vpx_rate_control.h b/media/gpu/vpx_rate_control.h similarity index 92% rename from media/gpu/vaapi/vpx_rate_control.h rename to media/gpu/vpx_rate_control.h index 5615c90..61831d9 100644 --- a/media/gpu/vaapi/vpx_rate_control.h +++ b/media/gpu/vpx_rate_control.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_GPU_VAAPI_VPX_RATE_CONTROL_H_ -#define MEDIA_GPU_VAAPI_VPX_RATE_CONTROL_H_ +#ifndef MEDIA_GPU_VPX_RATE_CONTROL_H_ +#define MEDIA_GPU_VPX_RATE_CONTROL_H_ #include <memory> @@ -52,4 +52,4 @@ }; } // namespace media -#endif // MEDIA_GPU_VAAPI_VPX_RATE_CONTROL_H_ +#endif // MEDIA_GPU_VPX_RATE_CONTROL_H_
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index 4e763f7..977600b 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -279,8 +279,10 @@ if (pp_activate) { for (UINT32 i = 0; i < encoder_count; i++) { if (pp_activate[i]) { - if (populate_svc_info && IsSvcSupported(pp_activate[i])) + if (populate_svc_info && !svc_supported && + IsSvcSupported(pp_activate[i])) { svc_supported = true; + } // Release the enumerated instances if any. // According to Windows Dev Center,
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index ef2209a2..78f5db22 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -106,7 +106,7 @@ // stack about stream video quads. Investigate alternative solutions. if (use_stream_video_draw_quad || dcomp_surface) return VideoFrameResourceType::STREAM_TEXTURE; - FALLTHROUGH; + [[fallthrough]]; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_ARB: return (format == PIXEL_FORMAT_XRGB) @@ -166,7 +166,7 @@ case PIXEL_FORMAT_UYVY: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case PIXEL_FORMAT_YV12: case PIXEL_FORMAT_I422: case PIXEL_FORMAT_I444:
diff --git a/media/renderers/win/media_engine_notify_impl.cc b/media/renderers/win/media_engine_notify_impl.cc index 5852a50..e6ec827 100644 --- a/media/renderers/win/media_engine_notify_impl.cc +++ b/media/renderers/win/media_engine_notify_impl.cc
@@ -79,7 +79,7 @@ case MF_MEDIA_ENGINE_ERR_NETWORK: return PipelineStatus::PIPELINE_ERROR_NETWORK; case MF_MEDIA_ENGINE_ERR_DECODE: - FALLTHROUGH; + [[fallthrough]]; case MF_MEDIA_ENGINE_ERR_ENCRYPTED: return PipelineStatus::PIPELINE_ERROR_DECODE; case MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED:
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc index 6e4c619..6d2842d 100644 --- a/media/video/av1_video_encoder.cc +++ b/media/video/av1_video_encoder.cc
@@ -55,7 +55,8 @@ } EncoderStatus SetUpAomConfig(const VideoEncoder::Options& opts, - aom_codec_enc_cfg_t* config) { + aom_codec_enc_cfg_t& config, + aom_svc_params_t& svc_params) { if (opts.frame_size.width() <= 0 || opts.frame_size.height() <= 0) return EncoderStatus(EncoderStatus::Codes::kEncoderUnsupportedConfig, "Negative width or height values."); @@ -64,60 +65,100 @@ return EncoderStatus(EncoderStatus::Codes::kEncoderUnsupportedConfig, "Frame is too large."); - config->g_profile = 0; // main - config->g_input_bit_depth = 8; - config->g_pass = AOM_RC_ONE_PASS; - config->g_lag_in_frames = 0; - config->rc_max_quantizer = 56; - config->rc_min_quantizer = 10; - config->rc_dropframe_thresh = 0; // Don't drop frames + // Set up general config + config.g_profile = 0; // main + config.g_input_bit_depth = 8; + config.g_pass = AOM_RC_ONE_PASS; + config.g_lag_in_frames = 0; + config.rc_max_quantizer = 56; + config.rc_min_quantizer = 10; + config.rc_dropframe_thresh = 0; // Don't drop frames - config->rc_undershoot_pct = 50; - config->rc_overshoot_pct = 50; - config->rc_buf_initial_sz = 600; - config->rc_buf_optimal_sz = 600; - config->rc_buf_sz = 1000; - config->g_error_resilient = 0; + config.rc_undershoot_pct = 50; + config.rc_overshoot_pct = 50; + config.rc_buf_initial_sz = 600; + config.rc_buf_optimal_sz = 600; + config.rc_buf_sz = 1000; + config.g_error_resilient = 0; - config->g_timebase.num = 1; - config->g_timebase.den = base::Time::kMicrosecondsPerSecond; + config.g_timebase.num = 1; + config.g_timebase.den = base::Time::kMicrosecondsPerSecond; // Set the number of threads based on the image width and num of cores. - config->g_threads = GetNumberOfThreads(opts.frame_size.width()); + config.g_threads = GetNumberOfThreads(opts.frame_size.width()); // Insert keyframes at will with a given max interval if (opts.keyframe_interval.has_value()) { - config->kf_mode = AOM_KF_AUTO; - config->kf_min_dist = 0; - config->kf_max_dist = opts.keyframe_interval.value(); + config.kf_mode = AOM_KF_AUTO; + config.kf_min_dist = 0; + config.kf_max_dist = opts.keyframe_interval.value(); } if (opts.bitrate.has_value()) { auto& bitrate = opts.bitrate.value(); - config->rc_target_bitrate = bitrate.target() / 1000; + config.rc_target_bitrate = bitrate.target() / 1000; switch (bitrate.mode()) { case Bitrate::Mode::kVariable: - config->rc_end_usage = AOM_VBR; + config.rc_end_usage = AOM_VBR; break; case Bitrate::Mode::kConstant: - config->rc_end_usage = AOM_CBR; + config.rc_end_usage = AOM_CBR; break; } } else { // Default that gives about 2mbps to HD video - config->rc_end_usage = AOM_VBR; - config->rc_target_bitrate = + config.rc_end_usage = AOM_VBR; + config.rc_target_bitrate = int{(opts.frame_size.GetCheckedArea() * 2) .ValueOrDefault(std::numeric_limits<int>::max())}; } - config->g_w = opts.frame_size.width(); - config->g_h = opts.frame_size.height(); + config.g_w = opts.frame_size.width(); + config.g_h = opts.frame_size.height(); + // Setting up SVC parameters + svc_params = {}; + svc_params.framerate_factor[0] = 1; + svc_params.number_spatial_layers = 1; if (opts.scalability_mode.has_value()) { - return EncoderStatus(EncoderStatus::Codes::kEncoderUnsupportedConfig, - "Unsupported number of temporal layers."); + switch (opts.scalability_mode.value()) { + case SVCScalabilityMode::kL1T2: + svc_params.framerate_factor[0] = 2; + svc_params.framerate_factor[1] = 1; + svc_params.number_temporal_layers = 2; + // Bitrate allocation L0: 60% L1: 40% + svc_params.layer_target_bitrate[0] = + 60 * config.rc_target_bitrate / 100; + svc_params.layer_target_bitrate[1] = config.rc_target_bitrate; + break; + case SVCScalabilityMode::kL1T3: + svc_params.framerate_factor[0] = 4; + svc_params.framerate_factor[1] = 2; + svc_params.framerate_factor[2] = 1; + svc_params.number_temporal_layers = 3; + + // Bitrate allocation L0: 50% L1: 20% L2: 30% + svc_params.layer_target_bitrate[0] = + 50 * config.rc_target_bitrate / 100; + svc_params.layer_target_bitrate[1] = + 70 * config.rc_target_bitrate / 100; + svc_params.layer_target_bitrate[2] = config.rc_target_bitrate; + + break; + default: + return EncoderStatus( + EncoderStatus::Codes::kEncoderUnsupportedConfig, + "Unsupported configuration of scalability layers."); + } } + + for (int i = 0; i < svc_params.number_temporal_layers; ++i) { + svc_params.scaling_factor_num[i] = 1; + svc_params.scaling_factor_den[i] = 1; + svc_params.max_quantizers[i] = config.rc_max_quantizer; + svc_params.min_quantizers[i] = config.rc_min_quantizer; + } + return EncoderStatus::Codes::kOk; } @@ -135,7 +176,7 @@ return; } profile_ = profile; - if (profile < AV1PROFILE_MIN || profile > AV1PROFILE_MAX) { + if (profile != AV1PROFILE_PROFILE_MAIN) { std::move(done_cb).Run( EncoderStatus(EncoderStatus::Codes::kEncoderUnsupportedProfile) .WithData("profile", profile)); @@ -154,8 +195,11 @@ return; } - POST_STATUS_AND_RETURN_ON_FAILURE(SetUpAomConfig(options, &config_), - std::move(done_cb), ); + if (auto status = SetUpAomConfig(options, config_, svc_params_); + !status.is_ok()) { + std::move(done_cb).Run(std::move(status)); + return; + } // Initialize an encoder instance. aom_codec_unique_ptr codec(new aom_codec_ctx_t, FreeCodecCtx); @@ -203,6 +247,7 @@ CALL_AOM_CONTROL(AV1E_SET_ENABLE_ANGLE_DELTA, 0); CALL_AOM_CONTROL(AV1E_SET_ENABLE_FILTER_INTRA, 0); CALL_AOM_CONTROL(AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1); + CALL_AOM_CONTROL(AV1E_SET_SVC_PARAMS, &svc_params_); if (config_.rc_end_usage == AOM_CBR) CALL_AOM_CONTROL(AV1E_SET_AQ_MODE, 3); @@ -222,7 +267,6 @@ #undef CALL_AOM_CONTROL options_ = options; - originally_configured_size_ = options.frame_size; output_cb_ = BindToCurrentLoop(std::move(output_cb)); codec_ = std::move(codec); std::move(done_cb).Run(EncoderStatus::Codes::kOk); @@ -292,6 +336,7 @@ std::move(done_cb).Run( EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, "Can't allocate a resized frame.")); + return; } frame = std::move(resized_frame); } @@ -315,6 +360,12 @@ key_frame = true; } + auto temporal_id_status = AssignNextTemporalId(key_frame); + if (temporal_id_status.has_error()) { + std::move(done_cb).Run(std::move(temporal_id_status).error()); + return; + } + TRACE_EVENT0("media", "aom_codec_encode"); // Use artificial timestamps, so the encoder will not be misled by frame's // fickle timestamps when doing rate control. @@ -332,7 +383,8 @@ EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg)); return; } - DrainOutputs(frame->timestamp(), frame->ColorSpace()); + DrainOutputs(std::move(temporal_id_status).value(), frame->timestamp(), + frame->ColorSpace()); std::move(done_cb).Run(EncoderStatus::Codes::kOk); } @@ -345,9 +397,41 @@ EncoderStatus::Codes::kEncoderInitializeNeverCompleted); return; } - // TODO(crbug.com/1208280) Try to actually adjust setting instead of - // immediately dismissing configuration change. - std::move(done_cb).Run(EncoderStatus::Codes::kEncoderUnsupportedConfig); + + aom_codec_enc_cfg_t new_config = config_; + aom_svc_params_t new_svc_params; + if (auto status = SetUpAomConfig(options, new_config, new_svc_params); + !status.is_ok()) { + std::move(done_cb).Run(status); + return; + } + + auto error = aom_codec_enc_config_set(codec_.get(), &new_config); + if (error != AOM_CODEC_OK) { + std::move(done_cb).Run( + EncoderStatus(EncoderStatus::Codes::kEncoderUnsupportedConfig, + "Failed to set a new AOM config") + .WithData("error_code", error) + .WithData("error_message", aom_codec_err_to_string(error))); + return; + } + + error = aom_codec_control(codec_.get(), AV1E_SET_SVC_PARAMS, &new_svc_params); + if (error != AOM_CODEC_OK) { + std::move(done_cb).Run( + EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError, + "Setting AV1E_SET_SVC_PARAMS failed.") + .WithData("error_code", error) + .WithData("error_message", aom_codec_err_to_string(error))); + return; + } + + config_ = new_config; + svc_params_ = new_svc_params; + options_ = options; + if (!output_cb.is_null()) + output_cb_ = BindToCurrentLoop(std::move(output_cb)); + std::move(done_cb).Run(EncoderStatus::Codes::kOk); } base::TimeDelta Av1VideoEncoder::GetFrameDuration(const VideoFrame& frame) { @@ -367,7 +451,8 @@ return base::clamp(duration, min_duration, max_duration); } -void Av1VideoEncoder::DrainOutputs(base::TimeDelta ts, +void Av1VideoEncoder::DrainOutputs(int temporal_id, + base::TimeDelta ts, gfx::ColorSpace color_space) { const aom_codec_cx_pkt_t* pkt = nullptr; aom_codec_iter_t iter = nullptr; @@ -380,12 +465,64 @@ result.timestamp = ts; result.color_space = color_space; result.size = pkt->data.frame.sz; + + if (result.key_frame) { + // If we got an unexpected key frame, temporal_svc_frame_index needs to + // be adjusted, because the next frame should have index 1. + temporal_svc_frame_index_ = 1; + result.temporal_id = 0; + } else { + result.temporal_id = temporal_id; + } + result.data.reset(new uint8_t[result.size]); memcpy(result.data.get(), pkt->data.frame.buf, result.size); output_cb_.Run(std::move(result), {}); } } +EncoderStatus::Or<int> Av1VideoEncoder::AssignNextTemporalId(bool key_frame) { + if (svc_params_.number_temporal_layers < 2) + return 0; + + int temporal_id = 0; + if (key_frame) + temporal_svc_frame_index_ = 0; + + switch (svc_params_.number_temporal_layers) { + case 2: { + const static std::array<int, 2> kTwoTemporalLayers = {0, 1}; + temporal_id = kTwoTemporalLayers[temporal_svc_frame_index_ % + kTwoTemporalLayers.size()]; + break; + } + case 3: { + const static std::array<int, 4> kThreeTemporalLayers = {0, 2, 1, 2}; + temporal_id = kThreeTemporalLayers[temporal_svc_frame_index_ % + kThreeTemporalLayers.size()]; + break; + } + } + + temporal_svc_frame_index_++; + + aom_svc_layer_id_t layer_id = {}; + layer_id.temporal_layer_id = temporal_id; + + auto error = + aom_codec_control(codec_.get(), AV1E_SET_SVC_LAYER_ID, &layer_id); + if (error == AOM_CODEC_OK) + aom_codec_control(codec_.get(), AV1E_SET_ERROR_RESILIENT_MODE, + temporal_id > 0 ? 1 : 0); + if (error != AOM_CODEC_OK) { + auto msg = + base::StringPrintf("Set AV1E_SET_SVC_LAYER_ID error: %s (%d)", + aom_codec_error_detail(codec_.get()), codec_->err); + return EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg); + } + return temporal_id; +} + Av1VideoEncoder::~Av1VideoEncoder() = default; void Av1VideoEncoder::Flush(EncoderStatusCB done_cb) { @@ -397,7 +534,6 @@ } auto error = aom_codec_encode(codec_.get(), nullptr, 0, 0, 0); - if (error != AOM_CODEC_OK) { auto msg = base::StringPrintf("AOM encoding error: %s (%d)", @@ -407,7 +543,11 @@ EncoderStatus(EncoderStatus::Codes::kEncoderFailedEncode, msg)); return; } - DrainOutputs(base::TimeDelta(), gfx::ColorSpace()); + + // We don't call DrainOutputs() because Flush() is not expected to produce any + // outputs. The encoder configured with g_lag_in_frames = 0 and all outputs + // are drained after each Encode(). We might want to change this in the + // future, see: crbug.com/1280404 std::move(done_cb).Run(EncoderStatus::Codes::kOk); }
diff --git a/media/video/av1_video_encoder.h b/media/video/av1_video_encoder.h index 7a10b01..01a5eed 100644 --- a/media/video/av1_video_encoder.h +++ b/media/video/av1_video_encoder.h
@@ -13,6 +13,7 @@ #include "media/base/video_encoder.h" #include "media/base/video_frame_pool.h" #include "third_party/libaom/source/libaom/aom/aom_encoder.h" +#include "third_party/libaom/source/libaom/aom/aomcx.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" @@ -38,13 +39,17 @@ private: base::TimeDelta GetFrameDuration(const VideoFrame& frame); - void DrainOutputs(base::TimeDelta ts, gfx::ColorSpace color_space); + void DrainOutputs(int temporal_id, + base::TimeDelta ts, + gfx::ColorSpace color_space); + EncoderStatus::Or<int> AssignNextTemporalId(bool key_frame); using aom_codec_unique_ptr = std::unique_ptr<aom_codec_ctx_t, void (*)(aom_codec_ctx_t*)>; aom_codec_unique_ptr codec_; - aom_codec_enc_cfg_t config_; + aom_codec_enc_cfg_t config_ = {}; + aom_svc_params_t svc_params_ = {}; aom_image_t image_ = {}; // This is a timestamp that is always increasing by frame's duration. @@ -52,9 +57,9 @@ // coming from real frames. aom_codec_pts_t artificial_timestamp_ = 0; - gfx::Size originally_configured_size_; base::TimeDelta last_frame_timestamp_; gfx::ColorSpace last_frame_color_space_; + int temporal_svc_frame_index_ = 0; VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN; VideoFramePool frame_pool_;
diff --git a/media/video/h264_parser.cc b/media/video/h264_parser.cc index 1e7a658..588ae5d 100644 --- a/media/video/h264_parser.cc +++ b/media/video/h264_parser.cc
@@ -612,8 +612,19 @@ nalu->size = nalu_size_with_start_code - start_code_size; DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code; - // Initialize bit reader at the start of found NALU. - if (!br_.Initialize(nalu->data, nalu->size)) { + // Initialize bit reader at the start of the found NALU. Limit the NALU size + // in the bitstream reader to unencrypted data. + size_t clear_nalu_size = nalu->size; + const uint8_t* nalu_end = nalu->data + nalu->size; + for (size_t i = 0; i < encrypted_ranges_.size(); ++i) { + if (nalu_end <= encrypted_ranges_.start(i)) + break; + if (nalu_end <= encrypted_ranges_.end(i)) { + clear_nalu_size = encrypted_ranges_.start(i) - nalu->data; + break; + } + } + if (!br_.Initialize(nalu->data, clear_nalu_size)) { stream_ = nullptr; bytes_left_ = 0; return kEOStream;
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc index 2c5618f..2041aa9 100644 --- a/media/video/software_video_encoder_test.cc +++ b/media/video/software_video_encoder_test.cc
@@ -892,6 +892,19 @@ SoftwareVideoEncoderTest, ::testing::ValuesIn(kAv1Params), PrintTestParams); + +SwVideoTestParams kAv1SVCParams[] = { + {VideoCodec::kAV1, AV1PROFILE_PROFILE_MAIN, PIXEL_FORMAT_I420, + absl::nullopt}, + {VideoCodec::kAV1, AV1PROFILE_PROFILE_MAIN, PIXEL_FORMAT_I420, + SVCScalabilityMode::kL1T2}, + {VideoCodec::kAV1, AV1PROFILE_PROFILE_MAIN, PIXEL_FORMAT_I420, + SVCScalabilityMode::kL1T3}}; + +INSTANTIATE_TEST_SUITE_P(Av1TemporalSvc, + SVCVideoEncoderTest, + ::testing::ValuesIn(kAv1SVCParams), + PrintTestParams); #endif // ENABLE_LIBAOM GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(H264VideoEncoderTest);
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc index 662944c..bcd62e9 100644 --- a/mojo/core/node_controller.cc +++ b/mojo/core/node_controller.cc
@@ -1140,6 +1140,12 @@ const ports::NodeName& name) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + if (broker_name_ != ports::kInvalidNodeName) { + DLOG(ERROR) << "Ignoring OnRequestIntroduction on non-broker node."; + DropPeer(from_node, nullptr); + return; + } + scoped_refptr<NodeChannel> requestor = GetPeerChannel(from_node); if (from_node == name || name == ports::kInvalidNodeName || !requestor) { DLOG(ERROR) << "Rejecting invalid OnRequestIntroduction message from " @@ -1212,6 +1218,12 @@ Channel::MessagePtr message) { DCHECK(!message->has_handles()); + if (broker_name_ != ports::kInvalidNodeName) { + DLOG(ERROR) << "Ignoring OnBroadcast on non-broker node."; + DropPeer(from_node, nullptr); + return; + } + auto event = DeserializeEventMessage(from_node, std::move(message)); if (!event) { // We silently ignore unparseable events, as they may come from a process
diff --git a/mojo/public/cpp/base/thread_priority_mojom_traits.cc b/mojo/public/cpp/base/thread_priority_mojom_traits.cc index f8b88cd..7302780 100644 --- a/mojo/public/cpp/base/thread_priority_mojom_traits.cc +++ b/mojo/public/cpp/base/thread_priority_mojom_traits.cc
@@ -4,6 +4,9 @@ #include "mojo/public/cpp/base/thread_priority_mojom_traits.h" +#include "base/notreached.h" +#include "base/threading/platform_thread.h" + namespace mojo { // static @@ -45,4 +48,4 @@ return false; } -} // namespace mojo \ No newline at end of file +} // namespace mojo
diff --git a/mojo/public/cpp/base/thread_priority_unittest.cc b/mojo/public/cpp/base/thread_priority_unittest.cc index 115d757..431a677 100644 --- a/mojo/public/cpp/base/thread_priority_unittest.cc +++ b/mojo/public/cpp/base/thread_priority_unittest.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "mojo/public/cpp/base/thread_priority_mojom_traits.h" + +#include "base/threading/platform_thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo_base { @@ -28,4 +30,4 @@ } } // namespace thread_priority_unittest -} // namespace mojo_base \ No newline at end of file +} // namespace mojo_base
diff --git a/mojo/public/js/mojo_bindings_resources.grd b/mojo/public/js/mojo_bindings_resources.grd index 81073dd..e17c2d56 100644 --- a/mojo/public/js/mojo_bindings_resources.grd +++ b/mojo/public/js/mojo_bindings_resources.grd
@@ -65,6 +65,11 @@ use_base_dir="false" resource_path="mojo/mojo/public/mojom/base/read_only_buffer.mojom-webui.js" type="BINDATA" /> + <include name="IDR_MOJO_SAFE_BASE_NAME_MOJOM_WEBUI_JS" + file="${root_gen_dir}/mojom-webui/mojo/public/mojom/base/safe_base_name.mojom-webui.js" + use_base_dir="false" + resource_path="mojo/mojo/public/mojom/base/safe_base_name.mojom-webui.js" + type="BINDATA" /> <include name="IDR_MOJO_STRING16_MOJOM_HTML" file="${root_gen_dir}/mojo/public/mojom/base/string16.mojom.html" use_base_dir="false"
diff --git a/net/BUILD.gn b/net/BUILD.gn index e493e38..45963d5 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -423,6 +423,8 @@ "cookies/cookie_store.h", "cookies/cookie_util.cc", "cookies/cookie_util.h", + "cookies/first_party_set_metadata.cc", + "cookies/first_party_set_metadata.h", "cookies/parsed_cookie.cc", "cookies/parsed_cookie.h", "cookies/same_party_context.cc",
diff --git a/net/base/features.cc b/net/base/features.cc index 172d7de..43386ed 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -24,6 +24,9 @@ const base::Feature kCapReferrerToOriginOnCrossOrigin{ "CapReferrerToOriginOnCrossOrigin", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCookieDomainAttributeEmptyString{ + "CookieDomainAttributeEmptyString", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kDnsTransactionDynamicTimeouts{ "DnsTransactionDynamicTimeouts", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/net/base/features.h b/net/base/features.h index f3f8666..6edbfe16 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -34,6 +34,10 @@ // origin requests are restricted to contain at most the source origin. NET_EXPORT extern const base::Feature kCapReferrerToOriginOnCrossOrigin; +// When enabled, ParsedCookie will allow the domain attribute to be the +// empty string. +NET_EXPORT extern const base::Feature kCookieDomainAttributeEmptyString; + // Support for altering the parameters used for DNS transaction timeout. See // ResolveContext::SecureTransactionTimeout(). NET_EXPORT extern const base::Feature kDnsTransactionDynamicTimeouts;
diff --git a/net/base/platform_mime_util_mac.mm b/net/base/platform_mime_util_mac.mm index 17f597e..8801a7f 100644 --- a/net/base/platform_mime_util_mac.mm +++ b/net/base/platform_mime_util_mac.mm
@@ -66,31 +66,34 @@ void PlatformMimeUtil::GetPlatformExtensionsForMimeType( const std::string& mime_type, std::unordered_set<base::FilePath::StringType>* extensions) const { - base::ScopedCFTypeRef<CFArrayRef> exts_ref; - base::ScopedCFTypeRef<CFStringRef> mime_ref( base::SysUTF8ToCFStringRef(mime_type)); if (mime_ref) { - base::ScopedCFTypeRef<CFStringRef> uti( - UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime_ref, - nullptr)); - if (uti) { - exts_ref.reset( - UTTypeCopyAllTagsWithClass(uti, kUTTagClassFilenameExtension)); + bool extensions_found = false; + base::ScopedCFTypeRef<CFArrayRef> types(UTTypeCreateAllIdentifiersForTag( + kUTTagClassMIMEType, mime_ref, nullptr)); + if (types) { + for (CFIndex i = 0; i < CFArrayGetCount(types); i++) { + base::ScopedCFTypeRef<CFArrayRef> extensions_list( + UTTypeCopyAllTagsWithClass(base::mac::CFCast<CFStringRef>( + CFArrayGetValueAtIndex(types, i)), + kUTTagClassFilenameExtension)); + if (!extensions_list) + continue; + extensions_found = true; + for (NSString* extension in base::mac::CFToNSCast(extensions_list)) { + extensions->insert(base::SysNSStringToUTF8(extension)); + } + } } + if (extensions_found) + return; } - NSArray* extensions_list = base::mac::CFToNSCast(exts_ref); - - if (extensions_list) { - for (NSString* extension in extensions_list) - extensions->insert(base::SysNSStringToUTF8(extension)); - } else { - // Huh? Give up. - base::FilePath::StringType ext; - if (GetPlatformPreferredExtensionForMimeType(mime_type, &ext)) - extensions->insert(ext); - } + // Huh? Give up. + base::FilePath::StringType ext; + if (GetPlatformPreferredExtensionForMimeType(mime_type, &ext)) + extensions->insert(ext); } } // namespace net
diff --git a/net/cert/cert_status_flags.cc b/net/cert/cert_status_flags.cc index 64470e7..5476b69 100644 --- a/net/cert/cert_status_flags.cc +++ b/net/cert/cert_status_flags.cc
@@ -31,7 +31,7 @@ // We should not use ERR_CERT_CONTAINS_ERRORS in new code. case ERR_CERT_CONTAINS_ERRORS: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ERR_CERT_INVALID: return CERT_STATUS_INVALID; case ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
diff --git a/net/cert/internal/crl.cc b/net/cert/internal/crl.cc index 4da8000f..f7452a5 100644 --- a/net/cert/internal/crl.cc +++ b/net/cert/internal/crl.cc
@@ -368,6 +368,18 @@ const base::Time& verify_time, const base::TimeDelta& max_age) { DCHECK_LT(target_cert_index, valid_chain.size()); + + if (cert_dp.reasons) { + // Reason codes are not supported. If the distribution point contains a + // subset of reasons then skip it. We aren't interested in subsets of CRLs + // and the RFC states that there MUST be a CRL that covers all reasons. + return CRLRevocationStatus::UNKNOWN; + } + if (cert_dp.crl_issuer) { + // Indirect CRLs are not supported. + return CRLRevocationStatus::UNKNOWN; + } + const ParsedCertificate* target_cert = valid_chain[target_cert_index].get(); // 6.3.3 (a) Update the local CRL cache by obtaining a complete CRL, a @@ -418,10 +430,10 @@ // field in the complete CRL matches cRLIssuer in the DP and // that the complete CRL contains an issuing distribution // point extension with the indirectCRL boolean asserted. - if (cert_dp.has_crl_issuer) { - // Indirect CRLs are not supported. - return CRLRevocationStatus::UNKNOWN; - } + // + // Nothing is done here since distribution points with crlIssuer were skipped + // above. + // 6.3.3 (b) (1) Otherwise, verify that the CRL issuer matches the // certificate issuer. // @@ -477,8 +489,10 @@ // 5.2.5. The identical encoding MUST be used in the distributionPoint // fields of the certificate and the CRL. // TODO(https://crbug.com/749276): Check other name types? - if (!ContainsExactMatchingName( - cert_dp.uris, + if (!cert_dp.distribution_point_fullname || + !ContainsExactMatchingName( + cert_dp.distribution_point_fullname + ->uniform_resource_identifiers, distribution_point_names->uniform_resource_identifiers)) { return CRLRevocationStatus::UNKNOWN; }
diff --git a/net/cert/internal/parse_certificate.cc b/net/cert/internal/parse_certificate.cc index c2a26b45..840160d 100644 --- a/net/cert/internal/parse_certificate.cc +++ b/net/cert/internal/parse_certificate.cc
@@ -137,40 +137,42 @@ // Parses a DistributionPointName. // -// Currently this implementation is only concerned with URIs encoded in -// fullName and skips the rest (it does not fully parse the GeneralNames). -// -// URIs found in fullName are appended to |uris|. -// // From RFC 5280: // // DistributionPointName ::= CHOICE { // fullName [0] GeneralNames, // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } bool ParseDistributionPointName(const der::Input& dp_name, - std::vector<base::StringPiece>* uris) { - bool has_full_name; - der::Input der_full_name; - if (!der::Parser(dp_name).ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, &der_full_name, - &has_full_name)) { + ParsedDistributionPoint* distribution_point) { + der::Parser parser(dp_name); + absl::optional<der::Input> der_full_name; + if (!parser.ReadOptionalTag( + der::kTagContextSpecific | der::kTagConstructed | 0, + &der_full_name)) { return false; } - if (!has_full_name) { - // Only process DistributionPoints which provide "fullName". - return true; + if (der_full_name) { + // TODO(mattm): surface the CertErrors. + CertErrors errors; + distribution_point->distribution_point_fullname = + GeneralNames::CreateFromValue(*der_full_name, &errors); + if (!distribution_point->distribution_point_fullname) + return false; + return !parser.HasMore(); } - // TODO(mattm): surface the CertErrors. - CertErrors errors; - std::unique_ptr<GeneralNames> full_name = - GeneralNames::CreateFromValue(der_full_name, &errors); - if (!full_name) + if (!parser.ReadOptionalTag( + der::kTagContextSpecific | der::kTagConstructed | 1, + &distribution_point + ->distribution_point_name_relative_to_crl_issuer)) { return false; + } + if (distribution_point->distribution_point_name_relative_to_crl_issuer) { + return !parser.HasMore(); + } - // This code is only interested in extracting the URIs from fullName. - *uris = full_name->uniform_resource_identifiers; - return true; + // The CHOICE must contain either fullName or nameRelativeToCRLIssuer. + return false; } // RFC 5280, section 4.2.1.13. @@ -190,48 +192,37 @@ return false; // distributionPoint [0] DistributionPointName OPTIONAL, - bool distribution_point_present; - der::Input name; + absl::optional<der::Input> distribution_point_name; if (!distrib_point_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, &name, - &distribution_point_present)) { + der::kTagContextSpecific | der::kTagConstructed | 0, + &distribution_point_name)) { return false; } - if (!distribution_point_present) { - // Only process DistributionPoints which provide a "distributionPoint". - return true; + if (distribution_point_name && + !ParseDistributionPointName(*distribution_point_name, + &distribution_point)) { + return false; } // reasons [1] ReasonFlags OPTIONAL, - bool reasons_present; - if (!distrib_point_parser.SkipOptionalTag(der::kTagContextSpecific | 1, - &reasons_present)) { + if (!distrib_point_parser.ReadOptionalTag(der::kTagContextSpecific | 1, + &distribution_point.reasons)) { return false; } - // If it contains a subset of reasons then we skip it. We aren't - // interested in subsets of CRLs and the RFC states that there MUST be - // a CRL that covers all reasons. - if (reasons_present) { - return true; - } - - // Extract the URIs from the DistributionPointName. - if (!ParseDistributionPointName(name, &distribution_point.uris)) - return false; - // cRLIssuer [2] GeneralNames OPTIONAL } - bool crl_issuer_present; - der::Input crl_issuer; if (!distrib_point_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 2, &crl_issuer, - &crl_issuer_present)) { + der::kTagContextSpecific | der::kTagConstructed | 2, + &distribution_point.crl_issuer)) { return false; } + // TODO(eroman): Parse "cRLIssuer"? - distribution_point.has_crl_issuer = crl_issuer_present; - // TODO(eroman): Parse "cRLIssuer". + // RFC 5280, section 4.2.1.13: + // either distributionPoint or cRLIssuer MUST be present. + if (!distribution_point_name && !distribution_point.crl_issuer) + return false; if (distrib_point_parser.HasMore()) return false;
diff --git a/net/cert/internal/parse_certificate.h b/net/cert/internal/parse_certificate.h index d0858b5..9d1dff8 100644 --- a/net/cert/internal/parse_certificate.h +++ b/net/cert/internal/parse_certificate.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "net/base/net_export.h" +#include "net/cert/internal/general_names.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -517,8 +518,6 @@ std::vector<base::StringPiece>* out_ocsp_uris) WARN_UNUSED_RESULT; // ParsedDistributionPoint represents a parsed DistributionPoint from RFC 5280. -// It is simplified compared to that from RFC 5280 as it make assumptions about -// which OPTIONAL fields are present, and which CHOICEs are used. // // DistributionPoint ::= SEQUENCE { // distributionPoint [0] DistributionPointName OPTIONAL, @@ -529,30 +528,26 @@ ParsedDistributionPoint(ParsedDistributionPoint&& other); ~ParsedDistributionPoint(); - // The possibly-empty list of URIs from distributionPoint. - std::vector<base::StringPiece> uris; + // The parsed fullName, if distributionPoint was present and was a fullName. + std::unique_ptr<GeneralNames> distribution_point_fullname; - // TODO(eroman): Include the actual cRLIssuer. - bool has_crl_issuer = false; + // If present, the DER encoded value of the nameRelativeToCRLIssuer field. + // This should be a RelativeDistinguishedName, but the parser does not + // validate it. + absl::optional<der::Input> distribution_point_name_relative_to_crl_issuer; + + // If present, the DER encoded value of the reasons field. This should be a + // ReasonFlags bitString, but the parser does not validate it. + absl::optional<der::Input> reasons; + + // If present, the DER encoded value of the cRLIssuer field. This should be a + // GeneralNames, but the parser does not validate it. + absl::optional<der::Input> crl_issuer; }; // Parses the value of a CRL Distribution Points extension (sequence of // DistributionPoint). Return true on success, and fills |distribution_points| // with values that reference data in |distribution_points_tlv|. -// -// Some simplifications are made during parsing. -// -// * Skips DistributionPoints that lack a "distributionPoint" (name) field. -// -// * Skips DistributionPoints that contain a "reasons" field. This is -// reasonable under RFC 5280's profile which requires that conforming CAs -// "MUST include at least one DistributionPoint that points to a CRL that -// covers the certificate for all reasons". -// -// * Only parses URIs from the GeneralNames "distributionPoint". If the -// DistributionPoint uses "nameRelativeToCRLIssuer" rather than "fullName" it -// is skipped. And if "fullName" includes names ofther than -// "uniformResourceIdentifier" they are also skipped. NET_EXPORT bool ParseCrlDistributionPoints( const der::Input& distribution_points_tlv, std::vector<ParsedDistributionPoint>* distribution_points)
diff --git a/net/cert/internal/parse_certificate_unittest.cc b/net/cert/internal/parse_certificate_unittest.cc index 7badc0b5..c58cd8b 100644 --- a/net/cert/internal/parse_certificate_unittest.cc +++ b/net/cert/internal/parse_certificate_unittest.cc
@@ -6,6 +6,7 @@ #include "base/strings/stringprintf.h" #include "net/cert/internal/cert_errors.h" +#include "net/cert/internal/general_names.h" #include "net/cert/internal/parsed_certificate.h" #include "net/cert/internal/test_helpers.h" #include "net/der/input.h" @@ -463,9 +464,18 @@ ASSERT_EQ(1u, dps.size()); const ParsedDistributionPoint& dp1 = dps.front(); - EXPECT_FALSE(dp1.has_crl_issuer); - ASSERT_EQ(1u, dp1.uris.size()); - EXPECT_EQ(dp1.uris.front(), std::string("http://www.example.com/foo.crl")); + + ASSERT_TRUE(dp1.distribution_point_fullname); + const GeneralNames& fullname = *dp1.distribution_point_fullname; + EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER, + fullname.present_name_types); + ASSERT_EQ(1u, fullname.uniform_resource_identifiers.size()); + EXPECT_EQ(fullname.uniform_resource_identifiers.front(), + std::string("http://www.example.com/foo.crl")); + + EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer); + EXPECT_FALSE(dp1.reasons); + EXPECT_FALSE(dp1.crl_issuer); } TEST_F(ParseCrlDistributionPointsTest, ThreeUrisNoIssuer) { @@ -474,11 +484,22 @@ ASSERT_EQ(1u, dps.size()); const ParsedDistributionPoint& dp1 = dps.front(); - EXPECT_FALSE(dp1.has_crl_issuer); - ASSERT_EQ(3u, dp1.uris.size()); - EXPECT_EQ(dp1.uris[0], std::string("http://www.example.com/foo1.crl")); - EXPECT_EQ(dp1.uris[1], std::string("http://www.example.com/blah.crl")); - EXPECT_EQ(dp1.uris[2], std::string("not-even-a-url")); + + ASSERT_TRUE(dp1.distribution_point_fullname); + const GeneralNames& fullname = *dp1.distribution_point_fullname; + EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER, + fullname.present_name_types); + ASSERT_EQ(3u, fullname.uniform_resource_identifiers.size()); + EXPECT_EQ(fullname.uniform_resource_identifiers[0], + std::string("http://www.example.com/foo1.crl")); + EXPECT_EQ(fullname.uniform_resource_identifiers[1], + std::string("http://www.example.com/blah.crl")); + EXPECT_EQ(fullname.uniform_resource_identifiers[2], + std::string("not-even-a-url")); + + EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer); + EXPECT_FALSE(dp1.reasons); + EXPECT_FALSE(dp1.crl_issuer); } TEST_F(ParseCrlDistributionPointsTest, CrlIssuerAsDirname) { @@ -487,10 +508,42 @@ ASSERT_EQ(1u, dps.size()); const ParsedDistributionPoint& dp1 = dps.front(); - EXPECT_TRUE(dp1.has_crl_issuer); - // TODO(eroman): This has directory names under the fullName which are not - // being parsed or reflected here. - ASSERT_EQ(0u, dp1.uris.size()); + ASSERT_TRUE(dp1.distribution_point_fullname); + const GeneralNames& fullname = *dp1.distribution_point_fullname; + EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types); + // Generated by `ascii2der | xxd -i` from the Name value in + // crldp_issuer_as_dirname.pem. + const uint8_t kExpectedName[] = { + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x22, + 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x19, 0x69, 0x6e, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x52, 0x4c, 0x20, 0x43, 0x41, 0x33, + 0x20, 0x63, 0x52, 0x4c, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x31, 0x29, + 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x69, 0x6e, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x43, 0x52, 0x4c, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x52, + 0x4c, 0x20, 0x43, 0x41, 0x33}; + ASSERT_EQ(1u, fullname.directory_names.size()); + EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]); + + EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer); + EXPECT_FALSE(dp1.reasons); + + ASSERT_TRUE(dp1.crl_issuer); + // Generated by `ascii2der | xxd -i` from the cRLIssuer value in + // crldp_issuer_as_dirname.pem. + const uint8_t kExpectedCrlIssuer[] = { + 0xa4, 0x54, 0x30, 0x52, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x19, 0x69, 0x6e, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x43, 0x52, 0x4c, 0x20, 0x43, 0x41, 0x33, 0x20, + 0x63, 0x52, 0x4c, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72}; + EXPECT_EQ(der::Input(kExpectedCrlIssuer), dp1.crl_issuer); } TEST_F(ParseCrlDistributionPointsTest, FullnameAsDirname) { @@ -499,10 +552,206 @@ ASSERT_EQ(1u, dps.size()); const ParsedDistributionPoint& dp1 = dps.front(); - EXPECT_FALSE(dp1.has_crl_issuer); - // TODO(eroman): This has 1 directory name under the fullName which is not - // being reflected here. - ASSERT_EQ(0u, dp1.uris.size()); + + ASSERT_TRUE(dp1.distribution_point_fullname); + const GeneralNames& fullname = *dp1.distribution_point_fullname; + EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types); + // Generated by `ascii2der | xxd -i` from the Name value in + // crldp_full_name_as_dirname.pem. + const uint8_t kExpectedName[] = { + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x45, + 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x53, 0x65, 0x6c, + 0x66, 0x2d, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x20, 0x44, 0x50, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x61, 0x73, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x6c, 0x66, 0x2d, 0x49, 0x73, 0x73, 0x75, + 0x65, 0x64, 0x20, 0x43, 0x52, 0x4c, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, + 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x43, 0x41}; + ASSERT_EQ(1u, fullname.directory_names.size()); + EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]); + + EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer); + EXPECT_FALSE(dp1.reasons); + EXPECT_FALSE(dp1.crl_issuer); +} + +TEST_F(ParseCrlDistributionPointsTest, RelativeNameAndReasonsAndMultipleDPs) { + // SEQUENCE { + // SEQUENCE { + // # distributionPoint + // [0] { + // # nameRelativeToCRLIssuer + // [1] { + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // PrintableString { "CRL1" } + // } + // } + // } + // } + // # reasons + // [1 PRIMITIVE] { b`011` } + // } + // SEQUENCE { + // # distributionPoint + // [0] { + // # fullName + // [0] { + // [4] { + // SEQUENCE { + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // PrintableString { "CRL2" } + // } + // } + // } + // } + // } + // } + // # reasons + // [1 PRIMITIVE] { b`100111111` } + // } + // } + const uint8_t kInputDer[] = { + 0x30, 0x37, 0x30, 0x17, 0xa0, 0x11, 0xa1, 0x0f, 0x31, 0x0d, 0x30, 0x0b, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x43, 0x52, 0x4c, 0x31, 0x81, + 0x02, 0x05, 0x60, 0x30, 0x1c, 0xa0, 0x15, 0xa0, 0x13, 0xa4, 0x11, 0x30, + 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, + 0x43, 0x52, 0x4c, 0x32, 0x81, 0x03, 0x07, 0x9f, 0x80}; + + std::vector<ParsedDistributionPoint> dps; + ASSERT_TRUE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps)); + ASSERT_EQ(2u, dps.size()); + { + const ParsedDistributionPoint& dp = dps[0]; + EXPECT_FALSE(dp.distribution_point_fullname); + + ASSERT_TRUE(dp.distribution_point_name_relative_to_crl_issuer); + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // PrintableString { "CRL1" } + // } + // } + const uint8_t kExpectedRDN[] = {0x31, 0x0d, 0x30, 0x0b, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, + 0x04, 0x43, 0x52, 0x4c, 0x31}; + EXPECT_EQ(der::Input(kExpectedRDN), + *dp.distribution_point_name_relative_to_crl_issuer); + + ASSERT_TRUE(dp.reasons); + const uint8_t kExpectedReasons[] = {0x05, 0x60}; + EXPECT_EQ(der::Input(kExpectedReasons), *dp.reasons); + + EXPECT_FALSE(dp.crl_issuer); + } + { + const ParsedDistributionPoint& dp = dps[1]; + ASSERT_TRUE(dp.distribution_point_fullname); + const GeneralNames& fullname = *dp.distribution_point_fullname; + EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types); + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // PrintableString { "CRL2" } + // } + // } + const uint8_t kExpectedName[] = {0x31, 0x0d, 0x30, 0x0b, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, + 0x04, 0x43, 0x52, 0x4c, 0x32}; + ASSERT_EQ(1u, fullname.directory_names.size()); + EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]); + + EXPECT_FALSE(dp.distribution_point_name_relative_to_crl_issuer); + + ASSERT_TRUE(dp.reasons); + const uint8_t kExpectedReasons[] = {0x07, 0x9f, 0x80}; + EXPECT_EQ(der::Input(kExpectedReasons), *dp.reasons); + + EXPECT_FALSE(dp.crl_issuer); + } +} + +TEST_F(ParseCrlDistributionPointsTest, NoDistributionPointName) { + // SEQUENCE { + // SEQUENCE { + // # cRLIssuer + // [2] { + // [4] { + // SEQUENCE { + // SET { + // SEQUENCE { + // # organizationUnitName + // OBJECT_IDENTIFIER { 2.5.4.11 } + // PrintableString { "crl issuer" } + // } + // } + // } + // } + // } + // } + // } + const uint8_t kInputDer[] = {0x30, 0x1d, 0x30, 0x1b, 0xa2, 0x19, 0xa4, 0x17, + 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x63, 0x72, 0x6c, + 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72}; + + std::vector<ParsedDistributionPoint> dps; + ASSERT_TRUE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps)); + ASSERT_EQ(1u, dps.size()); + const ParsedDistributionPoint& dp = dps[0]; + EXPECT_FALSE(dp.distribution_point_fullname); + + EXPECT_FALSE(dp.distribution_point_name_relative_to_crl_issuer); + + EXPECT_FALSE(dp.reasons); + + ASSERT_TRUE(dp.crl_issuer); + const uint8_t kExpectedDer[] = {0xa4, 0x17, 0x30, 0x15, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x0a, 0x63, 0x72, 0x6c, 0x20, 0x69, 0x73, + 0x73, 0x75, 0x65, 0x72}; + EXPECT_EQ(der::Input(kExpectedDer), *dp.crl_issuer); +} + +TEST_F(ParseCrlDistributionPointsTest, OnlyReasons) { + // SEQUENCE { + // SEQUENCE { + // # reasons + // [1 PRIMITIVE] { b`011` } + // } + // } + const uint8_t kInputDer[] = {0x30, 0x06, 0x30, 0x04, 0x81, 0x02, 0x05, 0x60}; + + std::vector<ParsedDistributionPoint> dps; + EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps)); +} + +TEST_F(ParseCrlDistributionPointsTest, EmptyDistributionPoint) { + // SEQUENCE { + // SEQUENCE { + // } + // } + const uint8_t kInputDer[] = {0x30, 0x02, 0x30, 0x00}; + + std::vector<ParsedDistributionPoint> dps; + EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps)); +} + +TEST_F(ParseCrlDistributionPointsTest, EmptyDistributionPoints) { + // SEQUENCE { } + const uint8_t kInputDer[] = {0x30, 0x00}; + + std::vector<ParsedDistributionPoint> dps; + EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps)); } bool ParseAuthorityKeyIdentifierTestData(
diff --git a/net/cert/internal/path_builder_pkits_unittest.cc b/net/cert/internal/path_builder_pkits_unittest.cc index 2fa6b35c..437e8cd 100644 --- a/net/cert/internal/path_builder_pkits_unittest.cc +++ b/net/cert/internal/path_builder_pkits_unittest.cc
@@ -63,7 +63,7 @@ // points, this means a default-initialized ParsedDistributionPoint is // sufficient. ParsedDistributionPoint fake_cert_dp; - ParsedDistributionPoint* cert_dp = &fake_cert_dp; + const ParsedDistributionPoint* cert_dp = &fake_cert_dp; // If the target cert does have a distribution point, use it. std::vector<ParsedDistributionPoint> distribution_points; @@ -72,8 +72,22 @@ &crl_dp_extension)) { ASSERT_TRUE(ParseCrlDistributionPoints(crl_dp_extension.value, &distribution_points)); - ASSERT_LE(distribution_points.size(), 1U); - if (!distribution_points.empty()) + // TODO(mattm): some test cases (some of the 4.14.* onlySomeReasons + // tests)) have two CRLs and two distribution points, one point + // corresponding to each CRL. Should select the matching point for + // each CRL. (Doesn't matter currently since we don't support + // reasons.) + + // Look for a DistributionPoint without reasons. + for (const auto& dp : distribution_points) { + if (!dp.reasons) { + cert_dp = &dp; + break; + } + } + // If there were only DistributionPoints with reasons, just use the + // first one. + if (cert_dp == &fake_cert_dp && !distribution_points.empty()) cert_dp = &distribution_points[0]; }
diff --git a/net/cert/internal/revocation_checker.cc b/net/cert/internal/revocation_checker.cc index 7561095..158666f 100644 --- a/net/cert/internal/revocation_checker.cc +++ b/net/cert/internal/revocation_checker.cc
@@ -159,13 +159,29 @@ if (ParseCrlDistributionPoints(crl_dp_extension.value, &distribution_points)) { for (const auto& distribution_point : distribution_points) { - if (distribution_point.has_crl_issuer) { + if (distribution_point.crl_issuer) { // Ignore indirect CRLs (CRL where CRLissuer != cert issuer), which // are optional according to RFC 5280's profile. continue; } - for (const auto& crl_uri : distribution_point.uris) { + if (distribution_point.reasons) { + // Ignore CRLs that only contain some reasons. RFC 5280's profile + // requires that conforming CAs "MUST include at least one + // DistributionPoint that points to a CRL that covers the certificate + // for all reasons". + continue; + } + + if (!distribution_point.distribution_point_fullname) { + // Only distributionPoints with a fullName containing URIs are + // supported. + continue; + } + + for (const auto& crl_uri : + distribution_point.distribution_point_fullname + ->uniform_resource_identifiers) { // Only consider http:// URLs (https:// could create a circular // dependency). GURL parsed_crl_url(crl_uri);
diff --git a/net/cert/internal/revocation_checker_unittest.cc b/net/cert/internal/revocation_checker_unittest.cc index 817e467..19d71a2 100644 --- a/net/cert/internal/revocation_checker_unittest.cc +++ b/net/cert/internal/revocation_checker_unittest.cc
@@ -4,15 +4,642 @@ #include "net/cert/internal/revocation_checker.h" +#include "base/time/time.h" +#include "net/cert/internal/cert_errors.h" +#include "net/cert/internal/common_cert_errors.h" +#include "net/cert/internal/parse_certificate.h" +#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/mock_cert_net_fetcher.h" +#include "net/test/cert_builder.h" +#include "net/test/revocation_builder.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" namespace net { namespace { -// TODO(eroman): Add unit-tests. Currently exercising this code indirectly -// through tests in url_request_unittest.cc and -// cert_verify_proc_unittest.cc. +using ::testing::_; +using ::testing::ByMove; +using ::testing::Mock; +using ::testing::Return; +using ::testing::StrictMock; + +bool AddCertsToList(std::vector<CertBuilder*> builders, + ParsedCertificateList* out_certs) { + for (auto* builder : builders) { + if (!ParsedCertificate::CreateAndAddToVector( + builder->DupCertBuffer(), {}, out_certs, /*errors=*/nullptr)) { + return false; + } + } + return true; +} + +TEST(RevocationChecker, NoRevocationMechanism) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + + { + // Require revocation methods to be presented. + policy.allow_missing_info = false; + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kNoRevocationMechanism)); + } + + { + // Allow certs without revocation methods. + policy.allow_missing_info = true; + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); + } + + { + // Revocation checking disabled. + policy.check_revocation = false; + // Require revocation methods to be presented, but this does not matter if + // check_revocation is false. + policy.allow_missing_info = false; + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); + } +} + +TEST(RevocationChecker, ValidCRL) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kTestCrlUrl("http://example.com/crl1"); + leaf->SetCrlDistributionPointUrl(kTestCrlUrl); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.allow_missing_info = false; + policy.allow_unable_to_check = false; + + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + { + policy.networking_allowed = true; + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); + } + + { + policy.networking_allowed = false; + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kUnableToCheckRevocation)); + } +} + +TEST(RevocationChecker, RevokedCRL) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kTestCrlUrl("http://example.com/crl1"); + leaf->SetCrlDistributionPointUrl(kTestCrlUrl); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + + std::string crl_data_as_string_for_some_reason = BuildCrl( + root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{leaf->GetSerialNumber()}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + { + // These should have no effect on an affirmatively revoked response. + policy.allow_missing_info = false; + policy.allow_unable_to_check = false; + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kCertificateRevoked)); + } + + { + // These should have no effect on an affirmatively revoked response. + policy.allow_missing_info = true; + policy.allow_unable_to_check = true; + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kCertificateRevoked)); + } +} + +TEST(RevocationChecker, CRLRequestFails) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kTestCrlUrl("http://example.com/crl1"); + leaf->SetCrlDistributionPointUrl(kTestCrlUrl); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + + { + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return( + ByMove(MockCertNetFetcherRequest::Create(ERR_CONNECTION_FAILED)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kUnableToCheckRevocation)); + } + + { + policy.allow_unable_to_check = false; + policy.allow_missing_info = true; // Should have no effect. + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return( + ByMove(MockCertNetFetcherRequest::Create(ERR_CONNECTION_FAILED)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kUnableToCheckRevocation)); + } + + { + policy.allow_unable_to_check = true; + policy.allow_missing_info = false; + + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) + .WillOnce(Return( + ByMove(MockCertNetFetcherRequest::Create(ERR_CONNECTION_FAILED)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); + } +} + +TEST(RevocationChecker, CRLNonHttpUrl) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kTestCrlUrl("https://example.com/crl1"); + leaf->SetCrlDistributionPointUrl(kTestCrlUrl); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + // HTTPS CRL URLs should not be fetched. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kNoRevocationMechanism)); +} + +TEST(RevocationChecker, SkipEntireInvalidCRLDistributionPoints) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kSecondCrlUrl("http://www.example.com/bar.crl"); + + // SEQUENCE { + // # First distribution point: this is invalid, thus the entire + // # crlDistributionPoints extension should be ignored and revocation + // # checking should fail. + // SEQUENCE { + // [0] { + // [0] { + // # [9] is not a valid tag in GeneralNames + // [9 PRIMITIVE] { "foo" } + // } + // } + // } + // # Second distribution point. Even though this is an acceptable + // # distributionPoint, it should not be used. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/bar.crl" } + // } + // } + // } + // } + const uint8_t crldp[] = {0x30, 0x31, 0x30, 0x09, 0xa0, 0x07, 0xa0, 0x05, 0x89, + 0x03, 0x66, 0x6f, 0x6f, 0x30, 0x24, 0xa0, 0x22, 0xa0, + 0x20, 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x61, 0x72, 0x2e, 0x63, 0x72, 0x6c}; + leaf->SetExtension( + CrlDistributionPointsOid(), + std::string(reinterpret_cast<const char*>(crldp), std::size(crldp))); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + // Should fail since the entire cRLDistributionPoints extension was skipped + // and no other revocation method is present. + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + EXPECT_TRUE(errors.ContainsError(cert_errors::kNoRevocationMechanism)); +} + +TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithNonUriFullname) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kSecondCrlUrl("http://www.example.com/bar.crl"); + + // SEQUENCE { + // # First distribution point: this should be ignored since it has a non-URI + // # fullName field. + // SEQUENCE { + // [0] { + // [0] { + // [4] { + // SEQUENCE { + // SET { + // SEQUENCE { + // # countryName + // OBJECT_IDENTIFIER { 2.5.4.6 } + // PrintableString { "US" } + // } + // } + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // PrintableString { "foo" } + // } + // } + // } + // } + // } + // } + // } + // # Second distribution point. This should be used since it only has a + // # fullName URI. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/bar.crl" } + // } + // } + // } + // } + const uint8_t crldp[] = { + 0x30, 0x4b, 0x30, 0x23, 0xa0, 0x21, 0xa0, 0x1f, 0xa4, 0x1d, 0x30, + 0x1b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x30, 0x24, 0xa0, 0x22, 0xa0, + 0x20, 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x72, 0x2e, 0x63, 0x72, 0x6c}; + leaf->SetExtension( + CrlDistributionPointsOid(), + std::string(reinterpret_cast<const char*>(crldp), std::size(crldp))); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + // The first crldp should be skipped, the second should be retrieved. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kSecondCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); +} + +TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithReasons) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kSecondCrlUrl("http://www.example.com/bar.crl"); + + // SEQUENCE { + // # First distribution point: this should be ignored since it has a reasons + // # field. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/foo.crl" } + // } + // } + // # reasons + // [1 PRIMITIVE] { b`011` } + // } + // # Second distribution point. This should be used since it only has a + // # fullName URI. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/bar.crl" } + // } + // } + // } + // } + const uint8_t crldp[] = { + 0x30, 0x50, 0x30, 0x28, 0xa0, 0x22, 0xa0, 0x20, 0x86, 0x1e, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6f, 0x6f, + 0x2e, 0x63, 0x72, 0x6c, 0x81, 0x02, 0x05, 0x60, 0x30, 0x24, 0xa0, 0x22, + 0xa0, 0x20, 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x72, 0x2e, 0x63, 0x72, 0x6c}; + leaf->SetExtension( + CrlDistributionPointsOid(), + std::string(reinterpret_cast<const char*>(crldp), std::size(crldp))); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + // The first crldp should be skipped, the second should be retrieved. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kSecondCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); +} + +TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithCrlIssuer) { + std::unique_ptr<CertBuilder> leaf, root; + CertBuilder::CreateSimpleChain(&leaf, &root); + + const GURL kSecondCrlUrl("http://www.example.com/bar.crl"); + + // SEQUENCE { + // # First distribution point: this should be ignored since it has a + // crlIssuer field. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/foo.crl" } + // } + // } + // [2] { + // [4] { + // SEQUENCE { + // SET { + // SEQUENCE { + // # countryName + // OBJECT_IDENTIFIER { 2.5.4.6 } + // PrintableString { "US" } + // } + // } + // SET { + // SEQUENCE { + // # organizationName + // OBJECT_IDENTIFIER { 2.5.4.10 } + // PrintableString { "Test Certificates 2011" } + // } + // } + // SET { + // SEQUENCE { + // # organizationUnitName + // OBJECT_IDENTIFIER { 2.5.4.11 } + // PrintableString { "indirectCRL CA3 cRLIssuer" } + // } + // } + // } + // } + // } + // } + // # Second distribution point. This should be used since it only has a + // # fullName URI. + // SEQUENCE { + // [0] { + // [0] { + // [6 PRIMITIVE] { "http://www.example.com/bar.crl" } + // } + // } + // } + // } + const uint8_t crldp[] = { + 0x30, 0x81, 0xa4, 0x30, 0x7c, 0xa0, 0x22, 0xa0, 0x20, 0x86, 0x1e, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6f, + 0x6f, 0x2e, 0x63, 0x72, 0x6c, 0xa2, 0x56, 0xa4, 0x54, 0x30, 0x52, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x19, 0x69, 0x6e, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x43, 0x52, 0x4c, 0x20, 0x43, 0x41, 0x33, 0x20, + 0x63, 0x52, 0x4c, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x30, 0x24, 0xa0, + 0x22, 0xa0, 0x20, 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x72, 0x2e, 0x63, 0x72, 0x6c}; + leaf->SetExtension( + CrlDistributionPointsOid(), + std::string(reinterpret_cast<const char*>(crldp), std::size(crldp))); + + ParsedCertificateList chain; + ASSERT_TRUE(AddCertsToList({leaf.get(), root.get()}, &chain)); + + RevocationPolicy policy; + policy.check_revocation = true; + policy.networking_allowed = true; + policy.allow_unable_to_check = false; + policy.allow_missing_info = false; + + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), + crl_data_as_string_for_some_reason.end()); + + // The first crldp should be skipped, the second should be retrieved. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + EXPECT_CALL(*mock_fetcher, FetchCrl(kSecondCrlUrl, _, _)) + .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(crl_data)))); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_FALSE(errors.ContainsHighSeverityErrors()); +} + +// TODO(mattm): Add more unittests (deadlines, OCSP, stapled OCSP, CRLSets). +// Currently those features are exercised indirectly through tests in +// url_request_unittest.cc, cert_verify_proc_unittest.cc, etc. } // namespace
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index d0ee8ee6..73d06d3 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -516,17 +516,20 @@ if (parsed_cookie.IsSameParty()) base::UmaHistogramBoolean("Cookie.IsSamePartyValid", is_same_party_valid); - bool is_partitioned_valid = IsCookiePartitionedValid(parsed_cookie); + bool partition_has_nonce = CookiePartitionKey::HasNonce(cookie_partition_key); + bool is_partitioned_valid = + IsCookiePartitionedValid(parsed_cookie, partition_has_nonce); if (!is_partitioned_valid) { status->AddExclusionReason( CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED); } // Collect metrics on whether usage of the Partitioned attribute is correct. + // Do not include implicit nonce-based partitioned cookies in these metrics. if (parsed_cookie.IsPartitioned()) { base::UmaHistogramBoolean("Cookie.IsPartitionedValid", is_partitioned_valid); - } else { + } else if (!partition_has_nonce) { cookie_partition_key = absl::nullopt; } @@ -711,8 +714,8 @@ status->AddExclusionReason( net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY); } - if (!IsCookiePartitionedValid(partition_key.has_value(), prefix, - same_party)) { + if (!IsCookiePartitionedValid(partition_key.has_value(), prefix, same_party, + CookiePartitionKey::HasNonce(partition_key))) { status->AddExclusionReason( net::CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED); } @@ -1381,7 +1384,8 @@ if (!IsCookieSamePartyValid(same_party_, secure_, same_site_)) return false; - return IsCookiePartitionedValid(IsPartitioned(), prefix, same_party_); + return IsCookiePartitionedValid(IsPartitioned(), prefix, same_party_, + CookiePartitionKey::HasNonce(partition_key_)); } bool CanonicalCookie::IsEffectivelySameSiteNone( @@ -1518,19 +1522,23 @@ // static bool CanonicalCookie::IsCookiePartitionedValid( - const ParsedCookie& parsed_cookie) { - return IsCookiePartitionedValid(parsed_cookie.IsPartitioned(), - GetCookiePrefix(parsed_cookie.Name()), - parsed_cookie.IsSameParty()); + const ParsedCookie& parsed_cookie, + bool partition_has_nonce) { + return IsCookiePartitionedValid( + parsed_cookie.IsPartitioned(), GetCookiePrefix(parsed_cookie.Name()), + parsed_cookie.IsSameParty(), partition_has_nonce); } // static bool CanonicalCookie::IsCookiePartitionedValid( bool is_partitioned, CanonicalCookie::CookiePrefix prefix, - bool is_same_party) { + bool is_same_party, + bool partition_has_nonce) { if (!is_partitioned) return true; + if (partition_has_nonce) + return true; return prefix == CookiePrefix::COOKIE_PREFIX_HOST && !is_same_party; }
diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h index de7ce05..3d9faf4 100644 --- a/net/cookies/canonical_cookie.h +++ b/net/cookies/canonical_cookie.h
@@ -490,14 +490,16 @@ bool is_secure, CookieSameSite same_site); - // Returns false iff the cookie is a partitioned cookie that violates the - // semantics of the Partitioned attribute: + // Returns true iff the cookie is a partitioned cookie with a nonce or that + // does not violate the semantics of the Partitioned attribute: // - Cannot be SameParty // - Must have a __Host- prefix - static bool IsCookiePartitionedValid(const ParsedCookie& parsed_cookie); + static bool IsCookiePartitionedValid(const ParsedCookie& parsed_cookie, + bool partition_has_nonce); static bool IsCookiePartitionedValid(bool is_partitioned, CookiePrefix prefix, - bool is_same_party); + bool is_same_party, + bool partition_has_nonce); // Keep defaults here in sync with // services/network/public/interfaces/cookie_manager.mojom. @@ -514,10 +516,11 @@ CookiePriority priority_{COOKIE_PRIORITY_MEDIUM}; bool same_party_{false}; // This will be absl::nullopt for all cookies not set with the Partitioned - // attribute. If the value is non-null, then the cookie will only be delivered - // when the top-frame site matches the partition key. - // If the partition key is non-null and opaque, this means the Partitioned - // cookie was created on an opaque origin. + // attribute or without a nonce. If the value is non-null, then the cookie + // will only be delivered when the top-frame site matches the partition key + // and the nonce (if present). If the partition key is non-null and opaque, + // this means the Partitioned cookie was created on an opaque origin or with + // a nonce. absl::optional<CookiePartitionKey> partition_key_; CookieSourceScheme source_scheme_{CookieSourceScheme::kUnset}; // This can be [0,65535], PORT_UNSPECIFIED, or PORT_INVALID.
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc index 359312a..28dc4980 100644 --- a/net/cookies/canonical_cookie_unittest.cc +++ b/net/cookies/canonical_cookie_unittest.cc
@@ -341,6 +341,25 @@ EXPECT_EQ(cookie->SourcePort(), url::PORT_INVALID); } +// Test that a cookie string with an empty domain attribute generates a +// canonical host cookie. +TEST(CanonicalCookieTest, CreateHostCookieFromString) { + // Enable the feature flag for this test. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kCookieDomainAttributeEmptyString); + // Create a new canonical host cookie via empty string domain in the + // cookie_line. + GURL url("http://www.example.com/test/foo.html"); + base::Time creation_time = base::Time::Now(); + absl::optional<base::Time> server_time = absl::nullopt; + std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create( + url, "A=2; domain=; Secure", creation_time, server_time, + absl::nullopt /*cookie_partition_key*/)); + EXPECT_EQ("www.example.com", cookie->Domain()); + EXPECT_TRUE(cookie->IsHostCookie()); +} + TEST(CanonicalCookieTest, CreateNonStandardSameSite) { GURL url("http://www.example.com/test/foo.html"); base::Time now = base::Time::Now(); @@ -511,6 +530,29 @@ EXPECT_FALSE(cookie.get()); EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting( {CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED})); + + // Invalid Partitioned attribute: SameParty cookie but with a nonce. + auto partition_key_with_nonce = + absl::make_optional(CookiePartitionKey::FromURLForTesting( + GURL("https://toplevelsite.com"), base::UnguessableToken::Create())); + status = CookieInclusionStatus(); + cookie = CanonicalCookie::Create( + url, "A=2; Partitioned; Path=/; Secure; SameParty", creation_time, + server_time, partition_key_with_nonce, &status); + EXPECT_TRUE(cookie.get()); + EXPECT_TRUE(status.IsInclude()); + EXPECT_TRUE(cookie->IsPartitioned()); + EXPECT_EQ(partition_key_with_nonce, cookie->PartitionKey()); + + // No Partitioned attribute but with a nonce. + status = CookieInclusionStatus(); + cookie = + CanonicalCookie::Create(url, "__Host-A=2; Path=/; Secure", creation_time, + server_time, partition_key_with_nonce, &status); + EXPECT_TRUE(cookie.get()); + EXPECT_TRUE(status.IsInclude()); + EXPECT_TRUE(cookie->IsPartitioned()); + EXPECT_EQ(partition_key_with_nonce, cookie->PartitionKey()); } TEST(CanonicalCookieTest, CreateWithMaxAge) { @@ -1738,8 +1780,7 @@ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE)); // Same as default, but just to be explicit: options.set_same_party_context( - SamePartyContext(SamePartyContext::Type::kCrossParty, - FirstPartySetsContextType::kUnknown)); + SamePartyContext(SamePartyContext::Type::kCrossParty)); // Check that the most restrictive context is recognized and enforced. EXPECT_THAT( @@ -1768,7 +1809,7 @@ // but the next-most-restrictive variation would still be blocked. options.set_same_party_context(SamePartyContext( SamePartyContextType::kSameParty, SamePartyContextType::kCrossParty, - SamePartyContextType::kSameParty, FirstPartySetsContextType::kUnknown)); + SamePartyContextType::kSameParty)); EXPECT_THAT( same_site_none_cookie->IncludeForRequestURL( url, options, @@ -4441,8 +4482,7 @@ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE)); // Same as default, but just to be explicit: options.set_same_party_context( - SamePartyContext(SamePartyContext::Type::kCrossParty, - FirstPartySetsContextType::kUnknown)); + SamePartyContext(SamePartyContext::Type::kCrossParty)); EXPECT_THAT( same_site_none_cookie->IsSetPermittedInContext( url, options, @@ -4470,7 +4510,7 @@ // check that if we modify the cookie as indicated, the set would be allowed. options.set_same_party_context(SamePartyContext( SamePartyContextType::kSameParty, SamePartyContextType::kCrossParty, - SamePartyContextType::kSameParty, FirstPartySetsContextType::kUnknown)); + SamePartyContextType::kSameParty)); EXPECT_THAT( same_site_none_cookie->IsSetPermittedInContext( url, options, @@ -4570,8 +4610,8 @@ CookieOptions options; options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext( CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE)); - options.set_same_party_context(SamePartyContext( - SamePartyContext::Type::kSameParty, FirstPartySetsContextType::kUnknown)); + options.set_same_party_context( + SamePartyContext(SamePartyContext::Type::kSameParty)); { bool delegate_treats_url_as_trustworthy = false;
diff --git a/net/cookies/cookie_access_delegate.h b/net/cookies/cookie_access_delegate.h index 91bdd82b..5136c46 100644 --- a/net/cookies/cookie_access_delegate.h +++ b/net/cookies/cookie_access_delegate.h
@@ -12,6 +12,7 @@ #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_partition_key.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -47,10 +48,11 @@ const GURL& url, const SiteForCookies& site_for_cookies) const = 0; - // Returns the SamePartyContext indicating whether `site` is same-party - // with `party_context` and `top_frame_site`. If `top_frame_site` is nullptr, - // then `site` will be checked only against `party_context`. - virtual SamePartyContext ComputeSamePartyContext( + // Returns the metadata indicating whether `site` is same-party with + // `party_context` and `top_frame_site`; and `site`'s owner, if applicable.. + // If `top_frame_site` is nullptr, then `site` will be checked only against + // `party_context`. + virtual FirstPartySetMetadata ComputeFirstPartySetMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const = 0;
diff --git a/net/cookies/cookie_deletion_info.cc b/net/cookies/cookie_deletion_info.cc index 7ec22eb..ce3817f 100644 --- a/net/cookies/cookie_deletion_info.cc +++ b/net/cookies/cookie_deletion_info.cc
@@ -131,6 +131,11 @@ return false; } + if (cookie.IsPartitioned() && + !cookie_partition_key_collection.Contains(*cookie.PartitionKey())) { + return false; + } + return true; }
diff --git a/net/cookies/cookie_deletion_info.h b/net/cookies/cookie_deletion_info.h index 30c46a63c..5158f452 100644 --- a/net/cookies/cookie_deletion_info.h +++ b/net/cookies/cookie_deletion_info.h
@@ -11,6 +11,7 @@ #include "base/time/time.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_constants.h" +#include "net/cookies/cookie_partition_key_collection.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace net { @@ -139,6 +140,12 @@ // Used only for testing purposes. absl::optional<std::string> value_for_testing; + + // Cookie partition keychain. Partitioned cookies are not deleted if their + // partition key is not in the keychain. By default, it clears cookies in all + // partitions. + CookiePartitionKeyCollection cookie_partition_key_collection = + CookiePartitionKeyCollection::ContainsAll(); }; } // namespace net
diff --git a/net/cookies/cookie_deletion_info_unittest.cc b/net/cookies/cookie_deletion_info_unittest.cc index d408ceeec..f316103 100644 --- a/net/cookies/cookie_deletion_info_unittest.cc +++ b/net/cookies/cookie_deletion_info_unittest.cc
@@ -507,10 +507,10 @@ // the IncludeForRequestURL call uses CookieOptions::MakeAllInclusive). TEST(CookieDeletionInfoTest, MatchesWithCookieAccessSemantics) { // Cookie with unspecified SameSite. - auto cookie = CanonicalCookie::Create( - GURL("https://www.example.com"), "cookie=1", base::Time::Now(), - absl::nullopt /* server_time */, - absl::nullopt /* cookie_partition_key */); + auto cookie = CanonicalCookie::Create(GURL("https://www.example.com"), + "cookie=1", base::Time::Now(), + /*server_time=*/absl::nullopt, + /*cookie_partition_key=*/absl::nullopt); CookieDeletionInfo delete_info; delete_info.url = GURL("https://www.example.com/path"); @@ -531,4 +531,64 @@ CookieSamePartyStatus::kNoSamePartyEnforcement})); } +TEST(CookieDeletionInfoTest, MatchesCookiePartitionKeyCollection) { + const CookiePartitionKey kPartitionKey = + CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")); + const CookiePartitionKey kOtherPartitionKey = + CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")); + const CookiePartitionKeyCollection kEmptyKeychain; + const CookiePartitionKeyCollection kSingletonKeychain(kPartitionKey); + const CookiePartitionKeyCollection kMultipleKeysKeychain( + {kPartitionKey, kOtherPartitionKey}); + const CookiePartitionKeyCollection kAllKeysKeychain = + CookiePartitionKeyCollection::ContainsAll(); + const absl::optional<CookiePartitionKey> kPartitionKeyOpt = + absl::make_optional(kPartitionKey); + const CookiePartitionKeyCollection kOtherKeySingletonKeychain( + kOtherPartitionKey); + + struct TestCase { + const std::string desc; + const CookiePartitionKeyCollection filter_cookie_partition_key_collection; + const absl::optional<CookiePartitionKey> cookie_partition_key; + bool expects_match; + } test_cases[] = { + // Unpartitioned cookie always matches + {"Unpartitioned empty keychain", kEmptyKeychain, absl::nullopt, true}, + {"Unpartitioned singleton keychain", kSingletonKeychain, absl::nullopt, + true}, + {"Unpartitioned multiple keys", kMultipleKeysKeychain, absl::nullopt, + true}, + {"Unpartitioned all keys", kAllKeysKeychain, absl::nullopt, true}, + // Partitioned cookie only matches keychains which contain its partition + // key. + {"Partitioned empty keychain", kEmptyKeychain, kPartitionKeyOpt, false}, + {"Partitioned singleton keychain", kSingletonKeychain, kPartitionKeyOpt, + true}, + {"Partitioned multiple keys", kMultipleKeysKeychain, kPartitionKeyOpt, + true}, + {"Partitioned all keys", kAllKeysKeychain, kPartitionKeyOpt, true}, + {"Partitioned mismatched keys", kOtherKeySingletonKeychain, + kPartitionKeyOpt, false}, + }; + + for (const auto& test_case : test_cases) { + SCOPED_TRACE(test_case.desc); + auto cookie = CanonicalCookie::Create( + GURL("https://www.example.com"), + "__Host-foo=bar; Secure; Path=/; Partitioned", base::Time::Now(), + /*server_time=*/absl::nullopt, test_case.cookie_partition_key); + CookieDeletionInfo delete_info; + delete_info.cookie_partition_key_collection = + test_case.filter_cookie_partition_key_collection; + EXPECT_EQ( + test_case.expects_match, + delete_info.Matches( + *cookie, CookieAccessParams{ + net::CookieAccessSemantics::UNKNOWN, + /*delegate_treats_url_as_trustworthy=*/false, + CookieSamePartyStatus::kNoSamePartyEnforcement})); + } +} + } // namespace net
diff --git a/net/cookies/cookie_partition_key.h b/net/cookies/cookie_partition_key.h index 620fb1ed..bedc838 100644 --- a/net/cookies/cookie_partition_key.h +++ b/net/cookies/cookie_partition_key.h
@@ -105,6 +105,10 @@ const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; } + static bool HasNonce(const absl::optional<CookiePartitionKey>& key) { + return key && key->nonce(); + } + private: explicit CookiePartitionKey(const SchemefulSite& site, absl::optional<base::UnguessableToken> nonce);
diff --git a/net/cookies/cookie_partition_key_collection.cc b/net/cookies/cookie_partition_key_collection.cc index 9882324..1734393 100644 --- a/net/cookies/cookie_partition_key_collection.cc +++ b/net/cookies/cookie_partition_key_collection.cc
@@ -4,6 +4,9 @@ #include "net/cookies/cookie_partition_key_collection.h" +#include "base/containers/contains.h" +#include "net/cookies/cookie_access_delegate.h" + namespace net { CookiePartitionKeyCollection::CookiePartitionKeyCollection() = default; @@ -24,8 +27,8 @@ : keys_(keys) {} CookiePartitionKeyCollection::CookiePartitionKeyCollection( - bool contains_all_keys_) - : contains_all_keys_(contains_all_keys_) {} + bool contains_all_keys) + : contains_all_keys_(contains_all_keys) {} CookiePartitionKeyCollection& CookiePartitionKeyCollection::operator=( const CookiePartitionKeyCollection& other) = default; @@ -54,4 +57,9 @@ return CookiePartitionKeyCollection(keys); } +bool CookiePartitionKeyCollection::Contains( + const CookiePartitionKey& key) const { + return contains_all_keys_ || base::Contains(keys_, key); +} + } // namespace net
diff --git a/net/cookies/cookie_partition_key_collection.h b/net/cookies/cookie_partition_key_collection.h index 58f8b9e..95005616 100644 --- a/net/cookies/cookie_partition_key_collection.h +++ b/net/cookies/cookie_partition_key_collection.h
@@ -8,11 +8,12 @@ #include <vector> #include "net/base/net_export.h" -#include "net/cookies/cookie_access_delegate.h" #include "net/cookies/cookie_partition_key.h" namespace net { +class CookieAccessDelegate; + // A data structure used to represent a collection of cookie partition keys. // // It can represent all possible cookie partition keys when @@ -23,7 +24,7 @@ class NET_EXPORT CookiePartitionKeyCollection { public: // Creates an empty key collection. - explicit CookiePartitionKeyCollection(); + CookiePartitionKeyCollection(); CookiePartitionKeyCollection(const CookiePartitionKeyCollection& other); CookiePartitionKeyCollection(CookiePartitionKeyCollection&& other); // Creates a key collection with a single element. @@ -81,8 +82,11 @@ return keys_; } + // Returns true if the collection contains the passed key. + bool Contains(const CookiePartitionKey& key) const; + private: - explicit CookiePartitionKeyCollection(bool contains_all_keys_); + explicit CookiePartitionKeyCollection(bool contains_all_keys); bool contains_all_keys_ = false; // If `contains_all_keys_` is true, `keys_` must be empty.
diff --git a/net/cookies/cookie_partition_key_collection_unittest.cc b/net/cookies/cookie_partition_key_collection_unittest.cc index 20fbc12f..8813279 100644 --- a/net/cookies/cookie_partition_key_collection_unittest.cc +++ b/net/cookies/cookie_partition_key_collection_unittest.cc
@@ -135,4 +135,34 @@ EXPECT_EQ(kNonMemberPartitionKey, got.PartitionKeys()[1]); } +TEST(CookiePartitionKeyCollectionTest, Contains) { + const CookiePartitionKey kPartitionKey = + CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")); + const CookiePartitionKey kOtherPartitionKey = + CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")); + + struct TestCase { + const CookiePartitionKeyCollection keychain; + const CookiePartitionKey key; + bool expects_contains; + } test_cases[] = { + // Empty keychain + {CookiePartitionKeyCollection(), kPartitionKey, false}, + // Singleton keychain with key + {CookiePartitionKeyCollection(kPartitionKey), kPartitionKey, true}, + // Singleton keychain with different key + {CookiePartitionKeyCollection(kOtherPartitionKey), kPartitionKey, false}, + // Multiple keys + {CookiePartitionKeyCollection({kPartitionKey, kOtherPartitionKey}), + kPartitionKey, true}, + // Contains all keys + {CookiePartitionKeyCollection::ContainsAll(), kPartitionKey, true}, + }; + + for (const auto& test_case : test_cases) { + EXPECT_EQ(test_case.expects_contains, + test_case.keychain.Contains(test_case.key)); + } +} + } // namespace net
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc index 02b1a28..b04f3d7 100644 --- a/net/cookies/cookie_util.cc +++ b/net/cookies/cookie_util.cc
@@ -30,6 +30,7 @@ #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_monster.h" #include "net/cookies/cookie_options.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "net/http/http_util.h" #include "url/gurl.h" @@ -741,18 +742,17 @@ return base::FeatureList::IsEnabled(features::kFirstPartySets); } -// Return SamePartyCookieContextType::kCrossParty when: -// 1) `isolation_info` is not fully populated. -// 2) `isolation_info.party_context` is null. -// 3) `cookie_access_delegate.IsContextSamePartyWithSite` returns false. -SamePartyContext ComputeSamePartyContext( +// Returns First-Party Set metadata for the given context. Returns empty/default +// metadata if `isolation_info` is not fully populated, or +// `isolation_info.party_context` is nullopt. +FirstPartySetMetadata ComputeFirstPartySetMetadata( const SchemefulSite& request_site, const IsolationInfo& isolation_info, const CookieAccessDelegate* cookie_access_delegate, bool force_ignore_top_frame_party) { if (!isolation_info.IsEmpty() && isolation_info.party_context().has_value() && cookie_access_delegate) { - return cookie_access_delegate->ComputeSamePartyContext( + return cookie_access_delegate->ComputeFirstPartySetMetadata( request_site, force_ignore_top_frame_party ? nullptr @@ -761,7 +761,7 @@ isolation_info.party_context().value()); } - return SamePartyContext(); + return FirstPartySetMetadata(); } CookieSamePartyStatus GetSamePartyStatus(const CanonicalCookie& cookie,
diff --git a/net/cookies/cookie_util.h b/net/cookies/cookie_util.h index 1a9374e..a149a64f 100644 --- a/net/cookies/cookie_util.h +++ b/net/cookies/cookie_util.h
@@ -15,6 +15,7 @@ #include "net/cookies/cookie_access_result.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_options.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/site_for_cookies.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/origin.h" @@ -239,16 +240,16 @@ NET_EXPORT bool IsSchemefulSameSiteEnabled(); NET_EXPORT bool IsFirstPartySetsEnabled(); -// Computes the SameParty context bundle, determining which of the cookies for +// Computes the First-Party Sets metadata, determining which of the cookies for // `request_site` can be accessed. `isolation_info` must be fully populated. If // `force_ignore_top_frame_party` is true, the top frame from `isolation_info` // will be assumed to be same-party with `request_site`, regardless of what it // is. -NET_EXPORT SamePartyContext -ComputeSamePartyContext(const SchemefulSite& request_site, - const IsolationInfo& isolation_info, - const CookieAccessDelegate* cookie_access_delegate, - bool force_ignore_top_frame_party); +NET_EXPORT FirstPartySetMetadata +ComputeFirstPartySetMetadata(const SchemefulSite& request_site, + const IsolationInfo& isolation_info, + const CookieAccessDelegate* cookie_access_delegate, + bool force_ignore_top_frame_party); // Get the SameParty inclusion status. If the cookie is not SameParty, returns // kNoSamePartyEnforcement; if the cookie is SameParty but does not have a
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc index 7cb9d97..a8a411eb 100644 --- a/net/cookies/cookie_util_unittest.cc +++ b/net/cookies/cookie_util_unittest.cc
@@ -1502,8 +1502,8 @@ secure, httponly, same_site, CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party); - options.set_same_party_context(SamePartyContext( - party_context_type, FirstPartySetsContextType::kUnknown)); + options.set_same_party_context( + SamePartyContext(party_context_type)); EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, cookie_util::GetSamePartyStatus(*cookie, options)); } @@ -1539,8 +1539,8 @@ secure, httponly, same_site, CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party); - options.set_same_party_context(SamePartyContext( - party_context_type, FirstPartySetsContextType::kUnknown)); + options.set_same_party_context( + SamePartyContext(party_context_type)); EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, cookie_util::GetSamePartyStatus(*cookie, options)); } @@ -1575,8 +1575,7 @@ httponly, same_site, CookiePriority::COOKIE_PRIORITY_DEFAULT, false /* same_party */); - options.set_same_party_context(SamePartyContext( - party_context_type, FirstPartySetsContextType::kUnknown)); + options.set_same_party_context(SamePartyContext(party_context_type)); EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, cookie_util::GetSamePartyStatus(*cookie, options)); } @@ -1634,14 +1633,12 @@ true /* same_party */); options.set_same_party_context( - SamePartyContext(SamePartyContext::Type::kCrossParty, - FirstPartySetsContextType::kUnknown)); + SamePartyContext(SamePartyContext::Type::kCrossParty)); EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyExclude, cookie_util::GetSamePartyStatus(*cookie, options)); options.set_same_party_context( - SamePartyContext(SamePartyContext::Type::kSameParty, - FirstPartySetsContextType::kUnknown)); + SamePartyContext(SamePartyContext::Type::kSameParty)); EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyInclude, cookie_util::GetSamePartyStatus(*cookie, options)); }
diff --git a/net/cookies/first_party_set_metadata.cc b/net/cookies/first_party_set_metadata.cc new file mode 100644 index 0000000..1a63e6f --- /dev/null +++ b/net/cookies/first_party_set_metadata.cc
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/cookies/first_party_set_metadata.h" + +#include <tuple> + +#include "base/stl_util.h" +#include "net/cookies/cookie_constants.h" + +namespace net { + +FirstPartySetMetadata::FirstPartySetMetadata() = default; +FirstPartySetMetadata::FirstPartySetMetadata( + const SamePartyContext& context, + const SchemefulSite* owner, + FirstPartySetsContextType first_party_sets_context_type) + : context_(context), + owner_(base::OptionalFromPtr(owner)), + first_party_sets_context_type_(first_party_sets_context_type) {} + +FirstPartySetMetadata::FirstPartySetMetadata(FirstPartySetMetadata&&) = default; +FirstPartySetMetadata& FirstPartySetMetadata::operator=( + FirstPartySetMetadata&&) = default; + +FirstPartySetMetadata::~FirstPartySetMetadata() = default; + +bool FirstPartySetMetadata::operator==( + const FirstPartySetMetadata& other) const { + return std::make_tuple(context(), owner(), first_party_sets_context_type()) == + std::make_tuple(other.context(), other.owner(), + other.first_party_sets_context_type()); +} + +std::ostream& operator<<(std::ostream& os, const FirstPartySetMetadata& fpsm) { + os << "{" << fpsm.context() << ", " << base::OptionalOrNullptr(fpsm.owner()) + << ", " << static_cast<int>(fpsm.first_party_sets_context_type()) << "}"; + return os; +} + +} // namespace net
diff --git a/net/cookies/first_party_set_metadata.h b/net/cookies/first_party_set_metadata.h new file mode 100644 index 0000000..f8ec4229 --- /dev/null +++ b/net/cookies/first_party_set_metadata.h
@@ -0,0 +1,59 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_COOKIES_FIRST_PARTY_SET_METADATA_H_ +#define NET_COOKIES_FIRST_PARTY_SET_METADATA_H_ + +#include "base/stl_util.h" +#include "net/base/net_export.h" +#include "net/base/schemeful_site.h" +#include "net/cookies/same_party_context.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace net { + +// This class bundles together metadata about the First-Party Set associated +// with a given context. +class NET_EXPORT FirstPartySetMetadata { + public: + FirstPartySetMetadata(); + + // `owner` must live for the duration of the ctor; nullptr indicates that + // there's no First-Party Set that's associated with the current frame in the + // given context. + FirstPartySetMetadata( + const SamePartyContext& context, + const SchemefulSite* owner, + FirstPartySetsContextType first_party_sets_context_type); + + FirstPartySetMetadata(FirstPartySetMetadata&&); + FirstPartySetMetadata& operator=(FirstPartySetMetadata&&); + + ~FirstPartySetMetadata(); + + bool operator==(const FirstPartySetMetadata& other) const; + + const SamePartyContext& context() const { return context_; } + + // Returns a optional<T>& instead of a T* so that operator== can be defined + // more easily. + const absl::optional<SchemefulSite>& owner() const { return owner_; } + + FirstPartySetsContextType first_party_sets_context_type() const { + return first_party_sets_context_type_; + } + + private: + SamePartyContext context_ = SamePartyContext(); + absl::optional<SchemefulSite> owner_ = absl::nullopt; + FirstPartySetsContextType first_party_sets_context_type_ = + FirstPartySetsContextType::kUnknown; +}; + +NET_EXPORT std::ostream& operator<<(std::ostream& os, + const FirstPartySetMetadata& fpsm); + +} // namespace net + +#endif // NET_COOKIES_FIRST_PARTY_SET_METADATA_H_
diff --git a/net/cookies/parsed_cookie.cc b/net/cookies/parsed_cookie.cc index 26c8bd2..f183438 100644 --- a/net/cookies/parsed_cookie.cc +++ b/net/cookies/parsed_cookie.cc
@@ -765,7 +765,7 @@ } void ParsedCookie::SetupAttributes() { - // For UMA_HISTOGRAMS below + // For the UMA_HISTOGRAMS below. int domain_count = std::count_if(pairs_.begin(), pairs_.end(), [](const std::pair<std::string, std::string>& pair) { @@ -776,14 +776,19 @@ if (pairs_[i].first == kPathTokenName) { path_index_ = i; } else if (pairs_[i].first == kDomainTokenName) { + // Record usage metrics for the empty string domain. UMA_HISTOGRAM_BOOLEAN( "Cookie.EmptyDomain.SetupAttributes.Single", (domain_count == 1) && (pairs_[i].second == std::string())); UMA_HISTOGRAM_BOOLEAN( "Cookie.EmptyDomain.SetupAttributes.Multiple", (domain_count > 1) && (pairs_[i].second == std::string())); - if (pairs_[i].second != "") + // Domain can be the empty string if the flag is enabled. + if (base::FeatureList::IsEnabled( + features::kCookieDomainAttributeEmptyString) || + pairs_[i].second != "") { domain_index_ = i; + } } else if (pairs_[i].first == kExpiresTokenName) { expires_index_ = i; } else if (pairs_[i].first == kMaxAgeTokenName) {
diff --git a/net/cookies/parsed_cookie.h b/net/cookies/parsed_cookie.h index cdad3939..8708864b 100644 --- a/net/cookies/parsed_cookie.h +++ b/net/cookies/parsed_cookie.h
@@ -62,6 +62,9 @@ DCHECK(HasPath()); return pairs_[path_index_].second; } + // Note that Domain() may return the empty string; in the case of cookie_line + // "domain=", HasDomain() will return true (as the empty string is an + // acceptable domain value), so Domain() will return std::string(). bool HasDomain() const { return domain_index_ != 0; } const std::string& Domain() const { DCHECK(HasDomain());
diff --git a/net/cookies/parsed_cookie_unittest.cc b/net/cookies/parsed_cookie_unittest.cc index fe8ccba..a2a265fa 100644 --- a/net/cookies/parsed_cookie_unittest.cc +++ b/net/cookies/parsed_cookie_unittest.cc
@@ -875,15 +875,27 @@ EXPECT_FALSE(pc.IsPartitioned()); } +// Setting the domain attribute to the empty string should be valid. +TEST(ParsedCookieTest, EmptyDomainAttributeValid) { + // Enable the feature flag for this test. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kCookieDomainAttributeEmptyString); + ParsedCookie pc("name=value; domain="); + EXPECT_TRUE(pc.IsValid()); +} + // Set the domain attribute twice in a cookie line. If the second attribute's -// value is empty, it shoud be ignored. -// -// This is de facto standard behavior, per https://crbug.com/601786. +// value is empty, it should equal the empty string. TEST(ParsedCookieTest, MultipleDomainAttributes) { + // Enable the feature flag for this test. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kCookieDomainAttributeEmptyString); ParsedCookie pc1("name=value; domain=foo.com; domain=bar.com"); EXPECT_EQ("bar.com", pc1.Domain()); ParsedCookie pc2("name=value; domain=foo.com; domain="); - EXPECT_EQ("foo.com", pc2.Domain()); + EXPECT_EQ(std::string(), pc2.Domain()); } TEST(ParsedCookieTest, SetPriority) {
diff --git a/net/cookies/same_party_context.cc b/net/cookies/same_party_context.cc index d045a7d..d531652 100644 --- a/net/cookies/same_party_context.cc +++ b/net/cookies/same_party_context.cc
@@ -10,34 +10,33 @@ namespace net { -SamePartyContext::SamePartyContext( - Type type, - FirstPartySetsContextType first_party_sets_context_type) - : SamePartyContext(type, type, type, first_party_sets_context_type) {} +SamePartyContext::SamePartyContext(Type type) + : SamePartyContext(type, type, type) {} -SamePartyContext::SamePartyContext( - Type context_type, - Type ancestors_for_metrics, - Type top_resource_for_metrics, - FirstPartySetsContextType first_party_sets_context_type) +SamePartyContext::SamePartyContext(Type context_type, + Type ancestors_for_metrics, + Type top_resource_for_metrics) : context_type_(context_type), ancestors_for_metrics_only_(ancestors_for_metrics), - top_resource_for_metrics_only_(top_resource_for_metrics), - first_party_sets_context_type_(first_party_sets_context_type) {} + top_resource_for_metrics_only_(top_resource_for_metrics) {} bool SamePartyContext::operator==(const SamePartyContext& other) const { return std::make_tuple(context_type(), ancestors_for_metrics_only(), - top_resource_for_metrics_only(), - first_party_sets_context_type()) == + top_resource_for_metrics_only()) == std::make_tuple(other.context_type(), other.ancestors_for_metrics_only(), - other.top_resource_for_metrics_only(), - other.first_party_sets_context_type()); + other.top_resource_for_metrics_only()); +} + +std::ostream& operator<<(std::ostream& os, const SamePartyContext& spc) { + os << "{" << static_cast<int>(spc.context_type()) << ", " + << static_cast<int>(spc.ancestors_for_metrics_only()) << ", " + << static_cast<int>(spc.top_resource_for_metrics_only()) << "}"; + return os; } // static SamePartyContext SamePartyContext::MakeInclusive() { - return SamePartyContext(Type::kSameParty, - FirstPartySetsContextType::kHomogeneous); + return SamePartyContext(Type::kSameParty); } } // namespace net
diff --git a/net/cookies/same_party_context.h b/net/cookies/same_party_context.h index 60607f5b..2de8e2c0a 100644 --- a/net/cookies/same_party_context.h +++ b/net/cookies/same_party_context.h
@@ -27,13 +27,10 @@ }; SamePartyContext() = default; - explicit SamePartyContext( - Type type, - FirstPartySetsContextType first_party_sets_context_type); + explicit SamePartyContext(Type type); SamePartyContext(Type context_type, Type ancestors_for_metrics, - Type top_resource_for_metrics, - FirstPartySetsContextType first_party_sets_context_type); + Type top_resource_for_metrics); bool operator==(const SamePartyContext& other) const; @@ -53,10 +50,6 @@ return top_resource_for_metrics_only_; } - FirstPartySetsContextType first_party_sets_context_type() const { - return first_party_sets_context_type_; - } - // Creates a SamePartyContext that is as permissive as possible. static SamePartyContext MakeInclusive(); @@ -64,10 +57,11 @@ Type context_type_ = Type::kCrossParty; Type ancestors_for_metrics_only_ = Type::kCrossParty; Type top_resource_for_metrics_only_ = Type::kCrossParty; - FirstPartySetsContextType first_party_sets_context_type_ = - FirstPartySetsContextType::kUnknown; }; +NET_EXPORT std::ostream& operator<<(std::ostream& os, + const SamePartyContext& spc); + } // namespace net #endif // NET_COOKIES_SAME_PARTY_CONTEXT_H_
diff --git a/net/cookies/test_cookie_access_delegate.cc b/net/cookies/test_cookie_access_delegate.cc index 19086bd..1c3dd36 100644 --- a/net/cookies/test_cookie_access_delegate.cc +++ b/net/cookies/test_cookie_access_delegate.cc
@@ -36,11 +36,11 @@ return true; } -SamePartyContext TestCookieAccessDelegate::ComputeSamePartyContext( +FirstPartySetMetadata TestCookieAccessDelegate::ComputeFirstPartySetMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const { - return SamePartyContext(); + return FirstPartySetMetadata(); } absl::optional<net::SchemefulSite>
diff --git a/net/cookies/test_cookie_access_delegate.h b/net/cookies/test_cookie_access_delegate.h index 7b8342d..db5ac5cc 100644 --- a/net/cookies/test_cookie_access_delegate.h +++ b/net/cookies/test_cookie_access_delegate.h
@@ -12,6 +12,7 @@ #include "base/containers/flat_map.h" #include "net/cookies/cookie_access_delegate.h" #include "net/cookies/cookie_constants.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -37,7 +38,7 @@ bool ShouldIgnoreSameSiteRestrictions( const GURL& url, const SiteForCookies& site_for_cookies) const override; - SamePartyContext ComputeSamePartyContext( + FirstPartySetMetadata ComputeFirstPartySetMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const override;
diff --git a/net/dns/dns_hosts.cc b/net/dns/dns_hosts.cc index 77eb79f..e45ab91f 100644 --- a/net/dns/dns_hosts.cc +++ b/net/dns/dns_hosts.cc
@@ -65,7 +65,7 @@ } // If comma_mode_ is COMMA_IS_TOKEN, fall through: - FALLTHROUGH; + [[fallthrough]]; default: { size_t token_start = pos_;
diff --git a/net/dns/fuzzed_host_resolver_util.cc b/net/dns/fuzzed_host_resolver_util.cc index 3bd7550..042d0e0e8 100644 --- a/net/dns/fuzzed_host_resolver_util.cc +++ b/net/dns/fuzzed_host_resolver_util.cc
@@ -103,13 +103,13 @@ switch (data_provider->ConsumeIntegralInRange(0, 3)) { case 3: config.search.push_back("foo.com"); - FALLTHROUGH; + [[fallthrough]]; case 2: config.search.push_back("bar"); - FALLTHROUGH; + [[fallthrough]]; case 1: config.search.push_back("com"); - FALLTHROUGH; + [[fallthrough]]; default: break; }
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 3247173..3bd51c3 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -1517,7 +1517,7 @@ case DnsQueryType::HTTPS: DCHECK(!secure_ || !features::kUseDnsHttpsSvcbEnforceSecureResponse.Get()); - FALLTHROUGH; + [[fallthrough]]; case DnsQueryType::HTTPS_EXPERIMENTAL: if (httpssvc_metrics_) { // Don't record provider ID for timeouts. It is not precisely known
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 47a2b926..e66ebe9 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -923,6 +923,12 @@ EVENT_TYPE(URL_REQUEST_DELEGATE_RESPONSE_STARTED) EVENT_TYPE(URL_REQUEST_DELEGATE_SSL_CERTIFICATE_ERROR) +// Like the above events, but the END phase also has the following parameter: +// { +// "net_error": <Network error code. Only present on error. +// } +EVENT_TYPE(URL_REQUEST_DELEGATE_CONNECTED) + // Logged when a delegate informs the URL_REQUEST of what's currently blocking // the request. The parameters attached to the begin event are: // {
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc index 8e206c2..de7e893 100644 --- a/net/test/cert_builder.cc +++ b/net/test/cert_builder.cc
@@ -132,6 +132,24 @@ (*out_leaf)->EraseExtension(AuthorityInfoAccessOid()); } +void CertBuilder::CreateSimpleChain(std::unique_ptr<CertBuilder>* out_leaf, + std::unique_ptr<CertBuilder>* out_root) { + const char kHostname[] = "www.example.com"; + base::FilePath certs_dir = GetTestCertsDirectory(); + + auto orig_root = ImportCertFromFile(certs_dir, "root_ca_cert.pem"); + ASSERT_TRUE(orig_root); + auto orig_leaf = ImportCertFromFile(certs_dir, "ok_cert.pem"); + ASSERT_TRUE(orig_leaf); + + // Build slightly modified variants of |orig_certs|. + *out_root = std::make_unique<CertBuilder>(orig_root->cert_buffer(), nullptr); + + *out_leaf = + std::make_unique<CertBuilder>(orig_leaf->cert_buffer(), out_root->get()); + (*out_leaf)->SetSubjectAltName(kHostname); +} + void CertBuilder::SetExtension(const der::Input& oid, std::string value, bool critical) {
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h index f0af3ef..b4f220f 100644 --- a/net/test/cert_builder.h +++ b/net/test/cert_builder.h
@@ -55,6 +55,12 @@ std::unique_ptr<CertBuilder>* out_intermediate, std::unique_ptr<CertBuilder>* out_root); + // Creates a simple leaf->root chain of CertBuilders with no AIA or + // CrlDistributionPoint extensions, and leaf having a subjectAltName of + // www.example.com. + static void CreateSimpleChain(std::unique_ptr<CertBuilder>* out_leaf, + std::unique_ptr<CertBuilder>* out_root); + // Sets a value for the indicated X.509 (v3) extension. void SetExtension(const der::Input& oid, std::string value,
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 02ae86e..02a3a9c 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -26,7 +26,6 @@ #include "net/cert/x509_certificate.h" #include "net/cookies/cookie_store.h" #include "net/cookies/cookie_util.h" -#include "net/cookies/same_party_context.h" #include "net/dns/public/secure_dns_policy.h" #include "net/http/http_log_util.h" #include "net/http/http_util.h" @@ -649,13 +648,13 @@ DCHECK(!is_pending_); DCHECK(!job_); - set_same_party_context( + set_first_party_set_metadata( context()->cookie_store() - ? cookie_util::ComputeSamePartyContext( + ? cookie_util::ComputeFirstPartySetMetadata( SchemefulSite(url()), isolation_info(), context()->cookie_store()->cookie_access_delegate(), force_ignore_top_frame_party_for_cookies()) - : SamePartyContext()); + : FirstPartySetMetadata()); privacy_mode_ = DeterminePrivacyMode(); net_log_.BeginEvent(NetLogEventType::URL_REQUEST_START_JOB, [&] { @@ -824,7 +823,18 @@ int URLRequest::NotifyConnected(const TransportInfo& info, CompletionOnceCallback callback) { - return delegate_->OnConnected(this, info, std::move(callback)); + OnCallToDelegate(NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED); + int result = delegate_->OnConnected( + this, info, + base::BindOnce( + [](URLRequest* request, CompletionOnceCallback callback, int result) { + request->OnCallToDelegateComplete(result); + std::move(callback).Run(result); + }, + this, std::move(callback))); + if (result != ERR_IO_PENDING) + OnCallToDelegateComplete(result); + return result; } void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info, @@ -1104,7 +1114,7 @@ if (network_delegate()) { enable_privacy_mode = network_delegate()->ForcePrivacyMode( url(), site_for_cookies_, isolation_info_.top_frame_origin(), - same_party_context().context_type()); + first_party_set_metadata().context().context_type()); } return enable_privacy_mode ? PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; } @@ -1175,13 +1185,13 @@ net_log_.BeginEvent(type); } -void URLRequest::OnCallToDelegateComplete() { +void URLRequest::OnCallToDelegateComplete(int error) { // This should have been cleared before resuming the request. DCHECK(blocked_by_.empty()); if (!calling_delegate_) return; calling_delegate_ = false; - net_log_.EndEvent(delegate_event_type_); + net_log_.EndEventWithNetErrorCode(delegate_event_type_, error); delegate_event_type_ = NetLogEventType::FAILED; }
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index cded3f23..3da5f137 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -25,6 +25,7 @@ #include "net/base/load_states.h" #include "net/base/load_timing_info.h" #include "net/base/net_error_details.h" +#include "net/base/net_errors.h" #include "net/base/net_export.h" #include "net/base/network_delegate.h" #include "net/base/privacy_mode.h" @@ -32,7 +33,7 @@ #include "net/base/request_priority.h" #include "net/base/upload_progress.h" #include "net/cookies/canonical_cookie.h" -#include "net/cookies/same_party_context.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/site_for_cookies.h" #include "net/dns/public/secure_dns_policy.h" #include "net/filter/source_stream.h" @@ -278,13 +279,13 @@ } const IsolationInfo& isolation_info() const { return isolation_info_; } - // The party_context_ of this leg of the request. This gets updated on - // redirects. - const SamePartyContext& same_party_context() const { - return same_party_context_; + // The First-Party Set metadata of this leg of the request. This gets updated + // on redirects. + const FirstPartySetMetadata& first_party_set_metadata() const { + return first_party_set_metadata_; } - void set_same_party_context(const SamePartyContext& context) { - same_party_context_ = context; + void set_first_party_set_metadata(FirstPartySetMetadata metadata) { + first_party_set_metadata_ = std::move(metadata); } // Indicate whether SameSite cookies should be attached even though the @@ -907,8 +908,10 @@ // e.g. NetLogEventType::NETWORK_DELEGATE_AUTH_REQUIRED. void OnCallToDelegate(NetLogEventType type); // Called when the delegate lets a request continue. Also called on - // cancellation. - void OnCallToDelegateComplete(); + // cancellation. `error` is an optional error code associated with + // completion. It's only for logging purposes, and will not directly cancel + // the request if it's a value other than OK. + void OnCallToDelegateComplete(int error = OK); // Records the referrer policy of the given request, bucketed by // whether the request is same-origin or not. To save computation, @@ -932,7 +935,7 @@ IsolationInfo isolation_info_; - SamePartyContext same_party_context_; + FirstPartySetMetadata first_party_set_metadata_; bool force_ignore_site_for_cookies_; bool force_ignore_top_frame_party_for_cookies_;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index d58c0e0..3be2597 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -241,7 +241,7 @@ throttling_entry_ = manager->RegisterRequestUrl(request->url()); ResetTimer(); - ComputeCookiePartitionKey(); + cookie_partition_key_ = ComputeCookiePartitionKey(); } URLRequestHttpJob::~URLRequestHttpJob() { @@ -580,19 +580,15 @@ request_->site_for_cookies(), request_->initiator(), is_main_frame_navigation, force_ignore_site_for_cookies); - net::SchemefulSite request_site(request_->url()); - const CookieAccessDelegate* delegate = - cookie_store->cookie_access_delegate(); - bool is_in_nontrivial_first_party_set = - delegate && delegate->FindFirstPartySetOwner(request_site).has_value(); + request_->first_party_set_metadata().owner().has_value(); CookieOptions options = CreateCookieOptions( - same_site_context, request_->same_party_context(), + same_site_context, request_->first_party_set_metadata().context(), request_->isolation_info(), is_in_nontrivial_first_party_set); UMA_HISTOGRAM_ENUMERATION( "Cookie.FirstPartySetsContextType.HTTP.Read", - request_->same_party_context().first_party_sets_context_type()); + request_->first_party_set_metadata().first_party_sets_context_type()); cookie_store->GetCookieListWithOptionsAsync( request_->url(), options, @@ -747,18 +743,15 @@ request_->initiator(), is_main_frame_navigation, force_ignore_site_for_cookies); - const CookieAccessDelegate* delegate = cookie_store->cookie_access_delegate(); - net::SchemefulSite request_site(request_->url()); - bool is_in_nontrivial_first_party_set = - delegate && delegate->FindFirstPartySetOwner(request_site).has_value(); + request_->first_party_set_metadata().owner().has_value(); CookieOptions options = CreateCookieOptions( - same_site_context, request_->same_party_context(), + same_site_context, request_->first_party_set_metadata().context(), request_->isolation_info(), is_in_nontrivial_first_party_set); UMA_HISTOGRAM_ENUMERATION( "Cookie.FirstPartySetsContextType.HTTP.Write", - request_->same_party_context().first_party_sets_context_type()); + request_->first_party_set_metadata().first_party_sets_context_type()); // Set all cookies, without waiting for them to be set. Any subsequent // read will see the combined result of all cookie operation. @@ -1616,13 +1609,12 @@ network_quality_estimator->NotifyURLRequestDestroyed(*request()); } -void URLRequestHttpJob::ComputeCookiePartitionKey() { +absl::optional<CookiePartitionKey> +URLRequestHttpJob::ComputeCookiePartitionKey() { const CookieStore* cookie_store = request_->context()->cookie_store(); - if (!cookie_store) { - cookie_partition_key_ = absl::nullopt; - return; - } - cookie_partition_key_ = CookieAccessDelegate::CreateCookiePartitionKey( + if (!cookie_store) + return absl::nullopt; + return CookieAccessDelegate::CreateCookiePartitionKey( cookie_store->cookie_access_delegate(), request_->isolation_info().network_isolation_key()); }
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index faf2319..7193baa 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h
@@ -206,13 +206,12 @@ // `override_response_info_::headers`. HttpResponseHeaders* GetResponseHeaders() const; - // Compute the `cookie_partition_key_` for the request. Partitioned cookies - // will be set using this key and only partitioned cookies with this partition - // key will be sent. - // Sets `cookie_partition_key_` to nullopt if cookie partitioning is not - // enabled, if the NIK has no top-frame site, or if the instance has no - // cookie store. - void ComputeCookiePartitionKey(); + // Computes the cookie partition key for the request. Partitioned cookies + // should be set using this key and only partitioned cookies with this + // partition key should be sent. + // Returns nullopt if cookie partitioning is not enabled, if the NIK has no + // top-frame site, or if the instance has no cookie store. + absl::optional<CookiePartitionKey> ComputeCookiePartitionKey(); // Returns true if partitioned cookies are enabled and can be accessed and/or // set.
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index da03fec0..88f4d88 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -1763,9 +1763,9 @@ EXPECT_THAT(delegate.transports(), IsEmpty()); } -// This test verifies that URLRequest::Delegate's OnConnected() callback +// This test verifies that URLRequest::Delegate's OnConnected() method // is called once for simple redirect-less requests. -TEST_F(URLRequestTest, NotifyDelegateConnectedOnce) { +TEST_F(URLRequestTest, OnConnected) { HttpTestServer test_server; ASSERT_TRUE(test_server.Start()); @@ -1782,11 +1782,25 @@ expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), test_server.port()); EXPECT_THAT(delegate.transports(), ElementsAre(expected_transport)); + + // Make sure URL_REQUEST_DELEGATE_CONNECTED is logged correctly. + auto entries = net_log_observer_.GetEntries(); + size_t start_event_index = ExpectLogContainsSomewhere( + entries, /*min_offset=*/0, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::BEGIN); + size_t end_event_index = ExpectLogContainsSomewhereAfter( + entries, /*start_offset=*/start_event_index, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::END); + EXPECT_FALSE(LogContainsEntryWithTypeAfter( + entries, end_event_index + 1, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED)); + ASSERT_LT(end_event_index, entries.size()); + EXPECT_FALSE(GetOptionalNetErrorCodeFromParams(entries[end_event_index])); } -// This test verifies that URLRequest::Delegate's OnConnected() callback is +// This test verifies that URLRequest::Delegate's OnConnected() method is // called after each redirect. -TEST_F(URLRequestTest, NotifyDelegateConnectedOnEachRedirect) { +TEST_F(URLRequestTest, OnConnectedRedirect) { HttpTestServer test_server; ASSERT_TRUE(test_server.Start()); @@ -1815,8 +1829,8 @@ } // This test verifies that when the URLRequest Delegate returns an error from -// OnBeforeSendHeaders(), the entire request fails with that error. -TEST_F(URLRequestTest, NotifyDelegateConnectedReturnError) { +// OnConnected(), the entire request fails with that error. +TEST_F(URLRequestTest, OnConnectedError) { HttpTestServer test_server; ASSERT_TRUE(test_server.Start()); @@ -1837,6 +1851,80 @@ EXPECT_TRUE(delegate.request_failed()); EXPECT_THAT(delegate.request_status(), IsError(ERR_NOT_IMPLEMENTED)); + + // Make sure URL_REQUEST_DELEGATE_CONNECTED is logged correctly. + auto entries = net_log_observer_.GetEntries(); + size_t start_event_index = ExpectLogContainsSomewhere( + entries, /*min_offset=*/0, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::BEGIN); + size_t end_event_index = ExpectLogContainsSomewhereAfter( + entries, /*start_offset=*/start_event_index, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::END); + EXPECT_FALSE(LogContainsEntryWithTypeAfter( + entries, end_event_index + 1, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED)); + ASSERT_LT(end_event_index, entries.size()); + EXPECT_EQ(ERR_NOT_IMPLEMENTED, + GetOptionalNetErrorCodeFromParams(entries[end_event_index])); +} + +TEST_F(URLRequestTest, OnConnectedAsync) { + HttpTestServer test_server; + ASSERT_TRUE(test_server.Start()); + + TestDelegate d; + d.set_on_connected_run_callback(true); + d.set_on_connected_result(OK); + std::unique_ptr<URLRequest> req(default_context_->CreateFirstPartyRequest( + test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d, + TRAFFIC_ANNOTATION_FOR_TESTS)); + req->Start(); + d.RunUntilComplete(); + EXPECT_THAT(d.request_status(), IsOk()); + + // Make sure URL_REQUEST_DELEGATE_CONNECTED is logged correctly. + auto entries = net_log_observer_.GetEntries(); + size_t start_event_index = ExpectLogContainsSomewhere( + entries, /*min_offset=*/0, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::BEGIN); + size_t end_event_index = ExpectLogContainsSomewhereAfter( + entries, /*start_offset=*/start_event_index, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::END); + EXPECT_FALSE(LogContainsEntryWithTypeAfter( + entries, end_event_index + 1, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED)); + ASSERT_LT(end_event_index, entries.size()); + EXPECT_FALSE(GetOptionalNetErrorCodeFromParams(entries[end_event_index])); +} + +TEST_F(URLRequestTest, OnConnectedAsyncError) { + HttpTestServer test_server; + ASSERT_TRUE(test_server.Start()); + + TestDelegate d; + d.set_on_connected_run_callback(true); + d.set_on_connected_result(ERR_NOT_IMPLEMENTED); + std::unique_ptr<URLRequest> req(default_context_->CreateFirstPartyRequest( + test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d, + TRAFFIC_ANNOTATION_FOR_TESTS)); + req->Start(); + d.RunUntilComplete(); + EXPECT_THAT(d.request_status(), IsError(ERR_NOT_IMPLEMENTED)); + + // Make sure URL_REQUEST_DELEGATE_CONNECTED is logged correctly. + auto entries = net_log_observer_.GetEntries(); + size_t start_event_index = ExpectLogContainsSomewhere( + entries, /*min_offset=*/0, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::BEGIN); + size_t end_event_index = ExpectLogContainsSomewhereAfter( + entries, /*start_offset=*/start_event_index, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED, NetLogEventPhase::END); + EXPECT_FALSE(LogContainsEntryWithTypeAfter( + entries, end_event_index + 1, + NetLogEventType::URL_REQUEST_DELEGATE_CONNECTED)); + ASSERT_LT(end_event_index, entries.size()); + EXPECT_EQ(ERR_NOT_IMPLEMENTED, + GetOptionalNetErrorCodeFromParams(entries[end_event_index])); } TEST_F(URLRequestTest, DelayedCookieCallback) { @@ -13006,38 +13094,6 @@ testing::ElementsAre("www.example.test")); } -TEST_F(URLRequestTest, OnConnectedCallbackAsyncOK) { - HttpTestServer test_server; - ASSERT_TRUE(test_server.Start()); - - TestURLRequestContext context; - TestDelegate d; - d.set_on_connected_run_callback(true); - d.set_on_connected_result(OK); - std::unique_ptr<URLRequest> req(context.CreateFirstPartyRequest( - test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d, - TRAFFIC_ANNOTATION_FOR_TESTS)); - req->Start(); - d.RunUntilComplete(); - EXPECT_THAT(d.request_status(), IsOk()); -} - -TEST_F(URLRequestTest, OnConnectedCallbackAsyncError) { - HttpTestServer test_server; - ASSERT_TRUE(test_server.Start()); - - TestURLRequestContext context; - TestDelegate d; - d.set_on_connected_run_callback(true); - d.set_on_connected_result(ERR_FAILED); - std::unique_ptr<URLRequest> req(context.CreateFirstPartyRequest( - test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d, - TRAFFIC_ANNOTATION_FOR_TESTS)); - req->Start(); - d.RunUntilComplete(); - EXPECT_THAT(d.request_status(), IsError(ERR_FAILED)); -} - TEST_F(URLRequestTest, SetURLChain) { TestDelegate d; {
diff --git a/pdf/ui/thumbnail.cc b/pdf/ui/thumbnail.cc index 7810e5b..092e48f 100644 --- a/pdf/ui/thumbnail.cc +++ b/pdf/ui/thumbnail.cc
@@ -94,14 +94,10 @@ } // namespace -Thumbnail::Thumbnail() = default; - -Thumbnail::Thumbnail(const gfx::Size& page_size, float device_pixel_ratio) { - DCHECK_GE(device_pixel_ratio, kMinDevicePixelRatio); - DCHECK_LE(device_pixel_ratio, kMaxDevicePixelRatio); - device_pixel_ratio_ = base::clamp(device_pixel_ratio, kMinDevicePixelRatio, - kMaxDevicePixelRatio); - +Thumbnail::Thumbnail(const gfx::Size& page_size, float device_pixel_ratio) + : device_pixel_ratio_(base::clamp(device_pixel_ratio, + kMinDevicePixelRatio, + kMaxDevicePixelRatio)) { const gfx::Size thumbnail_size_device_pixels = CalculateBestFitSize(page_size, device_pixel_ratio_);
diff --git a/pdf/ui/thumbnail.h b/pdf/ui/thumbnail.h index 5b343c7..8171f85 100644 --- a/pdf/ui/thumbnail.h +++ b/pdf/ui/thumbnail.h
@@ -15,7 +15,6 @@ class Thumbnail final { public: - Thumbnail(); Thumbnail(const gfx::Size& page_size, float device_pixel_ratio); Thumbnail(Thumbnail&& other); Thumbnail& operator=(Thumbnail&& other); @@ -33,7 +32,7 @@ // are the dimensions of the thumbnail in CSS pixels multiplied by // `device_pixel_ratio_`. // Only values between 0.25 and 2 are supported. - float device_pixel_ratio_ = 1; + float device_pixel_ratio_; }; } // namespace chrome_pdf
diff --git a/printing/emf_win_unittest.cc b/printing/emf_win_unittest.cc index e830a101..7daa9f9 100644 --- a/printing/emf_win_unittest.cc +++ b/printing/emf_win_unittest.cc
@@ -115,7 +115,6 @@ // current directory. // TODO(maruel): Clean the .PRN file generated in current directory. context.NewDocument(u"EmfTest.Enumerate"); - context.NewPage(); // Process one at a time. RECT page_bounds = emf.GetPageBounds(1).ToRECT(); Emf::Enumerator emf_enum(emf, context.context(), &page_bounds); @@ -129,7 +128,6 @@ EXPECT_TRUE(itr->SafePlayback(&emf_enum.context_)) << " index: " << index << " type: " << itr->record()->iType; } - context.PageDone(); context.DocumentDone(); }
diff --git a/printing/printed_document.cc b/printing/printed_document.cc index 54dd798f..81ebe97 100644 --- a/printing/printed_document.cc +++ b/printing/printed_document.cc
@@ -187,17 +187,18 @@ mojom::ResultCode PrintedDocument::RenderPrintedDocument( PrintingContext* context) { - mojom::ResultCode result = context->NewPage(); + base::AutoLock lock(lock_); + mojom::ResultCode result = context->PrintDocument( + *GetMetafile(), *immutable_.settings_, mutable_.expected_page_count_); if (result != mojom::ResultCode::kSuccess) return result; - { - base::AutoLock lock(lock_); - result = context->PrintDocument(*GetMetafile(), *immutable_.settings_, - mutable_.expected_page_count_); - if (result != mojom::ResultCode::kSuccess) - return result; - } - return context->PageDone(); + + // Beware of any asynchronous aborts of the print job that happened during + // printing. + if (context->PrintingAborted()) + return mojom::ResultCode::kCanceled; + + return mojom::ResultCode::kSuccess; } bool PrintedDocument::IsComplete() const {
diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc index 4024150..8e34b28 100644 --- a/printing/printed_document_win.cc +++ b/printing/printed_document_win.cc
@@ -24,8 +24,17 @@ #endif DCHECK(context); - return context->RenderPage(page, - immutable_.settings_->page_setup_device_units()); + mojom::ResultCode result = context->RenderPage( + page, immutable_.settings_->page_setup_device_units()); + if (result != mojom::ResultCode::kSuccess) + return result; + + // Beware of any asynchronous aborts of the print job that happened during + // printing. + if (context->PrintingAborted()) + return mojom::ResultCode::kCanceled; + + return mojom::ResultCode::kSuccess; } } // namespace printing
diff --git a/printing/printing_context.h b/printing/printing_context.h index 7d937e7..e34fb07 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h
@@ -122,18 +122,12 @@ virtual mojom::ResultCode NewDocument( const std::u16string& document_name) = 0; - // Starts a new page. - virtual mojom::ResultCode NewPage() = 0; - #if defined(OS_WIN) // Renders a page. virtual mojom::ResultCode RenderPage(const PrintedPage& page, const PageSetup& page_setup) = 0; #endif - // Closes the printed page. - virtual mojom::ResultCode PageDone() = 0; - // Prints the document contained in `metafile`. virtual mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, @@ -175,6 +169,8 @@ std::unique_ptr<PrintSettings> TakeAndResetSettings(); + bool PrintingAborted() const { return abort_printing_; } + int job_id() const { return job_id_; } protected:
diff --git a/printing/printing_context_android.cc b/printing/printing_context_android.cc index c28a40e..5b2f096c 100644 --- a/printing/printing_context_android.cc +++ b/printing/printing_context_android.cc
@@ -213,30 +213,13 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextAndroid::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - -mojom::ResultCode PrintingContextAndroid::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextAndroid::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) { + if (abort_printing_) + return mojom::ResultCode::kCanceled; + DCHECK(in_print_job_); DCHECK(is_file_descriptor_valid()); return metafile.SaveToFileDescriptor(fd_) ? mojom::ResultCode::kSuccess
diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h index 676d989..b4f2f25 100644 --- a/printing/printing_context_android.h +++ b/printing/printing_context_android.h
@@ -60,8 +60,6 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/printing/printing_context_chromeos.cc b/printing/printing_context_chromeos.cc index d996c3e..670df66 100644 --- a/printing/printing_context_chromeos.cc +++ b/printing/printing_context_chromeos.cc
@@ -402,32 +402,14 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextChromeos::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - -mojom::ResultCode PrintingContextChromeos::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextChromeos::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) { + if (abort_printing_) + return mojom::ResultCode::kCanceled; + DCHECK(in_print_job_); + #if defined(USE_CUPS) std::vector<char> buffer; if (!metafile.GetDataAsVector(&buffer))
diff --git a/printing/printing_context_chromeos.h b/printing/printing_context_chromeos.h index 7735337..06cb16c 100644 --- a/printing/printing_context_chromeos.h +++ b/printing/printing_context_chromeos.h
@@ -39,8 +39,6 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/printing/printing_context_linux.cc b/printing/printing_context_linux.cc index c5adfa3..204cec83 100644 --- a/printing/printing_context_linux.cc +++ b/printing/printing_context_linux.cc
@@ -151,30 +151,13 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextLinux::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - -mojom::ResultCode PrintingContextLinux::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextLinux::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) { + if (abort_printing_) + return mojom::ResultCode::kCanceled; + DCHECK(in_print_job_); DCHECK(print_dialog_); // TODO(crbug.com/1252685) Plumb error code back from // `PrintDialogGtkInterface`.
diff --git a/printing/printing_context_linux.h b/printing/printing_context_linux.h index 17d768a..653170b 100644 --- a/printing/printing_context_linux.h +++ b/printing/printing_context_linux.h
@@ -45,8 +45,6 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h index 36f2e09..3725aa4 100644 --- a/printing/printing_context_mac.h +++ b/printing/printing_context_mac.h
@@ -35,8 +35,6 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override; @@ -101,6 +99,12 @@ // Returns true is the pair is set. bool SetKeyValue(base::StringPiece key, base::StringPiece value); + // Starts a new page. + mojom::ResultCode NewPage(); + + // Closes the printed page. + mojom::ResultCode PageDone(); + // The native print info object. base::scoped_nsobject<NSPrintInfo> print_info_;
diff --git a/printing/printing_context_no_system_dialog.cc b/printing/printing_context_no_system_dialog.cc index c10123f35..253507f 100644 --- a/printing/printing_context_no_system_dialog.cc +++ b/printing/printing_context_no_system_dialog.cc
@@ -98,26 +98,6 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextNoSystemDialog::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - -mojom::ResultCode PrintingContextNoSystemDialog::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextNoSystemDialog::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings,
diff --git a/printing/printing_context_no_system_dialog.h b/printing/printing_context_no_system_dialog.h index 2753d7ba..cb0d0b8 100644 --- a/printing/printing_context_no_system_dialog.h +++ b/printing/printing_context_no_system_dialog.h
@@ -32,8 +32,6 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index 0addb52..4f1fb12 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc
@@ -366,18 +366,6 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextWin::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(context_); - DCHECK(in_print_job_); - - // Intentional No-op. MetafileSkia::SafePlayback takes care of calling - // ::StartPage(). - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextWin::RenderPage(const PrintedPage& page, const PageSetup& page_setup) { if (abort_printing_) @@ -416,17 +404,6 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode PrintingContextWin::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // Intentional No-op. MetafileSkia::SafePlayback takes care of calling - // ::EndPage(). - - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode PrintingContextWin::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings,
diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h index 700bfe2c..babd443 100644 --- a/printing/printing_context_win.h +++ b/printing/printing_context_win.h
@@ -35,10 +35,8 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; mojom::ResultCode RenderPage(const PrintedPage& page, const PageSetup& page_setup) override; - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc index 4f0bf0a..208e8a1 100644 --- a/printing/test_printing_context.cc +++ b/printing/test_printing_context.cc
@@ -116,15 +116,6 @@ return mojom::ResultCode::kSuccess; } -mojom::ResultCode TestPrintingContext::NewPage() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // No-op. - return mojom::ResultCode::kSuccess; -} - #if defined(OS_WIN) mojom::ResultCode TestPrintingContext::RenderPage(const PrintedPage& page, const PageSetup& page_setup) { @@ -138,15 +129,6 @@ } #endif // defined(OS_WIN) -mojom::ResultCode TestPrintingContext::PageDone() { - if (abort_printing_) - return mojom::ResultCode::kCanceled; - DCHECK(in_print_job_); - - // No-op. - return mojom::ResultCode::kSuccess; -} - mojom::ResultCode TestPrintingContext::PrintDocument( const MetafilePlayer& metafile, const PrintSettings& settings,
diff --git a/printing/test_printing_context.h b/printing/test_printing_context.h index e2a0f90..579a926 100644 --- a/printing/test_printing_context.h +++ b/printing/test_printing_context.h
@@ -58,12 +58,10 @@ mojom::ResultCode UpdatePrinterSettings( const PrinterSettings& printer_settings) override; mojom::ResultCode NewDocument(const std::u16string& document_name) override; - mojom::ResultCode NewPage() override; #if defined(OS_WIN) mojom::ResultCode RenderPage(const PrintedPage& page, const PageSetup& page_setup) override; #endif - mojom::ResultCode PageDone() override; mojom::ResultCode PrintDocument(const MetafilePlayer& metafile, const PrintSettings& settings, uint32_t num_pages) override;
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc index cbc6ace..e592ef65 100644 --- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc +++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -214,7 +214,7 @@ bool consent, DaemonController::CompletionCallback done) { // Verify parameters passed in. - if (consent && config && config->HasKey("start")) { + if (consent && config && config->FindKey("start")) { std::move(done).Run(DaemonController::RESULT_OK); } else { std::move(done).Run(DaemonController::RESULT_FAILED); @@ -224,7 +224,7 @@ void MockDaemonControllerDelegate::UpdateConfig( std::unique_ptr<base::DictionaryValue> config, DaemonController::CompletionCallback done) { - if (config && config->HasKey("update")) { + if (config && config->FindKey("update")) { std::move(done).Run(DaemonController::RESULT_OK); } else { std::move(done).Run(DaemonController::RESULT_FAILED);
diff --git a/remoting/protocol/pairing_registry_unittest.cc b/remoting/protocol/pairing_registry_unittest.cc index 6b13a1ee..15bf6f15 100644 --- a/remoting/protocol/pairing_registry_unittest.cc +++ b/remoting/protocol/pairing_registry_unittest.cc
@@ -49,13 +49,15 @@ // any shared secret. void VerifyPairing(PairingRegistry::Pairing expected, const base::DictionaryValue& actual) { - std::string value; - EXPECT_TRUE(actual.GetString(PairingRegistry::kClientNameKey, &value)); - EXPECT_EQ(expected.client_name(), value); - EXPECT_TRUE(actual.GetString(PairingRegistry::kClientIdKey, &value)); - EXPECT_EQ(expected.client_id(), value); + const std::string* value = + actual.FindStringKey(PairingRegistry::kClientNameKey); + ASSERT_TRUE(value); + EXPECT_EQ(expected.client_name(), *value); + value = actual.FindStringKey(PairingRegistry::kClientIdKey); + ASSERT_TRUE(value); + EXPECT_EQ(expected.client_id(), *value); - EXPECT_FALSE(actual.HasKey(PairingRegistry::kSharedSecretKey)); + EXPECT_FALSE(actual.FindKey(PairingRegistry::kSharedSecretKey)); } } // namespace
diff --git a/rlz/lib/rlz_lib.cc b/rlz/lib/rlz_lib.cc index 2a1ae723..f9b2cdb 100644 --- a/rlz/lib/rlz_lib.cc +++ b/rlz/lib/rlz_lib.cc
@@ -13,6 +13,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/syslog_logging.h" +#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h"
diff --git a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc index 61298af9..60d6323 100644 --- a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc +++ b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc
@@ -801,7 +801,7 @@ #if defined(__NR_open) case __NR_open: flags_argument_position = 1; - FALLTHROUGH; + [[fallthrough]]; #endif case __NR_openat: { // open can be a wrapper for openat(2). if (sysno == __NR_openat)
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn index 2149bd7..5b0bf2b 100644 --- a/services/device/BUILD.gn +++ b/services/device/BUILD.gn
@@ -302,6 +302,7 @@ if (is_serial_enabled_platform) { sources += [ + "serial/bluetooth_serial_device_enumerator_unittests.cc", "serial/bluetooth_serial_port_impl_unittest.cc", "serial/serial_device_enumerator_unittest.cc", "serial/serial_port_impl_unittest.cc",
diff --git a/services/device/generic_sensor/platform_sensor_provider_linux.cc b/services/device/generic_sensor/platform_sensor_provider_linux.cc index 88153f3..b6ef776 100644 --- a/services/device/generic_sensor/platform_sensor_provider_linux.cc +++ b/services/device/generic_sensor/platform_sensor_provider_linux.cc
@@ -56,7 +56,7 @@ if (will_run) enumeration_status_ = SensorEnumerationState::kEnumerationStarted; - FALLTHROUGH; + [[fallthrough]]; } case SensorEnumerationState::kEnumerationStarted: return;
diff --git a/services/device/serial/bluetooth_serial_device_enumerator.cc b/services/device/serial/bluetooth_serial_device_enumerator.cc index 481bb4d0..272385a 100644 --- a/services/device/serial/bluetooth_serial_device_enumerator.cc +++ b/services/device/serial/bluetooth_serial_device_enumerator.cc
@@ -6,6 +6,8 @@ #include "base/command_line.h" #include "base/containers/contains.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "base/unguessable_token.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "services/device/public/cpp/bluetooth/bluetooth_utils.h" @@ -51,34 +53,27 @@ scoped_refptr<device::BluetoothAdapter> adapter) { SEQUENCE_CHECKER(sequence_checker_); DCHECK(adapter); - adapter->AddObserver(this); - std::vector<std::string> port_device_addresses; + BluetoothAdapter::DeviceList devices = adapter->GetDevices(); for (auto* device : devices) { - BluetoothDevice::UUIDSet device_uuids = device->GetUUIDs(); - if (base::Contains(device_uuids, GetSerialPortProfileUUID())) { - port_device_addresses.push_back(device->GetAddress()); - } + DeviceAdded(adapter.get(), device); } - + adapter->AddObserver(this); enumerator_runner_->PostTask( FROM_HERE, base::BindOnce(&BluetoothSerialDeviceEnumerator::SetClassicAdapter, - enumerator_, std::move(adapter), - std::move(port_device_addresses))); + enumerator_, std::move(adapter))); } void BluetoothSerialDeviceEnumerator::AdapterHelper::DeviceAdded( - BluetoothAdapter* adapter, + BluetoothAdapter*, BluetoothDevice* device) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - BluetoothDevice::UUIDSet device_uuids = device->GetUUIDs(); - if (!base::Contains(device_uuids, GetSerialPortProfileUUID())) - return; - enumerator_runner_->PostTask( - FROM_HERE, base::BindOnce(&BluetoothSerialDeviceEnumerator::PortAdded, - enumerator_, device->GetAddress())); + FROM_HERE, + base::BindOnce(&BluetoothSerialDeviceEnumerator::DeviceAdded, enumerator_, + device->GetAddress(), device->GetNameForDisplay(), + device->GetUUIDs())); } void BluetoothSerialDeviceEnumerator::AdapterHelper::DeviceRemoved( @@ -86,7 +81,7 @@ BluetoothDevice* device) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); enumerator_runner_->PostTask( - FROM_HERE, base::BindOnce(&BluetoothSerialDeviceEnumerator::PortRemoved, + FROM_HERE, base::BindOnce(&BluetoothSerialDeviceEnumerator::DeviceRemoved, enumerator_, device->GetAddress())); } @@ -103,44 +98,61 @@ BluetoothSerialDeviceEnumerator::~BluetoothSerialDeviceEnumerator() = default; void BluetoothSerialDeviceEnumerator::SetClassicAdapter( - scoped_refptr<device::BluetoothAdapter> adapter, - std::vector<std::string> port_device_addresses) { + scoped_refptr<device::BluetoothAdapter> adapter) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(adapter); adapter_ = std::move(adapter); - DCHECK(device_ports_.empty()); - for (const auto& device_address : port_device_addresses) { - PortAdded(device_address); - } if (got_adapter_callback_) { std::move(got_adapter_callback_).Run(); } } -void BluetoothSerialDeviceEnumerator::PortAdded( - const std::string& device_address) { +void BluetoothSerialDeviceEnumerator::DeviceAdded( + base::StringPiece device_address, + base::StringPiece16 device_name, + BluetoothDevice::UUIDSet service_class_ids) { + for (const auto& service_class_id : service_class_ids) { + AddService(device_address, device_name, service_class_id); + } +} + +void BluetoothSerialDeviceEnumerator::AddService( + base::StringPiece device_address, + base::StringPiece16 device_name, + const BluetoothUUID& service_class_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Ignore duplicate devices. Some ports send device notifications after - // requesting the classic adapter resulting in double detection of devices. - if (base::Contains(device_ports_, device_address)) + DeviceServiceInfo key = + std::make_pair(std::string(device_address), service_class_id); + if (base::Contains(device_ports_, key)) return; auto port = mojom::SerialPortInfo::New(); port->token = base::UnguessableToken::Create(); port->path = base::FilePath::FromUTF8Unsafe(device_address); port->type = mojom::DeviceType::SPP_DEVICE; - device_ports_.insert(std::make_pair(device_address, port->token)); + // TODO(crbug.com/1261557): Use better name. + // Using service class ID for development to disambiguate device services. + const std::string device_name_utf8 = base::UTF16ToUTF8(device_name); + if (service_class_id == GetSerialPortProfileUUID()) { + port->display_name = device_name_utf8; + } else { + port->display_name = base::StringPrintf("%s [%s]", device_name_utf8.c_str(), + service_class_id.value().c_str()); + } + device_ports_.insert(std::make_pair(std::move(key), port->token)); AddPort(std::move(port)); } -void BluetoothSerialDeviceEnumerator::PortRemoved( +void BluetoothSerialDeviceEnumerator::DeviceRemoved( const std::string& device_address) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto it = device_ports_.find(device_address); - DCHECK(it != device_ports_.end()); - base::UnguessableToken token = it->second; - device_ports_.erase(it); - RemovePort(token); + base::EraseIf(device_ports_, [&](auto& map_entry) { + if (map_entry.first.first == device_address) { + RemovePort(/*token=*/map_entry.second); + return true; + } + return false; + }); } scoped_refptr<BluetoothAdapter> BluetoothSerialDeviceEnumerator::GetAdapter() { @@ -149,15 +161,25 @@ absl::optional<std::string> BluetoothSerialDeviceEnumerator::GetAddressFromToken( - const base::UnguessableToken& token) { + const base::UnguessableToken& token) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (const auto& entry : device_ports_) { if (entry.second == token) - return entry.first; + return entry.first.first; } return absl::nullopt; } +BluetoothUUID BluetoothSerialDeviceEnumerator::GetServiceClassIdFromToken( + const base::UnguessableToken& token) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (const auto& entry : device_ports_) { + if (entry.second == token) + return entry.first.second; + } + return BluetoothUUID(); +} + void BluetoothSerialDeviceEnumerator::OnGotAdapterForTesting( base::OnceClosure closure) { if (adapter_) {
diff --git a/services/device/serial/bluetooth_serial_device_enumerator.h b/services/device/serial/bluetooth_serial_device_enumerator.h index 2bc7ec3b..04d8e06 100644 --- a/services/device/serial/bluetooth_serial_device_enumerator.h +++ b/services/device/serial/bluetooth_serial_device_enumerator.h
@@ -5,13 +5,14 @@ #ifndef SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_DEVICE_ENUMERATOR_H_ #define SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_DEVICE_ENUMERATOR_H_ -#include <map> -#include <unordered_map> -#include <vector> +#include <string> +#include <utility> +#include "base/containers/flat_map.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "base/strings/string_piece.h" #include "base/threading/sequence_bound.h" #include "device/bluetooth/bluetooth_adapter.h" #include "services/device/public/mojom/serial.mojom-forward.h" @@ -19,6 +20,8 @@ namespace device { +class BluetoothUUID; + class BluetoothSerialDeviceEnumerator : public SerialDeviceEnumerator { public: // `adapter_runner` is the task runner with which to access the Bluetooth @@ -31,15 +34,22 @@ const BluetoothSerialDeviceEnumerator&) = delete; ~BluetoothSerialDeviceEnumerator() override; - void PortAdded(const std::string& device_address); - void PortRemoved(const std::string& device_address); + void DeviceAdded(base::StringPiece device_address, + base::StringPiece16 device_name, + BluetoothDevice::UUIDSet service_class_ids); + void DeviceRemoved(const std::string& device_address); scoped_refptr<BluetoothAdapter> GetAdapter(); // This method will search the map of Bluetooth ports and find the // address with the matching token. absl::optional<std::string> GetAddressFromToken( - const base::UnguessableToken& token); + const base::UnguessableToken& token) const; + + // Return the service class ID for the port's `token`. If `token` is not found + // then an empty (invalid) id will be returned. + BluetoothUUID GetServiceClassIdFromToken( + const base::UnguessableToken& token) const; void OnGotAdapterForTesting(base::OnceClosure closure); void DeviceAddedForTesting(BluetoothAdapter* adapter, @@ -49,15 +59,18 @@ private: class AdapterHelper; + // Contains <Device address, Bluetooth service class ID>. + using DeviceServiceInfo = std::pair<std::string, BluetoothUUID>; + // Map BluetoothDevice address to port token. using DevicePortsMap = - std::unordered_map<std::string, base::UnguessableToken>; + base::flat_map<DeviceServiceInfo, base::UnguessableToken>; - // Set the "classic" `adapter`. `port_device_addresses` is a collection of - // all known ports device addresses at the time the adapter is detected. - // Called once during initialization. - void SetClassicAdapter(scoped_refptr<device::BluetoothAdapter> adapter, - std::vector<std::string> port_device_addresses); + void AddService(base::StringPiece device_address, + base::StringPiece16 device_name, + const BluetoothUUID& service_class_id); + // Set the "classic" `adapter`. Called once during initialization. + void SetClassicAdapter(scoped_refptr<device::BluetoothAdapter> adapter); base::OnceClosure got_adapter_callback_; scoped_refptr<BluetoothAdapter> adapter_;
diff --git a/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc new file mode 100644 index 0000000..d0a1fb7b --- /dev/null +++ b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
@@ -0,0 +1,201 @@ +// 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 "services/device/serial/bluetooth_serial_device_enumerator.h" + +#include <memory> + +#include "base/command_line.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/task_environment.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "services/device/public/cpp/bluetooth/bluetooth_utils.h" +#include "services/device/public/cpp/serial/serial_switches.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +namespace { + +using ::testing::NiceMock; +using ::testing::Return; + +constexpr char kTestDeviceAddress[] = "11:12:13:14:15:16"; +constexpr char kTestDeviceName[] = "Device w/SPP"; + +std::unique_ptr<device::MockBluetoothDevice> CreateDevice( + device::MockBluetoothAdapter* adapter, + const char* device_name, + const std::string& device_address) { + return std::make_unique<NiceMock<device::MockBluetoothDevice>>( + adapter, /*bluetooth_class=*/0u, device_name, device_address, + /*paired=*/true, /*connected=*/true); +} + +class MockSerialPortEnumeratorObserver + : public SerialDeviceEnumerator::Observer { + public: + MOCK_METHOD1(OnPortAdded, void(const mojom::SerialPortInfo&)); + MOCK_METHOD1(OnPortRemoved, void(const mojom::SerialPortInfo&)); +}; + +class BluetoothSerialDeviceEnumeratorTest : public testing::Test { + public: + BluetoothSerialDeviceEnumeratorTest() = default; + + void SetUp() override { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableBluetoothSerialPortProfileInSerialApi); + } + + scoped_refptr<base::SingleThreadTaskRunner> adapter_runner() { + return task_environment_.GetMainThreadTaskRunner(); + } + + private: + base::test::TaskEnvironment task_environment_; +}; + +} // namespace + +TEST_F(BluetoothSerialDeviceEnumeratorTest, ConstructDestruct) { + auto mock_adapter = + base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>(); + base::RunLoop run_loop; + mock_adapter->Initialize(run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_TRUE(mock_adapter->IsInitialized()); + + device::BluetoothAdapterFactory::Get()->SetAdapterForTesting(mock_adapter); + + BluetoothSerialDeviceEnumerator enumerator(adapter_runner()); + EXPECT_FALSE(enumerator.GetAdapter()); + // Prevent memory leak warning. + enumerator.SynchronouslyResetHelperForTesting(); +} + +TEST_F(BluetoothSerialDeviceEnumeratorTest, ConstructWaitForAdapter) { + auto mock_adapter = + base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>(); + + { + base::RunLoop run_loop; + mock_adapter->Initialize(run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_TRUE(mock_adapter->IsInitialized()); + } + + device::BluetoothAdapterFactory::Get()->SetAdapterForTesting(mock_adapter); + + BluetoothSerialDeviceEnumerator enumerator(adapter_runner()); + EXPECT_FALSE(enumerator.GetAdapter()); + + { + base::RunLoop run_loop; + enumerator.OnGotAdapterForTesting(run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_TRUE(enumerator.GetAdapter()); + } + + // Prevent memory leak warning. + enumerator.SynchronouslyResetHelperForTesting(); +} + +TEST_F(BluetoothSerialDeviceEnumeratorTest, CreateWithDevice) { + auto mock_adapter = + base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>(); + + { + base::RunLoop run_loop; + mock_adapter->Initialize(run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_TRUE(mock_adapter->IsInitialized()); + } + + auto mock_device = + CreateDevice(mock_adapter.get(), kTestDeviceName, kTestDeviceAddress); + mock_device->AddUUID(GetSerialPortProfileUUID()); + mock_adapter->AddMockDevice(std::move(mock_device)); + EXPECT_CALL(*mock_adapter, GetDevices()) + .WillOnce(Return(mock_adapter->GetConstMockDevices())); + + device::BluetoothAdapterFactory::Get()->SetAdapterForTesting(mock_adapter); + + BluetoothSerialDeviceEnumerator enumerator(adapter_runner()); + + base::UnguessableToken port_token; + MockSerialPortEnumeratorObserver observer; + enumerator.AddObserver(&observer); + { + base::RunLoop run_loop; + EXPECT_CALL(observer, OnPortAdded) + .WillOnce([&run_loop, + &port_token](const mojom::SerialPortInfo& serial_port_info) { + port_token = serial_port_info.token; + EXPECT_FALSE(serial_port_info.token.is_empty()); + EXPECT_EQ(base::FilePath::FromASCII(kTestDeviceAddress), + serial_port_info.path); + EXPECT_EQ(kTestDeviceName, serial_port_info.display_name); + EXPECT_EQ(absl::nullopt, serial_port_info.serial_number); + EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, serial_port_info.type); + EXPECT_FALSE(serial_port_info.has_vendor_id); + EXPECT_EQ(0x0, serial_port_info.vendor_id); + EXPECT_FALSE(serial_port_info.has_product_id); + EXPECT_EQ(0x0, serial_port_info.product_id); + run_loop.Quit(); + }); + run_loop.Run(); + } + + ASSERT_EQ(1u, enumerator.GetDevices().size()); + + auto address = enumerator.GetAddressFromToken(port_token); + ASSERT_TRUE(address); + EXPECT_EQ(*address, kTestDeviceAddress); + EXPECT_EQ(GetSerialPortProfileUUID(), + enumerator.GetServiceClassIdFromToken(port_token)); + + const base::UnguessableToken unused_token; + EXPECT_FALSE(enumerator.GetAddressFromToken(unused_token)); + EXPECT_FALSE(enumerator.GetServiceClassIdFromToken(unused_token).IsValid()); + + { + base::RunLoop run_loop; + enumerator.OnGotAdapterForTesting(run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_TRUE(enumerator.GetAdapter()); + } + + // Second add - which will be skipped. + const BluetoothDevice::UUIDSet service_class_ids = { + GetSerialPortProfileUUID()}; + const std::u16string device_name( + base::UTF8ToUTF16(std::string(kTestDeviceName))); + enumerator.DeviceAdded(kTestDeviceAddress, device_name, service_class_ids); + ASSERT_EQ(1u, enumerator.GetDevices().size()); + + // Remove device. + { + base::RunLoop run_loop; + EXPECT_CALL(observer, OnPortRemoved) + .WillOnce([&run_loop, + &port_token](const mojom::SerialPortInfo& serial_port_info) { + EXPECT_EQ(port_token, serial_port_info.token); + run_loop.Quit(); + }); + enumerator.DeviceRemoved(kTestDeviceAddress); + run_loop.Run(); + } + + // Remove again - now nonexistent. + enumerator.DeviceRemoved(kTestDeviceAddress); + + // Prevent memory leak warning. + enumerator.SynchronouslyResetHelperForTesting(); +} + +} // namespace device
diff --git a/services/device/serial/bluetooth_serial_port_impl.cc b/services/device/serial/bluetooth_serial_port_impl.cc index 330716a..1bb6793 100644 --- a/services/device/serial/bluetooth_serial_port_impl.cc +++ b/services/device/serial/bluetooth_serial_port_impl.cc
@@ -20,6 +20,7 @@ void BluetoothSerialPortImpl::Open( scoped_refptr<BluetoothAdapter> adapter, const std::string& address, + const BluetoothUUID& service_class_id, mojom::SerialConnectionOptionsPtr options, mojo::PendingRemote<mojom::SerialPortClient> client, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher, @@ -32,7 +33,7 @@ auto* port = new BluetoothSerialPortImpl( std::move(adapter), address, std::move(options), std::move(client), std::move(watcher)); - port->OpenSocket(std::move(callback)); + port->OpenSocket(service_class_id, std::move(callback)); } BluetoothSerialPortImpl::BluetoothSerialPortImpl( @@ -60,7 +61,8 @@ bluetooth_socket_->Disconnect(base::DoNothing()); } -void BluetoothSerialPortImpl::OpenSocket(OpenCallback callback) { +void BluetoothSerialPortImpl::OpenSocket(const BluetoothUUID& service_class_id, + OpenCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); BluetoothDevice* device = bluetooth_adapter_->GetDevice(address_); if (!device) { @@ -69,21 +71,15 @@ return; } - if (base::Contains(device->GetUUIDs(), GetSerialPortProfileUUID())) { - auto split_callback = base::SplitOnceCallback(std::move(callback)); - device->ConnectToService( - GetSerialPortProfileUUID(), - base::BindOnce(&BluetoothSerialPortImpl::OnSocketConnected, - weak_ptr_factory_.GetWeakPtr(), - std::move(split_callback.first)), - base::BindOnce(&BluetoothSerialPortImpl::OnSocketConnectedError, - weak_ptr_factory_.GetWeakPtr(), - std::move(split_callback.second))); - return; - } - - std::move(callback).Run(mojo::NullRemote()); - delete this; + auto split_callback = base::SplitOnceCallback(std::move(callback)); + device->ConnectToService( + service_class_id, + base::BindOnce(&BluetoothSerialPortImpl::OnSocketConnected, + weak_ptr_factory_.GetWeakPtr(), + std::move(split_callback.first)), + base::BindOnce(&BluetoothSerialPortImpl::OnSocketConnectedError, + weak_ptr_factory_.GetWeakPtr(), + std::move(split_callback.second))); } void BluetoothSerialPortImpl::OnSocketConnected(
diff --git a/services/device/serial/bluetooth_serial_port_impl.h b/services/device/serial/bluetooth_serial_port_impl.h index 11e6f082..b8f8421 100644 --- a/services/device/serial/bluetooth_serial_port_impl.h +++ b/services/device/serial/bluetooth_serial_port_impl.h
@@ -18,6 +18,8 @@ namespace device { +class BluetoothUUID; + // This class is intended to allow serial communication using a Bluetooth // SPP device. The Bluetooth device is used to create a Bluetooth socket // which is closed upon error in any of the interface functions. @@ -32,6 +34,7 @@ static void Open( scoped_refptr<BluetoothAdapter> adapter, const std::string& address, + const BluetoothUUID& service_class_id, mojom::SerialConnectionOptionsPtr options, mojo::PendingRemote<mojom::SerialPortClient> client, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher, @@ -61,7 +64,7 @@ void GetPortInfo(GetPortInfoCallback callback) override; void Close(CloseCallback callback) override; - void OpenSocket(OpenCallback callback); + void OpenSocket(const BluetoothUUID& service_class_id, OpenCallback callback); void WriteToSocket(MojoResult result, const mojo::HandleSignalsState& state); void ReadFromSocketAndWriteOut(MojoResult result, const mojo::HandleSignalsState& state);
diff --git a/services/device/serial/bluetooth_serial_port_impl_unittest.cc b/services/device/serial/bluetooth_serial_port_impl_unittest.cc index 1520ae2..1815399 100644 --- a/services/device/serial/bluetooth_serial_port_impl_unittest.cc +++ b/services/device/serial/bluetooth_serial_port_impl_unittest.cc
@@ -126,7 +126,7 @@ base::RunLoop loop; BluetoothSerialPortImpl::Open( - std::move(adapter), kDeviceAddress, + std::move(adapter), kDeviceAddress, GetSerialPortProfileUUID(), mojom::SerialConnectionOptions::New(), FakeSerialPortClient::Create(), std::move(watcher_remote), base::BindLambdaForTesting( @@ -181,8 +181,9 @@ base::RunLoop loop; BluetoothSerialPortImpl::Open( - std::move(adapter), kDeviceAddress, mojom::SerialConnectionOptions::New(), - FakeSerialPortClient::Create(), mojo::NullRemote(), + std::move(adapter), kDeviceAddress, GetSerialPortProfileUUID(), + mojom::SerialConnectionOptions::New(), FakeSerialPortClient::Create(), + mojo::NullRemote(), base::BindLambdaForTesting( [&](mojo::PendingRemote<mojom::SerialPort> remote) { EXPECT_FALSE(remote.is_valid());
diff --git a/services/device/serial/serial_port_manager_impl.cc b/services/device/serial/serial_port_manager_impl.cc index 022c8b367..ab34f0e3 100644 --- a/services/device/serial/serial_port_manager_impl.cc +++ b/services/device/serial/serial_port_manager_impl.cc
@@ -128,12 +128,14 @@ absl::optional<std::string> address = bluetooth_enumerator_->GetAddressFromToken(token); if (address) { + const BluetoothUUID service_class_id = + bluetooth_enumerator_->GetServiceClassIdFromToken(token); ui_task_runner_->PostTask( FROM_HERE, base::BindOnce( &SerialPortManagerImpl::OpenBluetoothSerialPortOnUI, - weak_factory_.GetWeakPtr(), *address, std::move(options), - std::move(client), std::move(watcher), + weak_factory_.GetWeakPtr(), *address, service_class_id, + std::move(options), std::move(client), std::move(watcher), base::BindOnce(&OnPortOpened, std::move(callback), base::SequencedTaskRunnerHandle::Get()))); return; @@ -145,13 +147,15 @@ void SerialPortManagerImpl::OpenBluetoothSerialPortOnUI( const std::string& address, + const BluetoothUUID& service_class_id, mojom::SerialConnectionOptionsPtr options, mojo::PendingRemote<mojom::SerialPortClient> client, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher, BluetoothSerialPortImpl::OpenCallback callback) { BluetoothSerialPortImpl::Open(bluetooth_enumerator_->GetAdapter(), address, - std::move(options), std::move(client), - std::move(watcher), std::move(callback)); + service_class_id, std::move(options), + std::move(client), std::move(watcher), + std::move(callback)); } void SerialPortManagerImpl::OnPortAdded(const mojom::SerialPortInfo& port) {
diff --git a/services/device/serial/serial_port_manager_impl.h b/services/device/serial/serial_port_manager_impl.h index 8cb5109c..18932f1 100644 --- a/services/device/serial/serial_port_manager_impl.h +++ b/services/device/serial/serial_port_manager_impl.h
@@ -27,6 +27,8 @@ namespace device { +class BluetoothUUID; + // TODO(leonhsl): Merge this class with SerialDeviceEnumerator if/once // SerialDeviceEnumerator is exposed only via the Device Service. // crbug.com/748505 @@ -75,6 +77,7 @@ void OpenBluetoothSerialPortOnUI( const std::string& address, + const BluetoothUUID& service_class_id, mojom::SerialConnectionOptionsPtr options, mojo::PendingRemote<mojom::SerialPortClient> client, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher,
diff --git a/services/device/serial/serial_port_manager_impl_unittest.cc b/services/device/serial/serial_port_manager_impl_unittest.cc index b8c0f14..bedbae79d 100644 --- a/services/device/serial/serial_port_manager_impl_unittest.cc +++ b/services/device/serial/serial_port_manager_impl_unittest.cc
@@ -372,7 +372,7 @@ } ASSERT_FALSE(port1_token.is_empty()); - bluetooth_enumerator_->PortRemoved(kDeviceAddress); + bluetooth_enumerator_->DeviceRemoved(kDeviceAddress); { base::RunLoop run_loop; EXPECT_CALL(client, OnPortRemoved(_))
diff --git a/services/network/cookie_access_delegate_impl.cc b/services/network/cookie_access_delegate_impl.cc index 65d4df57..3003ca5f 100644 --- a/services/network/cookie_access_delegate_impl.cc +++ b/services/network/cookie_access_delegate_impl.cc
@@ -6,7 +6,7 @@ #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_util.h" -#include "net/cookies/same_party_context.h" +#include "net/cookies/first_party_set_metadata.h" #include "services/network/first_party_sets/first_party_sets.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -55,13 +55,14 @@ return false; } -net::SamePartyContext CookieAccessDelegateImpl::ComputeSamePartyContext( +net::FirstPartySetMetadata +CookieAccessDelegateImpl::ComputeFirstPartySetMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const { - return first_party_sets_ ? first_party_sets_->ComputeContext( + return first_party_sets_ ? first_party_sets_->ComputeMetadata( site, top_frame_site, party_context) - : net::SamePartyContext(); + : net::FirstPartySetMetadata(); } absl::optional<net::SchemefulSite>
diff --git a/services/network/cookie_access_delegate_impl.h b/services/network/cookie_access_delegate_impl.h index f59940e..6a2f951 100644 --- a/services/network/cookie_access_delegate_impl.h +++ b/services/network/cookie_access_delegate_impl.h
@@ -9,7 +9,7 @@ #include "base/memory/raw_ptr.h" #include "net/cookies/cookie_access_delegate.h" #include "net/cookies/cookie_constants.h" -#include "net/cookies/same_party_context.h" +#include "net/cookies/first_party_set_metadata.h" #include "services/network/cookie_settings.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -49,7 +49,7 @@ bool ShouldIgnoreSameSiteRestrictions( const GURL& url, const net::SiteForCookies& site_for_cookies) const override; - net::SamePartyContext ComputeSamePartyContext( + net::FirstPartySetMetadata ComputeFirstPartySetMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const override;
diff --git a/services/network/cookie_manager.cc b/services/network/cookie_manager.cc index abce7ae..0503a986 100644 --- a/services/network/cookie_manager.cc +++ b/services/network/cookie_manager.cc
@@ -382,6 +382,9 @@ filter->excluding_domains.value().end()); } + delete_info.cookie_partition_key_collection = + filter->cookie_partition_key_collection; + return delete_info; }
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 9bba6ec8..beb8dc2d 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -928,8 +928,7 @@ // included, and non-SameParty cookies should be excluded based on SameSite // value. options.set_same_party_context( - net::SamePartyContext(net::SamePartyContext::Type::kSameParty, - net::FirstPartySetsContextType::kUnknown)); + net::SamePartyContext(net::SamePartyContext::Type::kSameParty)); EXPECT_THAT(service_wrapper()->GetCookieList( cookie_url, options, net::CookiePartitionKeyCollection()), UnorderedElementsAre( @@ -990,8 +989,7 @@ // Same-party, cross-site. options.set_same_party_context( - net::SamePartyContext(net::SamePartyContext::Type::kSameParty, - net::FirstPartySetsContextType::kUnknown)); + net::SamePartyContext(net::SamePartyContext::Type::kSameParty)); EXPECT_THAT( service_wrapper()->GetCookieList(cookie_url, options, net::CookiePartitionKeyCollection()), @@ -2723,6 +2721,10 @@ filter_ptr->url = GURL("https://www.example.com"); filter_ptr->session_control = mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES; + filter_ptr->cookie_partition_key_collection = + net::CookiePartitionKeyCollection( + net::CookiePartitionKey::FromURLForTesting( + GURL("https://www.foo.com"))); delete_info = DeletionFilterToInfo(std::move(filter_ptr)); EXPECT_EQ(base::Time::FromDoubleT(kTestStartEpoch), @@ -2748,6 +2750,12 @@ EXPECT_NE(delete_info.domains_and_ips_to_ignore.find("twelve.com"), delete_info.domains_and_ips_to_ignore.end()); EXPECT_FALSE(delete_info.value_for_testing.has_value()); + EXPECT_FALSE(delete_info.cookie_partition_key_collection.ContainsAllKeys()); + EXPECT_EQ(1u, + delete_info.cookie_partition_key_collection.PartitionKeys().size()); + EXPECT_EQ( + net::CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")), + delete_info.cookie_partition_key_collection.PartitionKeys()[0]); } // A test class having cookie store with a persistent backing store. The cookie
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc index 098cd38..e4112e8f 100644 --- a/services/network/first_party_sets/first_party_sets.cc +++ b/services/network/first_party_sets/first_party_sets.cc
@@ -24,6 +24,7 @@ #include "net/base/schemeful_site.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_util.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "services/network/first_party_sets/first_party_set_parser.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -156,7 +157,7 @@ return base::ranges::all_of(party_context, is_owned_by_site_owner); } -net::SamePartyContext FirstPartySets::ComputeContext( +net::FirstPartySetMetadata FirstPartySets::ComputeMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const { @@ -173,6 +174,8 @@ ContextTypeFromBool(IsContextSamePartyWithSite( site, top_frame_site, {}, true /* infer_singleton_sets */)); + net::SamePartyContext context(context_type, ancestors, top_resource); + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( "Cookie.FirstPartySets.ComputeContext.Latency", timer.Elapsed(), base::Microseconds(1), base::Milliseconds(100), 50); @@ -180,8 +183,9 @@ net::FirstPartySetsContextType first_party_sets_context_type = ComputeContextType(site, top_frame_site, party_context); - return net::SamePartyContext(context_type, ancestors, top_resource, - first_party_sets_context_type); + return net::FirstPartySetMetadata(context, + base::OptionalOrNullptr(FindOwner(site)), + first_party_sets_context_type); } net::FirstPartySetsContextType FirstPartySets::ComputeContextType(
diff --git a/services/network/first_party_sets/first_party_sets.h b/services/network/first_party_sets/first_party_sets.h index 83c239c..5afda58 100644 --- a/services/network/first_party_sets/first_party_sets.h +++ b/services/network/first_party_sets/first_party_sets.h
@@ -17,6 +17,7 @@ #include "base/thread_annotations.h" #include "net/base/schemeful_site.h" #include "net/cookies/cookie_constants.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -56,11 +57,8 @@ // Has no effect if `kFirstPartySets` is disabled. void ParseAndSet(base::File sets_file); - // Computes the SameParty context, indicating whether `site` is same-party - // with `top_frame_site` (if not nullptr) and `party_context`. The context - // includes the real context type, plus some additional "hypothetical" context - // types for metrics. - net::SamePartyContext ComputeContext( + // Computes the First-Party Set metadata related to the given context. + net::FirstPartySetMetadata ComputeMetadata( const net::SchemefulSite& site, const net::SchemefulSite* top_frame_site, const std::set<net::SchemefulSite>& party_context) const;
diff --git a/services/network/first_party_sets/first_party_sets_unittest.cc b/services/network/first_party_sets/first_party_sets_unittest.cc index 911c325..5448b9e 100644 --- a/services/network/first_party_sets/first_party_sets_unittest.cc +++ b/services/network/first_party_sets/first_party_sets_unittest.cc
@@ -13,6 +13,7 @@ #include "net/base/features.h" #include "net/base/schemeful_site.h" #include "net/cookies/cookie_constants.h" +#include "net/cookies/first_party_set_metadata.h" #include "net/cookies/same_party_context.h" #include "services/network/first_party_sets/first_party_set_parser.h" #include "testing/gmock/include/gmock/gmock-matchers.h" @@ -98,54 +99,43 @@ EXPECT_THAT(sets().Sets(), IsEmpty()); } -TEST_F(FirstPartySetsDisabledTest, ComputeContext_InfersSingletons) { +TEST_F(FirstPartySetsDisabledTest, ComputeMetadata_InfersSingletons) { net::SchemefulSite member(GURL("https://member1.test")); net::SchemefulSite example(GURL("https://example.test")); net::SchemefulSite wss_member(GURL("wss://member1.test")); // Works if the site is provided with WSS scheme instead of HTTPS. - EXPECT_THAT(sets().ComputeContext(wss_member, &member, {member, example}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_THAT( + sets().ComputeMetadata(wss_member, &member, {member, example}).context(), + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty)); - EXPECT_THAT(sets().ComputeContext(example, &member, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(member, &example, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_THAT(sets().ComputeMetadata(example, &member, {member}).context(), + net::SamePartyContext(Type::kCrossParty)); + EXPECT_THAT(sets().ComputeMetadata(member, &example, {member}).context(), + net::SamePartyContext(Type::kCrossParty)); // Top&resource differs from Ancestors. - EXPECT_THAT(sets().ComputeContext(member, &member, {example}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_THAT(sets().ComputeMetadata(member, &member, {example}).context(), + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty)); // Metrics values infer singleton sets when appropriate. - EXPECT_THAT(sets().ComputeContext(member, &member, {member}), - net::SamePartyContext( - Type::kCrossParty, Type::kSameParty, Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT(sets().ComputeContext(member, &example, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(example, &member, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(member, &member, {example}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_THAT(sets().ComputeMetadata(member, &member, {member}).context(), + net::SamePartyContext(Type::kCrossParty, Type::kSameParty, + Type::kSameParty)); + EXPECT_THAT(sets().ComputeMetadata(member, &example, {member}).context(), + net::SamePartyContext(Type::kCrossParty)); + EXPECT_THAT(sets().ComputeMetadata(example, &member, {member}).context(), + net::SamePartyContext(Type::kCrossParty)); + EXPECT_THAT(sets().ComputeMetadata(member, &member, {example}).context(), + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty)); - EXPECT_THAT(sets().ComputeContext(member, &member, {member, example}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_THAT( + sets().ComputeMetadata(member, &member, {member, example}).context(), + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty)); } TEST_F(FirstPartySetsDisabledTest, FindOwner) { @@ -967,7 +957,7 @@ } }; -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_EmptyContext) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_EmptyContext) { net::SchemefulSite example_site(GURL("https://example.test")); net::SchemefulSite nonmember(GURL("https://nonmember.test")); @@ -975,29 +965,40 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, {}) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, {}) + .context() .context_type(), Type::kCrossParty); - EXPECT_EQ(sets().ComputeContext(example_site, top_frame, {}).context_type(), + EXPECT_EQ(sets() + .ComputeMetadata(example_site, top_frame, {}) + .context() + .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, {}) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, {}) + .context() .context_type(), Type::kCrossParty); } - EXPECT_EQ(sets().ComputeContext(example_site, &nonmember, {}).context_type(), + EXPECT_EQ(sets() + .ComputeMetadata(example_site, &nonmember, {}) + .context() + .context_type(), Type::kCrossParty); - EXPECT_EQ(sets().ComputeContext(nonmember, &example_site, {}).context_type(), + EXPECT_EQ(sets() + .ComputeMetadata(nonmember, &example_site, {}) + .context() + .context_type(), Type::kCrossParty); } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextIsNonmember) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextIsNonmember) { std::set<net::SchemefulSite> context({ net::SchemefulSite(GURL("https://nonmember.test")), }); @@ -1008,48 +1009,54 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextIsOwner) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextIsOwner) { std::set<net::SchemefulSite> context( {net::SchemefulSite(GURL("https://example.test"))}); @@ -1059,48 +1066,54 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextIsMember) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextIsMember) { std::set<net::SchemefulSite> context( {net::SchemefulSite(GURL("https://member1.test"))}); @@ -1110,55 +1123,62 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextIsOwnerAndMember) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextIsOwnerAndMember) { std::set<net::SchemefulSite> context({ net::SchemefulSite(GURL("https://example.test")), net::SchemefulSite(GURL("https://member1.test")), @@ -1170,55 +1190,62 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member3.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member3.test")), + top_frame, context) + .context() .context_type(), Type::kSameParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextMixesParties) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextMixesParties) { std::set<net::SchemefulSite> context({ net::SchemefulSite(GURL("https://example.test")), net::SchemefulSite(GURL("https://member1.test")), @@ -1231,49 +1258,55 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } TEST_F(PopulatedFirstPartySetsTest, - ComputeContext_ContextMixesMembersAndNonmembers) { + ComputeMetadata_ContextMixesMembersAndNonmembers) { std::set<net::SchemefulSite> context({ net::SchemefulSite(GURL("https://example.test")), net::SchemefulSite(GURL("https://member1.test")), @@ -1286,48 +1319,54 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext_ContextMixesSchemes) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata_ContextMixesSchemes) { std::set<net::SchemefulSite> context({ net::SchemefulSite(GURL("https://example.test")), net::SchemefulSite(GURL("https://member1.test")), @@ -1340,48 +1379,54 @@ std::initializer_list<net::SchemefulSite*>{&example_site, nullptr}) { EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("http://example.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("http://example.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member1.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member1.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ(sets() - .ComputeContext(net::SchemefulSite(GURL("https://foo.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://foo.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://member2.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://member2.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); EXPECT_EQ( sets() - .ComputeContext(net::SchemefulSite(GURL("https://nonmember.test")), - top_frame, context) + .ComputeMetadata(net::SchemefulSite(GURL("https://nonmember.test")), + top_frame, context) + .context() .context_type(), Type::kCrossParty); } } -TEST_F(PopulatedFirstPartySetsTest, ComputeContext) { +TEST_F(PopulatedFirstPartySetsTest, ComputeMetadata) { net::SchemefulSite nonmember(GURL("https://nonmember.test")); net::SchemefulSite nonmember1(GURL("https://nonmember1.test")); net::SchemefulSite member(GURL("https://member1.test")); @@ -1390,79 +1435,87 @@ net::SchemefulSite wss_nonmember(GURL("wss://nonmember.test")); // Works as usual for sites that are in First-Party sets. - EXPECT_THAT( - sets().ComputeContext(member, &member, {member}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT( - sets().ComputeContext(owner, &member, {member}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT( - sets().ComputeContext(member, &owner, {member}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT( - sets().ComputeContext(member, &member, {owner}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT( - sets().ComputeContext(member, &member, {member, owner}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(member, &member, {member}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(owner, &member, {member}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(member, &owner, {member}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(member, &member, {owner}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(member, &member, {member, owner}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); // Works if the site is provided with WSS scheme instead of HTTPS. - EXPECT_THAT( - sets().ComputeContext(wss_member, &member, {member, owner}), - net::SamePartyContext(Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(wss_member, &member, {member, owner}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kSameParty), &owner, + net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT(sets().ComputeContext(nonmember, &member, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(member, &nonmember, {member}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT( - sets().ComputeContext(wss_nonmember, &wss_member, {member, owner}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_EQ(sets().ComputeMetadata(nonmember, &member, {member}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty), nullptr, + net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_EQ(sets().ComputeMetadata(member, &nonmember, {member}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty), &owner, + net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_EQ(sets().ComputeMetadata(wss_nonmember, &wss_member, {member, owner}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty), nullptr, + net::FirstPartySetsContextType::kTopResourceMismatch)); // Top&resource differs from Ancestors. - EXPECT_THAT(sets().ComputeContext(member, &member, {nonmember}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_EQ( + sets().ComputeMetadata(member, &member, {nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty), + &owner, net::FirstPartySetsContextType::kTopResourceMatchMixed)); // Metrics values infer singleton sets when appropriate. - EXPECT_THAT(sets().ComputeContext(nonmember, &nonmember, {nonmember}), - net::SamePartyContext( - Type::kCrossParty, Type::kSameParty, Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); - EXPECT_THAT(sets().ComputeContext(nonmember, &nonmember1, {nonmember}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(nonmember1, &nonmember, {nonmember}), - net::SamePartyContext( - Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch)); - EXPECT_THAT(sets().ComputeContext(nonmember, &nonmember, {nonmember1}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_EQ(sets().ComputeMetadata(nonmember, &nonmember, {nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty, Type::kSameParty, + Type::kSameParty), + nullptr, net::FirstPartySetsContextType::kHomogeneous)); + EXPECT_EQ(sets().ComputeMetadata(nonmember, &nonmember1, {nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty), nullptr, + net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_EQ(sets().ComputeMetadata(nonmember1, &nonmember, {nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty), nullptr, + net::FirstPartySetsContextType::kTopResourceMismatch)); + EXPECT_EQ( + sets().ComputeMetadata(nonmember, &nonmember, {nonmember1}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty), + nullptr, net::FirstPartySetsContextType::kTopResourceMatchMixed)); - EXPECT_THAT(sets().ComputeContext(member, &member, {member, nonmember}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); - EXPECT_THAT(sets().ComputeContext(nonmember, &nonmember, {member, nonmember}), - net::SamePartyContext( - Type::kCrossParty, Type::kCrossParty, Type::kSameParty, - net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_EQ( + sets().ComputeMetadata(member, &member, {member, nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty), + &owner, net::FirstPartySetsContextType::kTopResourceMatchMixed)); + EXPECT_EQ( + sets().ComputeMetadata(nonmember, &nonmember, {member, nonmember}), + net::FirstPartySetMetadata( + net::SamePartyContext(Type::kCrossParty, Type::kCrossParty, + Type::kSameParty), + nullptr, net::FirstPartySetsContextType::kTopResourceMatchMixed)); } TEST_F(PopulatedFirstPartySetsTest, FindOwner) {
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc index 1d16f3d..4854cb2 100644 --- a/services/network/network_service_network_delegate.cc +++ b/services/network/network_service_network_delegate.cc
@@ -358,6 +358,8 @@ url_loader_network_observer->OnClearSiteData( request->url(), header_value, request->load_flags(), + net::CookiePartitionKey::FromNetworkIsolationKey( + request->isolation_info().network_isolation_key()), base::BindOnce(&NetworkServiceNetworkDelegate::FinishedClearSiteData, weak_ptr_factory_.GetWeakPtr(), request->GetWeakPtr(), std::move(callback)));
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc index 17748ba4..1a29e98d 100644 --- a/services/network/network_service_unittest.cc +++ b/services/network/network_service_unittest.cc
@@ -1404,10 +1404,12 @@ explicit ClearSiteDataAuthCertObserver() = default; ~ClearSiteDataAuthCertObserver() override = default; - void OnClearSiteData(const GURL& url, - const std::string& header_value, - int load_flags, - OnClearSiteDataCallback callback) override { + void OnClearSiteData( + const GURL& url, + const std::string& header_value, + int load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) override { ++on_clear_site_data_counter_; last_on_clear_site_data_header_value_ = header_value; std::move(callback).Run();
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.cc b/services/network/public/cpp/cookie_manager_mojom_traits.cc index 93ae80c6..9c7778ae 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits.cc
@@ -427,56 +427,6 @@ return network::mojom::SamePartyCookieContextType::kCrossParty; } -bool EnumTraits<network::mojom::FirstPartySetsContextType, - net::FirstPartySetsContextType>:: - FromMojom(network::mojom::FirstPartySetsContextType type, - net::FirstPartySetsContextType* out) { - switch (type) { - case network::mojom::FirstPartySetsContextType::kUnknown: - *out = net::FirstPartySetsContextType::kUnknown; - return true; - case network::mojom::FirstPartySetsContextType::kTopFrameIgnoredMixed: - *out = net::FirstPartySetsContextType::kTopFrameIgnoredMixed; - return true; - case network::mojom::FirstPartySetsContextType::kTopFrameIgnoredHomogeneous: - *out = net::FirstPartySetsContextType::kTopFrameIgnoredHomogeneous; - return true; - case network::mojom::FirstPartySetsContextType::kTopResourceMismatch: - *out = net::FirstPartySetsContextType::kTopResourceMismatch; - return true; - case network::mojom::FirstPartySetsContextType::kTopResourceMatchMixed: - *out = net::FirstPartySetsContextType::kTopResourceMatchMixed; - return true; - case network::mojom::FirstPartySetsContextType::kHomogeneous: - *out = net::FirstPartySetsContextType::kHomogeneous; - return true; - } - return false; -} - -network::mojom::FirstPartySetsContextType EnumTraits< - network::mojom::FirstPartySetsContextType, - net::FirstPartySetsContextType>::ToMojom(net::FirstPartySetsContextType - type) { - switch (type) { - case net::FirstPartySetsContextType::kUnknown: - return network::mojom::FirstPartySetsContextType::kUnknown; - case net::FirstPartySetsContextType::kTopFrameIgnoredMixed: - return network::mojom::FirstPartySetsContextType::kTopFrameIgnoredMixed; - case net::FirstPartySetsContextType::kTopFrameIgnoredHomogeneous: - return network::mojom::FirstPartySetsContextType:: - kTopFrameIgnoredHomogeneous; - case net::FirstPartySetsContextType::kTopResourceMismatch: - return network::mojom::FirstPartySetsContextType::kTopResourceMismatch; - case net::FirstPartySetsContextType::kTopResourceMatchMixed: - return network::mojom::FirstPartySetsContextType::kTopResourceMatchMixed; - case net::FirstPartySetsContextType::kHomogeneous: - return network::mojom::FirstPartySetsContextType::kHomogeneous; - } - NOTREACHED(); - return network::mojom::FirstPartySetsContextType::kUnknown; -} - bool StructTraits<network::mojom::CookieOptionsDataView, net::CookieOptions>:: Read(network::mojom::CookieOptionsDataView mojo_options, net::CookieOptions* cookie_options) { @@ -723,13 +673,8 @@ if (!context.ReadTopResourceForMetricsOnly(&top_resource_for_metrics_only)) return false; - net::FirstPartySetsContextType first_party_sets_context_type; - if (!context.ReadFirstPartySetsContextType(&first_party_sets_context_type)) - return false; - *out = net::SamePartyContext(context_type, ancestors_for_metrics_only, - top_resource_for_metrics_only, - first_party_sets_context_type); + top_resource_for_metrics_only); return true; }
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.h b/services/network/public/cpp/cookie_manager_mojom_traits.h index 0dca5e4a..c2dc387 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.h +++ b/services/network/public/cpp/cookie_manager_mojom_traits.h
@@ -148,16 +148,6 @@ }; template <> -struct EnumTraits<network::mojom::FirstPartySetsContextType, - net::FirstPartySetsContextType> { - static network::mojom::FirstPartySetsContextType ToMojom( - net::FirstPartySetsContextType type); - - static bool FromMojom(network::mojom::FirstPartySetsContextType type, - net::FirstPartySetsContextType* out); -}; - -template <> struct StructTraits<network::mojom::CookieOptionsDataView, net::CookieOptions> { static bool exclude_httponly(const net::CookieOptions& o) { return o.exclude_httponly(); @@ -375,10 +365,6 @@ const net::SamePartyContext& s) { return s.top_resource_for_metrics_only(); } - static net::FirstPartySetsContextType first_party_sets_context_type( - const net::SamePartyContext& s) { - return s.first_party_sets_context_type(); - } static bool Read(network::mojom::SamePartyContextDataView bundle, net::SamePartyContext* out);
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc index 210396b..3ac4430f 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc
@@ -373,19 +373,6 @@ } } -TEST(CookieManagerTraitsTest, Roundtrips_FirstPartySetsContextType) { - using Type = net::FirstPartySetsContextType; - for (Type type : {Type::kUnknown, Type::kTopFrameIgnoredHomogeneous, - Type::kTopFrameIgnoredMixed, Type::kTopResourceMatchMixed, - Type::kTopResourceMismatch, Type::kHomogeneous}) { - Type roundtrip; - ASSERT_TRUE( - mojo::test::SerializeAndDeserialize<mojom::FirstPartySetsContextType>( - type, roundtrip)); - EXPECT_EQ(type, roundtrip); - } -} - TEST(CookieManagerTraitsTest, Roundtrips_PartitionKey) { auto original = net::CanonicalCookie::CreateUnsafeCookieForTesting( "__Host-A", "B", "x.y", "/", base::Time(), base::Time(), base::Time(), @@ -469,9 +456,7 @@ TEST(CookieManagerTraitsTest, RoundTrips_SamePartyContext) { { - net::SamePartyContext same_party( - net::SamePartyContext::Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous); + net::SamePartyContext same_party(net::SamePartyContext::Type::kSameParty); net::SamePartyContext copy; EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SamePartyContext>( @@ -481,14 +466,10 @@ net::SamePartyContext::Type::kSameParty); EXPECT_EQ(copy.top_resource_for_metrics_only(), net::SamePartyContext::Type::kSameParty); - EXPECT_EQ(copy.first_party_sets_context_type(), - net::FirstPartySetsContextType::kHomogeneous); } { - net::SamePartyContext cross_party( - net::SamePartyContext::Type::kCrossParty, - net::FirstPartySetsContextType::kTopResourceMismatch); + net::SamePartyContext cross_party(net::SamePartyContext::Type::kCrossParty); net::SamePartyContext copy; EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SamePartyContext>( @@ -498,8 +479,6 @@ net::SamePartyContext::Type::kCrossParty); EXPECT_EQ(copy.top_resource_for_metrics_only(), net::SamePartyContext::Type::kCrossParty); - EXPECT_EQ(copy.first_party_sets_context_type(), - net::FirstPartySetsContextType::kTopResourceMismatch); } } @@ -536,8 +515,7 @@ very_trusted.set_same_site_cookie_context( net::CookieOptions::SameSiteCookieContext::MakeInclusive()); very_trusted.set_same_party_context( - net::SamePartyContext(net::SamePartyContext::Type::kSameParty, - net::FirstPartySetsContextType::kHomogeneous)); + net::SamePartyContext(net::SamePartyContext::Type::kSameParty)); very_trusted.set_full_party_context_size(1u); very_trusted.set_is_in_nontrivial_first_party_set(true); @@ -553,8 +531,6 @@ copy.same_party_context().ancestors_for_metrics_only()); EXPECT_EQ(net::SamePartyContext::Type::kSameParty, copy.same_party_context().top_resource_for_metrics_only()); - EXPECT_EQ(copy.same_party_context().first_party_sets_context_type(), - net::FirstPartySetsContextType::kHomogeneous); EXPECT_EQ(1u, copy.full_party_context_size()); EXPECT_TRUE(copy.is_in_nontrivial_first_party_set()); }
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 6289361..63e390c 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -736,6 +736,7 @@ sources = [ "cookie_access_observer.mojom", "cookie_manager.mojom", + "cookie_partition_key.mojom", "restricted_cookie_manager.mojom", "site_for_cookies.mojom", ] @@ -809,6 +810,14 @@ cpp = "::net::CookieOptions" }, { + mojom = "network.mojom.CookiePartitionKey" + cpp = "::net::CookiePartitionKey" + }, + { + mojom = "network.mojom.CookiePartitionKeyCollection" + cpp = "::net::CookiePartitionKeyCollection" + }, + { mojom = "network.mojom.CookiePartitionKeyCollection" cpp = "::net::CookiePartitionKeyCollection" },
diff --git a/services/network/public/mojom/cookie_manager.mojom b/services/network/public/mojom/cookie_manager.mojom index ecb4f19..2007032 100644 --- a/services/network/public/mojom/cookie_manager.mojom +++ b/services/network/public/mojom/cookie_manager.mojom
@@ -6,8 +6,7 @@ import "components/content_settings/core/common/content_settings.mojom"; import "mojo/public/mojom/base/time.mojom"; -import "mojo/public/mojom/base/unguessable_token.mojom"; -import "services/network/public/mojom/schemeful_site.mojom"; +import "services/network/public/mojom/cookie_partition_key.mojom"; import "url/mojom/url.mojom"; // Parameters for constructing a cookie manager. @@ -127,26 +126,6 @@ kSameParty, }; -// This must be kept in sync with the corresponding enum in -// /net/cookies/cookie_constants.h. -enum FirstPartySetsContextType { - // Unknown context type. - kUnknown = 0, - // The top frame was ignored, and the rest of the context consisted of at - // least 2 different parties. - kTopFrameIgnoredMixed = 1, - // The top frame was ignored, and the rest of the context was a single party. - kTopFrameIgnoredHomogeneous = 2, - // The top frame and resource URL were of different parties. - kTopResourceMismatch = 3, - // The top frame and resource URL were both of the same party, and there was - // at least one intervening frame of a different party. - kTopResourceMatchMixed = 4, - // The top frame, resource URL, and all intervening frames were all from the - // same party. - kHomogeneous = 5, -}; - // What rules to apply when determining whether access to a particular cookie is // allowed. // Keep in sync with net/cookies/cookie_constants.h. @@ -170,22 +149,6 @@ bool is_in_nontrivial_first_party_set = false; }; -struct CookiePartitionKey { - SchemefulSite site; - - // Indicates the CookiePartitionKey is a placeholder indicating that the - // cookie should be partitioned, but it was created in the renderer so we - // don't know what its partition key is yet. - bool from_script = false; - - mojo_base.mojom.UnguessableToken? nonce; -}; - -struct CookiePartitionKeyCollection { - bool contains_all_partitions = false; - array<CookiePartitionKey> keys; -}; - // See net/cookies/canonical_cookie.{h,cc} for documentation. // Keep defaults here in sync with those files. struct CanonicalCookie { @@ -251,7 +214,6 @@ SamePartyCookieContextType context_type = kCrossParty; SamePartyCookieContextType ancestors_for_metrics_only = kCrossParty; SamePartyCookieContextType top_resource_for_metrics_only = kCrossParty; - FirstPartySetsContextType first_party_sets_context_type = kUnknown; }; // Keep values here in sync with net::CookieChangeCause. @@ -345,6 +307,11 @@ // Delete session/persistent cookies. CookieDeletionSessionControl session_control = IGNORE_CONTROL; + + // Only delete partitioned cookies contained in this + // CookiePartitionKeyCollection. + // See net/cookies/cookie_partition_key_collection.h for documentation. + CookiePartitionKeyCollection cookie_partition_key_collection; }; interface CookieChangeListener {
diff --git a/services/network/public/mojom/cookie_partition_key.mojom b/services/network/public/mojom/cookie_partition_key.mojom new file mode 100644 index 0000000..78f999d --- /dev/null +++ b/services/network/public/mojom/cookie_partition_key.mojom
@@ -0,0 +1,25 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +import "mojo/public/mojom/base/unguessable_token.mojom"; +import "services/network/public/mojom/schemeful_site.mojom"; + +struct CookiePartitionKey { + SchemefulSite site; + + // Indicates the CookiePartitionKey is a placeholder indicating that the + // cookie should be partitioned, but it was created in the renderer so we + // don't know what its partition key is yet. + bool from_script = false; + + mojo_base.mojom.UnguessableToken? nonce; +}; + +struct CookiePartitionKeyCollection { + bool contains_all_partitions = false; + array<CookiePartitionKey> keys; +}; +
diff --git a/services/network/public/mojom/url_loader_network_service_observer.mojom b/services/network/public/mojom/url_loader_network_service_observer.mojom index be3d57c..7f29d782c 100644 --- a/services/network/public/mojom/url_loader_network_service_observer.mojom +++ b/services/network/public/mojom/url_loader_network_service_observer.mojom
@@ -7,6 +7,7 @@ import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; +import "services/network/public/mojom/cookie_partition_key.mojom"; import "services/network/public/mojom/network_param.mojom"; import "url/mojom/url.mojom"; @@ -132,7 +133,8 @@ // Network Service for security concerns (e.g. |header_value| => booleans). OnClearSiteData(url.mojom.Url url, string header_value, - int32 load_flags) => (); + int32 load_flags, + CookiePartitionKey? cookie_partition_key) => (); // Called periodically to update the client about progress of the current // loads. To avoid flooding the client, it has to ack the update before it can @@ -151,4 +153,4 @@ // (e.g. when creating an observer for URLLoader from URLLoaderFactory's // observer). Clone(pending_receiver<URLLoaderNetworkServiceObserver> listener); -}; \ No newline at end of file +};
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc index 59ef2cf..f1829d7 100644 --- a/services/network/restricted_cookie_manager.cc +++ b/services/network/restricted_cookie_manager.cc
@@ -9,7 +9,7 @@ #include <vector> #include "base/bind.h" -#include "base/compiler_specific.h" // for FALLTHROUGH; +#include "base/compiler_specific.h" // for [[fallthrough]]; #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_macros.h" @@ -25,9 +25,10 @@ #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_inclusion_status.h" #include "net/cookies/cookie_options.h" +#include "net/cookies/cookie_partition_key.h" #include "net/cookies/cookie_store.h" #include "net/cookies/cookie_util.h" -#include "net/cookies/same_party_context.h" +#include "net/cookies/first_party_set_metadata.h" #include "services/network/cookie_settings.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" #include "services/network/public/mojom/cookie_manager.mojom.h" @@ -61,31 +62,28 @@ net::cookie_util::ComputeSameSiteContextForSubresource( url, site_for_cookies, force_ignore_site_for_cookies)); } - net::SchemefulSite request_site(url); // TODO(cfredric): the `force_ignore_top_frame_party` param below prevents // `document.cookie` access for same-party scripts embedded in an extension // frame. It would be better if we allowed that similarly to how we allow // SameParty cookies for requests in same-party contexts embedded in top-level // extension frames. bool force_ignore_top_frame_party = false; - net::SamePartyContext same_party_context = - net::cookie_util::ComputeSamePartyContext(request_site, isolation_info, - cookie_access_delegate, - force_ignore_top_frame_party); - options.set_same_party_context(same_party_context); + net::FirstPartySetMetadata first_party_set_metadata = + net::cookie_util::ComputeFirstPartySetMetadata( + /*request_site=*/net::SchemefulSite(url), isolation_info, + cookie_access_delegate, force_ignore_top_frame_party); + options.set_same_party_context(first_party_set_metadata.context()); if (isolation_info.party_context().has_value()) { // Count the top-frame site since it's not in the party_context. options.set_full_party_context_size(isolation_info.party_context()->size() + 1); } - bool is_in_nontrivial_first_party_set = - cookie_access_delegate && - cookie_access_delegate->FindFirstPartySetOwner(request_site).has_value(); options.set_is_in_nontrivial_first_party_set( - is_in_nontrivial_first_party_set); + first_party_set_metadata.owner().has_value()); - UMA_HISTOGRAM_ENUMERATION("Cookie.FirstPartySetsContextType.JS.Write", - same_party_context.first_party_sets_context_type()); + UMA_HISTOGRAM_ENUMERATION( + "Cookie.FirstPartySetsContextType.JS.Write", + first_party_set_metadata.first_party_sets_context_type()); return options; } @@ -114,26 +112,23 @@ net::cookie_util::ComputeSameSiteContextForSubresource( url, site_for_cookies, force_ignore_site_for_cookies)); } - net::SchemefulSite request_site(url); bool force_ignore_top_frame_party = false; - net::SamePartyContext same_party_context = - net::cookie_util::ComputeSamePartyContext(request_site, isolation_info, - cookie_access_delegate, - force_ignore_top_frame_party); - options.set_same_party_context(same_party_context); + net::FirstPartySetMetadata first_party_set_metadata = + net::cookie_util::ComputeFirstPartySetMetadata( + /*request_site=*/net::SchemefulSite(url), isolation_info, + cookie_access_delegate, force_ignore_top_frame_party); + options.set_same_party_context(first_party_set_metadata.context()); if (isolation_info.party_context().has_value()) { // Count the top-frame site since it's not in the party_context. options.set_full_party_context_size(isolation_info.party_context()->size() + 1); } - bool is_in_nontrivial_first_party_set = - cookie_access_delegate && - cookie_access_delegate->FindFirstPartySetOwner(request_site).has_value(); options.set_is_in_nontrivial_first_party_set( - is_in_nontrivial_first_party_set); + first_party_set_metadata.owner().has_value()); - UMA_HISTOGRAM_ENUMERATION("Cookie.FirstPartySetsContextType.JS.Read", - same_party_context.first_party_sets_context_type()); + UMA_HISTOGRAM_ENUMERATION( + "Cookie.FirstPartySetsContextType.JS.Read", + first_party_set_metadata.first_party_sets_context_type()); return options; } @@ -568,6 +563,13 @@ // equal to RestrictedCookieManager's partition key. absl::optional<net::CookiePartitionKey> cookie_partition_key = cookie.PartitionKey(); + + // If the `cookie_partition_key_` has a nonce then force all cookie writes to + // be in the nonce based partition even if the cookie was not set with the + // Partitioned attribute. + if (net::CookiePartitionKey::HasNonce(cookie_partition_key_)) { + cookie_partition_key = cookie_partition_key_; + } if (cookie_partition_key) { // RestrictedCookieManager having a null partition key strictly implies the // feature is disabled. If that is the case, we treat the cookie as @@ -576,8 +578,8 @@ cookie_partition_key = absl::nullopt; } else { bool cookie_partition_key_ok = - cookie.PartitionKey()->from_script() || - cookie.PartitionKey().value() == cookie_partition_key_.value(); + cookie_partition_key->from_script() || + cookie_partition_key.value() == cookie_partition_key_.value(); UMA_HISTOGRAM_BOOLEAN("Net.RestrictedCookieManager.CookiePartitionKeyOK", cookie_partition_key_ok); if (!cookie_partition_key_ok) { @@ -586,7 +588,7 @@ std::move(callback).Run(false); return; } - if (cookie.PartitionKey()->from_script()) { + if (cookie_partition_key->from_script()) { cookie_partition_key = cookie_partition_key_; } }
diff --git a/services/network/restricted_cookie_manager_unittest.cc b/services/network/restricted_cookie_manager_unittest.cc index 1988815..64aa3e3b 100644 --- a/services/network/restricted_cookie_manager_unittest.cc +++ b/services/network/restricted_cookie_manager_unittest.cc
@@ -21,10 +21,13 @@ #include "mojo/public/cpp/system/functions.h" #include "net/base/features.h" #include "net/base/isolation_info.h" +#include "net/base/network_isolation_key.h" +#include "net/base/schemeful_site.h" #include "net/cookies/canonical_cookie_test_helpers.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_inclusion_status.h" #include "net/cookies/cookie_monster.h" +#include "net/cookies/cookie_partition_key.h" #include "net/cookies/cookie_store.h" #include "net/cookies/cookie_store_test_callbacks.h" #include "net/cookies/cookie_util.h" @@ -277,8 +280,8 @@ net::CookieOptions::SameSiteCookieContext same_site_cookie_context( same_site_cookie_context_type, same_site_cookie_context_type); options.set_same_site_cookie_context(same_site_cookie_context); - options.set_same_party_context(net::SamePartyContext( - same_party_context_type, net::FirstPartySetsContextType::kUnknown)); + options.set_same_party_context( + net::SamePartyContext(same_party_context_type)); cookie_monster_.SetCanonicalCookieAsync( std::make_unique<net::CanonicalCookie>(cookie), @@ -1994,6 +1997,43 @@ } } +TEST_P(PartitionedCookiesRestrictedCookieManagerTest, PartitionKeyWithNonce) { + const GURL kCookieURL("https://example.com"); + const GURL kTopFrameURL("https://foo.com"); + const net::SiteForCookies kSiteForCookies = + net::SiteForCookies::FromUrl(kTopFrameURL); + const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL); + const base::UnguessableToken kNonce = base::UnguessableToken::Create(); + const absl::optional<std::set<net::SchemefulSite>> kPartyContextEmpty = + std::set<net::SchemefulSite>(); + const net::IsolationInfo kIsolationInfo = net::IsolationInfo::Create( + net::IsolationInfo::RequestType::kMainFrame, kTopFrameOrigin, + kTopFrameOrigin, kSiteForCookies, kPartyContextEmpty, &kNonce); + + service_->OverrideIsolationInfoForTesting(kIsolationInfo); + EXPECT_TRUE(sync_service_->SetCanonicalCookie( + *net::CanonicalCookie::Create( + kCookieURL, "__Host-foo=bar; Secure; SameSite=None; Path=/;", + base::Time::Now(), absl::nullopt /* server_time */, + net::CookiePartitionKey::FromScript()), + kCookieURL, kSiteForCookies, kTopFrameOrigin)); + + auto options = mojom::CookieManagerGetOptions::New(); + options->name = ""; + options->match_type = mojom::CookieMatchType::STARTS_WITH; + + net::CookieList cookies = sync_service_->GetAllForUrl( + kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options)); + ASSERT_EQ(1u, cookies.size()); + EXPECT_TRUE(cookies[0].IsPartitioned()); + EXPECT_EQ( + cookies[0].PartitionKey().value(), + net::CookiePartitionKey::FromNetworkIsolationKey( + net::NetworkIsolationKey(net::SchemefulSite(kTopFrameURL), + net::SchemefulSite(kTopFrameURL), &kNonce))); + EXPECT_EQ("__Host-foo", cookies[0].Name()); +} + INSTANTIATE_TEST_SUITE_P( PartitionedCookies, PartitionedCookiesRestrictedCookieManagerTest,
diff --git a/services/network/test/test_url_loader_network_observer.cc b/services/network/test/test_url_loader_network_observer.cc index 7bebdc1..70631ba 100644 --- a/services/network/test/test_url_loader_network_observer.cc +++ b/services/network/test/test_url_loader_network_observer.cc
@@ -47,6 +47,7 @@ const GURL& url, const std::string& header_value, int32_t load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, OnClearSiteDataCallback callback) { std::move(callback).Run(); }
diff --git a/services/network/test/test_url_loader_network_observer.h b/services/network/test/test_url_loader_network_observer.h index a98962db..e262f878 100644 --- a/services/network/test/test_url_loader_network_observer.h +++ b/services/network/test/test_url_loader_network_observer.h
@@ -46,10 +46,12 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnClearSiteData(const GURL& url, - const std::string& header_value, - int32_t load_flags, - OnClearSiteDataCallback callback) override; + void OnClearSiteData( + const GURL& url, + const std::string& header_value, + int32_t load_flags, + const absl::optional<net::CookiePartitionKey>& cookie_partition_key, + OnClearSiteDataCallback callback) override; void OnLoadingStateUpdate(mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) override; void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash,
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 6c4d8d4..2a7a0214 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -441,9 +441,27 @@ private: void StartAsync() { - const int result = NotifyConnected(transport_info_, base::DoNothing()); + // Simulate notifying caller of a connection. Call NotifyStartError() or + // NotifyHeadersComplete() synchronously/asynchronously on error/success, + // depending on return value and callback invocation. + const int result = NotifyConnected( + transport_info_, + base::BindOnce( + [](URLRequestFakeTransportInfoJob* job, int result) { + if (result != net::OK) { + job->NotifyStartError(result); + return; + } + job->NotifyHeadersComplete(); + }, + base::Unretained(this))); - if (result != net::OK && result != net::ERR_IO_PENDING) { + // Wait for callback to be invoked in async case. + if (result == net::ERR_IO_PENDING) + return; + + // Fail request on synchronous error. + if (result != net::OK) { NotifyStartError(result); return; }
diff --git a/skia/skia_resources.grd b/skia/skia_resources.grd index 5820b6a..86d3c7c 100644 --- a/skia/skia_resources.grd +++ b/skia/skia_resources.grd
@@ -17,11 +17,21 @@ resource_path="mojo/skia/public/mojom/bitmap.mojom-lite.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_SKIA_BITMAP_MOJOM_WEBUI_JS" + file="${root_gen_dir}/mojom-webui/skia/public/mojom/bitmap.mojom-webui.js" + resource_path="mojo/skia/public/mojom/bitmap.mojom-webui.js" + use_base_dir="false" + type="BINDATA" /> <include name="IDR_SKIA_IMAGE_INFO_MOJOM_LITE_JS" file="${root_gen_dir}/skia/public/mojom/image_info.mojom-lite.js" resource_path="mojo/skia/public/mojom/image_info.mojom-lite.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_SKIA_IMAGE_INFO_MOJOM_WEBUI_JS" + file="${root_gen_dir}/mojom-webui/skia/public/mojom/image_info.mojom-webui.js" + resource_path="mojo/skia/public/mojom/image_info.mojom-webui.js" + use_base_dir="false" + type="BINDATA" /> <include name="IDR_SKIA_SKCOLOR_MOJOM_LITE_JS" file="${root_gen_dir}/skia/public/mojom/skcolor.mojom-lite.js" resource_path="mojo/skia/public/mojom/skcolor.mojom-lite.js"
diff --git a/storage/browser/file_system/sandbox_directory_database.cc b/storage/browser/file_system/sandbox_directory_database.cc index e8eab17..9f6bb1b 100644 --- a/storage/browser/file_system/sandbox_directory_database.cc +++ b/storage/browser/file_system/sandbox_directory_database.cc
@@ -746,7 +746,7 @@ SandboxDirectoryRepairResult::DB_REPAIR_FAILED, SandboxDirectoryRepairResult::DB_REPAIR_MAX); LOG(WARNING) << "Failed to repair SandboxDirectoryDatabase."; - FALLTHROUGH; + [[fallthrough]]; case DELETE_ON_CORRUPTION: LOG(WARNING) << "Clearing SandboxDirectoryDatabase."; if (!leveldb_chrome::DeleteDB(filesystem_data_directory_, options).ok())
diff --git a/storage/browser/file_system/sandbox_origin_database.cc b/storage/browser/file_system/sandbox_origin_database.cc index 21c8ec8..800c124 100644 --- a/storage/browser/file_system/sandbox_origin_database.cc +++ b/storage/browser/file_system/sandbox_origin_database.cc
@@ -116,7 +116,7 @@ UMA_HISTOGRAM_ENUMERATION(kSandboxOriginDatabaseRepairHistogramLabel, SandboxOriginRepairResult::DB_REPAIR_FAILED, SandboxOriginRepairResult::DB_REPAIR_MAX); - FALLTHROUGH; + [[fallthrough]]; case DELETE_ON_CORRUPTION: if (!base::DeletePathRecursively(file_system_directory_)) return false;
diff --git a/storage/common/file_system/file_system_util.cc b/storage/common/file_system/file_system_util.cc index 34aa58c..fa7dbcd5 100644 --- a/storage/common/file_system/file_system_util.cc +++ b/storage/common/file_system/file_system_util.cc
@@ -280,7 +280,7 @@ case kFileSystemInternalTypeEnumStart: case kFileSystemInternalTypeEnumEnd: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case kFileSystemTypeUnknown: return "Unknown"; }
diff --git a/styleguide/c++/c++11.md b/styleguide/c++/c++11.md index 5b212cb..f6f0020 100644 --- a/styleguide/c++/c++11.md +++ b/styleguide/c++/c++11.md
@@ -382,6 +382,23 @@ The following C++17 language features are allowed in the Chromium codebase. +### Nested namespaces <sup>[allowed]</sup> + +```c++ +namespace A::B::C { ... +``` + +**Description:** Using the namespace resolution operator to create nested +namespace definitions. + +**Documentation:** +[Namespaces](https://en.cppreference.com/w/cpp/language/namespace) + +**Notes:** +*** promo +[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/gLdR3apDSmg/) +*** + ### Template argument deduction for class templates <sup>[allowed]</sup> ```c++ @@ -424,7 +441,7 @@ [@cxx discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/4GP43nftePE) *** -### fallthrough <sup>[allowed]</sup> +### fallthrough attribute <sup>[allowed]</sup> ```c++ case 1: @@ -685,23 +702,6 @@ None *** -### Nested namespaces <sup>[tbd]</sup> - -```c++ -namespace A::B::C { ... -``` - -**Description:** Using the namespace resolution operator to create nested -namespace definitions. - -**Documentation:** -[Namespaces](https://en.cppreference.com/w/cpp/language/namespace) - -**Notes:** -*** promo -None -*** - ### Structured bindings <sup>[tbd]</sup> ```c++ @@ -760,33 +760,44 @@ ### nodiscard attribute <sup>[tbd]</sup> ```c++ -[[nodiscard]] bool do_something() { ... +struct [[nodiscard]] ErrorOrValue; +[[nodiscard]] bool DoSomething(); ``` -**Description:** C++17 introduces the `[[nodiscard]]` attribute. +**Description:** +The `[[nodiscard]]` attribute can be used to indicate that + + - the return value of a function should not be ignored + - values of annotated classes/structs/enums returned from functions should not + be ignored **Documentation:** [C++ attribute: nodiscard](https://en.cppreference.com/w/cpp/language/attributes/nodiscard) **Notes:** *** promo -See similar attribute macro in base/compiler_specific.h. +See `WARN_UNUSED_RESULT` macro in base/compiler_specific.h. *** ### maybe_unused attribute <sup>[tbd]</sup> ```c++ +struct [[maybe_unused]] MyUnusedThing; [[maybe_unused]] int x; ``` -**Description:** C++17 introduces the `[[maybe_unused]]` attribute. +**Description:** +The `[[maybe_unused]]` attribute can be used to indicate that individual +variables or values of a class/struct/enum can be left unused (including values +with `[[nodiscard]]` attribute). **Documentation:** [C++ attribute: maybe_unused](https://en.cppreference.com/w/cpp/language/attributes/maybe_unused), **Notes:** *** promo -See similar attribute macro in base/compiler_specific.h. +Similar to the `ignore_result` function in base/ignore_result.h [(and other +places)](https://source.chromium.org/search?q=function:ignore_result&sq=). *** ### using declaration for attributes <sup>[tbd]</sup>
diff --git a/testing/PRESUBMIT.py b/testing/PRESUBMIT.py index 65f2d62..2806e893 100644 --- a/testing/PRESUBMIT.py +++ b/testing/PRESUBMIT.py
@@ -29,7 +29,11 @@ [r'^.+_unittest\.py$'], env=testing_env)) output.extend(input_api.canned_checks.RunPylint( - input_api, output_api, files_to_skip=[r'gmock.*', r'gtest.*'])) + input_api, output_api, files_to_skip=[r'gmock.*', r'gtest.*', + r'merge_scripts.*'])) + output.extend(input_api.canned_checks.RunPylint( + input_api, output_api, files_to_skip=[r'gmock.*', r'gtest.*', + r'(?!merge_scripts).*'], version='2.6')) return output
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index d67412b2..9561213 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -1743,7 +1743,7 @@ { "args": [], "cros_board": "atlas", - "cros_img": "atlas-release/R97-14324.49.0", + "cros_img": "atlas-release/R97-14324.56.0", "name": "lacros_all_tast_tests_ATLAS_BETA", "resultdb": { "enable": true, @@ -1758,7 +1758,7 @@ { "args": [], "cros_board": "atlas", - "cros_img": "atlas-release/R96-14268.67.0", + "cros_img": "atlas-release/R97-14324.62.0", "name": "lacros_all_tast_tests_ATLAS_STABLE", "resultdb": { "enable": true, @@ -1803,7 +1803,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R97-14324.49.0", + "cros_img": "eve-release/R97-14324.56.0", "name": "lacros_all_tast_tests_EVE_BETA", "resultdb": { "enable": true,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 2507a6f5..cb036ee 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -5094,82 +5094,6 @@ "--bucket", "chromium-result-details", "--test-name", - "webview_64_cts_tests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/android_webview/tools/cts_archive", - "location": "android_webview/tools/cts_archive", - "revision": "ai8Ig4HlO0vG6aP_JP2uhyruE2yPzze8PFP1g8Z4_hgC" - }, - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "machine_type": "e2-standard-8", - "os": "Ubuntu-16.04|Ubuntu-18.04", - "pool": "chromium.tests.avd" - } - ], - "named_caches": [ - { - "name": "avd_generic_android31", - "path": ".android" - }, - { - "name": "system_images_android_31_google_apis_x64", - "path": ".emulator_sdk" - } - ], - "optional_dimensions": { - "60": [ - { - "caches": "avd_generic_android31" - } - ] - }, - "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", - "shards": 2 - }, - "test": "webview_64_cts_tests", - "test_id_prefix": "ninja://android_webview/test:webview_64_cts_tests/" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details", - "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", "webview_instrumentation_test_apk" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 6e87cac7..79b786d 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -37509,2540 +37509,6 @@ "all" ] }, - "ToTWinCFI": { - "additional_compile_targets": [ - "all" - ], - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "absl_hardening_tests", - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "accessibility_unittests", - "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" - }, - { - "args": [ - "angle_unittests" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_unittests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", - "use_isolated_scripts_api": true - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "app_shell_unittests", - "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "aura_unittests", - "test_id_prefix": "ninja://ui/aura:aura_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_common_unittests", - "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_fuzzer_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_heap_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_platform_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_crypto_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_ssl_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "browser_switcher_bho_unittests", - "test_id_prefix": "ninja://chrome/browser/browser_switcher/bho:browser_switcher_bho_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "capture_unittests", - "test_id_prefix": "ninja://media/capture:capture_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cast_unittests", - "test_id_prefix": "ninja://media/cast:cast_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cc_unittests", - "test_id_prefix": "ninja://cc:cc_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_app_unittests", - "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_cleaner_unittests", - "test_id_prefix": "ninja://chrome/chrome_cleaner:chrome_cleaner_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_elf_unittests", - "test_id_prefix": "ninja://chrome/chrome_elf:chrome_elf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chromedriver_unittests", - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "color_unittests", - "test_id_prefix": "ninja://ui/color:color_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_browsertests", - "test_id_prefix": "ninja://components:components_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "compositor_unittests", - "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_unittests", - "test_id_prefix": "ninja://content/test:content_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "courgette_unittests", - "test_id_prefix": "ninja://courgette:courgette_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crashpad_tests", - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_tests", - "test_id_prefix": "ninja://components/cronet:cronet_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_unittests", - "test_id_prefix": "ninja://components/cronet:cronet_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crypto_unittests", - "test_id_prefix": "ninja://crypto:crypto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "delayloads_unittests", - "test_id_prefix": "ninja://chrome/test:delayloads_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "device_unittests", - "test_id_prefix": "ninja://device:device_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "display_unittests", - "test_id_prefix": "ninja://ui/display:display_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "elevation_service_unittests", - "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "events_unittests", - "test_id_prefix": "ninja://ui/events:events_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_browsertests", - "test_id_prefix": "ninja://extensions:extensions_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_unittests", - "test_id_prefix": "ninja://extensions:extensions_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "filesystem_service_unittests", - "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcm_unit_tests", - "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcp_unittests", - "test_id_prefix": "ninja://chrome/credential_provider/test:gcp_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gfx_unittests", - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gin_unittests", - "test_id_prefix": "ninja://gin:gin_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "google_apis_unittests", - "test_id_prefix": "ninja://google_apis:google_apis_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gpu_unittests", - "test_id_prefix": "ninja://gpu:gpu_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gwp_asan_unittests", - "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_browsertests", - "test_id_prefix": "ninja://headless:headless_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_unittests", - "test_id_prefix": "ninja://headless:headless_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "install_static_unittests", - "test_id_prefix": "ninja://chrome/install_static:install_static_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "installer_util_unittests", - "test_id_prefix": "ninja://chrome/installer/util:installer_util_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ipc_tests", - "test_id_prefix": "ninja://ipc:ipc_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "jingle_unittests", - "test_id_prefix": "ninja://jingle:jingle_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "latency_unittests", - "test_id_prefix": "ninja://ui/latency:latency_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "libjingle_xmpp_unittests", - "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "liburlpattern_unittests", - "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "media_unittests", - "test_id_prefix": "ninja://media:media_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "message_center_unittests", - "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "midi_unittests", - "test_id_prefix": "ninja://media/midi:midi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_core_unittests", - "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_unittests", - "test_id_prefix": "ninja://mojo:mojo_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "nacl_loader_unittests", - "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "native_theme_unittests", - "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "net_unittests", - "test_id_prefix": "ninja://net:net_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "pdf_unittests", - "test_id_prefix": "ninja://pdf:pdf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "perfetto_unittests", - "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ppapi_unittests", - "test_id_prefix": "ninja://ppapi:ppapi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "printing_unittests", - "test_id_prefix": "ninja://printing:printing_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "remoting_unittests", - "test_id_prefix": "ninja://remoting:remoting_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_integration_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_integration_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_unittests", - "test_id_prefix": "ninja://sandbox/win:sbox_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_validation_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_validation_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "service_manager_unittests", - "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "services_unittests", - "test_id_prefix": "ninja://services:services_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "setup_unittests", - "test_id_prefix": "ninja://chrome/installer/setup:setup_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "shell_dialogs_unittests", - "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "skia_unittests", - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "snapshot_unittests", - "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sql_unittests", - "test_id_prefix": "ninja://sql:sql_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "storage_unittests", - "test_id_prefix": "ninja://storage:storage_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sync_integration_tests", - "test_id_prefix": "ninja://chrome/test:sync_integration_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_base_unittests", - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_touch_selection_unittests", - "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "unit_tests", - "test_id_prefix": "ninja://chrome/test:unit_tests/" - }, - { - "args": [ - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests", - "test_id_prefix": "ninja://chrome/updater:updater_tests/" - }, - { - "args": [ - "--test-launcher-print-test-stdio=always", - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000", - "--ui-test-action-timeout=40000" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests_system", - "test_id_prefix": "ninja://chrome/updater:updater_tests_system/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "url_unittests", - "test_id_prefix": "ninja://url:url_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "viz_unittests", - "test_id_prefix": "ninja://components/viz:viz_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_common_unittests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_pixeltests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_browsertests", - "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_unittests", - "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wm_unittests", - "test_id_prefix": "ninja://ui/wm:wm_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wtf_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zlib_unittests", - "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zucchini_unittests", - "test_id_prefix": "ninja://components/zucchini:zucchini_unittests/" - } - ], - "isolated_scripts": [ - { - "isolate_name": "mini_installer_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "mini_installer_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test/mini_installer:mini_installer_tests/" - }, - { - "experiment_percentage": 100, - "isolate_name": "polymer_tools_python_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "polymer_tools_python_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/polymer:polymer_tools_python_unittests/" - } - ] - }, - "ToTWinCFI64": { - "additional_compile_targets": [ - "all" - ], - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "absl_hardening_tests", - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "accessibility_unittests", - "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" - }, - { - "args": [ - "angle_unittests" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_unittests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", - "use_isolated_scripts_api": true - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "app_shell_unittests", - "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "aura_unittests", - "test_id_prefix": "ninja://ui/aura:aura_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_common_unittests", - "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_fuzzer_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_heap_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_platform_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_crypto_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_ssl_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "browser_switcher_bho_unittests", - "test_id_prefix": "ninja://chrome/browser/browser_switcher/bho:browser_switcher_bho_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "capture_unittests", - "test_id_prefix": "ninja://media/capture:capture_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cast_unittests", - "test_id_prefix": "ninja://media/cast:cast_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cc_unittests", - "test_id_prefix": "ninja://cc:cc_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_app_unittests", - "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_cleaner_unittests", - "test_id_prefix": "ninja://chrome/chrome_cleaner:chrome_cleaner_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_elf_unittests", - "test_id_prefix": "ninja://chrome/chrome_elf:chrome_elf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chromedriver_unittests", - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "color_unittests", - "test_id_prefix": "ninja://ui/color:color_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_browsertests", - "test_id_prefix": "ninja://components:components_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "compositor_unittests", - "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_unittests", - "test_id_prefix": "ninja://content/test:content_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "courgette_unittests", - "test_id_prefix": "ninja://courgette:courgette_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crashpad_tests", - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_tests", - "test_id_prefix": "ninja://components/cronet:cronet_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_unittests", - "test_id_prefix": "ninja://components/cronet:cronet_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crypto_unittests", - "test_id_prefix": "ninja://crypto:crypto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "delayloads_unittests", - "test_id_prefix": "ninja://chrome/test:delayloads_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "device_unittests", - "test_id_prefix": "ninja://device:device_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "display_unittests", - "test_id_prefix": "ninja://ui/display:display_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "elevation_service_unittests", - "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "events_unittests", - "test_id_prefix": "ninja://ui/events:events_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_browsertests", - "test_id_prefix": "ninja://extensions:extensions_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_unittests", - "test_id_prefix": "ninja://extensions:extensions_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "filesystem_service_unittests", - "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcm_unit_tests", - "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcp_unittests", - "test_id_prefix": "ninja://chrome/credential_provider/test:gcp_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gfx_unittests", - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gin_unittests", - "test_id_prefix": "ninja://gin:gin_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "google_apis_unittests", - "test_id_prefix": "ninja://google_apis:google_apis_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gpu_unittests", - "test_id_prefix": "ninja://gpu:gpu_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gwp_asan_unittests", - "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_browsertests", - "test_id_prefix": "ninja://headless:headless_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_unittests", - "test_id_prefix": "ninja://headless:headless_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "install_static_unittests", - "test_id_prefix": "ninja://chrome/install_static:install_static_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "installer_util_unittests", - "test_id_prefix": "ninja://chrome/installer/util:installer_util_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ipc_tests", - "test_id_prefix": "ninja://ipc:ipc_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "jingle_unittests", - "test_id_prefix": "ninja://jingle:jingle_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "latency_unittests", - "test_id_prefix": "ninja://ui/latency:latency_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "libjingle_xmpp_unittests", - "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "liburlpattern_unittests", - "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "media_unittests", - "test_id_prefix": "ninja://media:media_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "message_center_unittests", - "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "midi_unittests", - "test_id_prefix": "ninja://media/midi:midi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_core_unittests", - "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_unittests", - "test_id_prefix": "ninja://mojo:mojo_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "nacl_loader_unittests", - "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "native_theme_unittests", - "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "net_unittests", - "test_id_prefix": "ninja://net:net_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "pdf_unittests", - "test_id_prefix": "ninja://pdf:pdf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "perfetto_unittests", - "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ppapi_unittests", - "test_id_prefix": "ninja://ppapi:ppapi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "printing_unittests", - "test_id_prefix": "ninja://printing:printing_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "remoting_unittests", - "test_id_prefix": "ninja://remoting:remoting_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_integration_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_integration_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_unittests", - "test_id_prefix": "ninja://sandbox/win:sbox_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_validation_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_validation_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "service_manager_unittests", - "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "services_unittests", - "test_id_prefix": "ninja://services:services_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "setup_unittests", - "test_id_prefix": "ninja://chrome/installer/setup:setup_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "shell_dialogs_unittests", - "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "skia_unittests", - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "snapshot_unittests", - "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sql_unittests", - "test_id_prefix": "ninja://sql:sql_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "storage_unittests", - "test_id_prefix": "ninja://storage:storage_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sync_integration_tests", - "test_id_prefix": "ninja://chrome/test:sync_integration_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_base_unittests", - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_touch_selection_unittests", - "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "unit_tests", - "test_id_prefix": "ninja://chrome/test:unit_tests/" - }, - { - "args": [ - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests", - "test_id_prefix": "ninja://chrome/updater:updater_tests/" - }, - { - "args": [ - "--test-launcher-print-test-stdio=always", - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000", - "--ui-test-action-timeout=40000" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests_system", - "test_id_prefix": "ninja://chrome/updater:updater_tests_system/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "url_unittests", - "test_id_prefix": "ninja://url:url_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "viz_unittests", - "test_id_prefix": "ninja://components/viz:viz_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_common_unittests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_pixeltests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_browsertests", - "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_unittests", - "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wm_unittests", - "test_id_prefix": "ninja://ui/wm:wm_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wtf_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zlib_unittests", - "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zucchini_unittests", - "test_id_prefix": "ninja://components/zucchini:zucchini_unittests/" - } - ], - "isolated_scripts": [ - { - "isolate_name": "mini_installer_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "mini_installer_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "integrity": "high" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test/mini_installer:mini_installer_tests/" - }, - { - "experiment_percentage": 100, - "isolate_name": "polymer_tools_python_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "polymer_tools_python_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/polymer:polymer_tools_python_unittests/" - } - ] - }, "ToTWinOfficial": { "additional_compile_targets": [ "chrome_official_builder"
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json index 492730c9..3dec5a8 100644 --- a/testing/buildbot/chromium.dawn.json +++ b/testing/buildbot/chromium.dawn.json
@@ -226,7 +226,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--no-xvfb", "--additional-driver-flag=--enable-features=UseSkiaRenderer,Vulkan" ], @@ -480,7 +480,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--no-xvfb", "--additional-driver-flag=--enable-features=UseSkiaRenderer,Vulkan" ], @@ -734,7 +734,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--no-xvfb", "--additional-driver-flag=--enable-features=UseSkiaRenderer,Vulkan" ], @@ -988,7 +988,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--no-xvfb", "--additional-driver-flag=--enable-features=UseSkiaRenderer,Vulkan" ], @@ -1261,7 +1261,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--platform=mac-mac11" ], "isolate_name": "webgpu_blink_web_tests", @@ -1516,7 +1516,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--platform=mac-mac11" ], "isolate_name": "webgpu_blink_web_tests", @@ -1861,7 +1861,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--platform=mac-mac11" ], "isolate_name": "webgpu_blink_web_tests", @@ -2116,7 +2116,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--platform=mac-mac11" ], "isolate_name": "webgpu_blink_web_tests", @@ -2337,7 +2337,7 @@ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu", "--target=Release_x64", - "--time-out-ms=48000" + "--timeout-ms=48000" ], "isolate_name": "webgpu_blink_web_tests", "merge": { @@ -2589,7 +2589,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--target=Release_x64" ], "isolate_name": "webgpu_blink_web_tests", @@ -2835,7 +2835,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--target=Release_x64" ], "isolate_name": "webgpu_blink_web_tests", @@ -3081,7 +3081,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--target=Release_x64" ], "isolate_name": "webgpu_blink_web_tests", @@ -3327,7 +3327,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000", + "--timeout-ms=30000", "--target=Release_x64" ], "isolate_name": "webgpu_blink_web_tests", @@ -3574,7 +3574,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000" + "--timeout-ms=30000" ], "isolate_name": "webgpu_blink_web_tests", "merge": { @@ -3818,7 +3818,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000" + "--timeout-ms=30000" ], "isolate_name": "webgpu_blink_web_tests", "merge": { @@ -4062,7 +4062,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000" + "--timeout-ms=30000" ], "isolate_name": "webgpu_blink_web_tests", "merge": { @@ -4306,7 +4306,7 @@ "args": [ "--initialize-webgpu-adapter-at-startup-timeout-ms=60000", "--flag-specific=webgpu-with-partial-backend-validation", - "--time-out-ms=30000" + "--timeout-ms=30000" ], "isolate_name": "webgpu_blink_web_tests", "merge": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 405e3c1..bddb60c 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -1580,7 +1580,6 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", "--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan", "--use-vulkan=swiftshader", - "--enable-oop-rasterization", "--enable-gpu-rasterization", "--disable-software-compositing-fallback", "--disable-vulkan-fallback-to-gl-for-testing", @@ -5007,2342 +5006,6 @@ } ] }, - "Win10 Tests x64 20h2": { - "gtest_tests": [ - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "absl_hardening_tests", - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "accessibility_unittests", - "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" - }, - { - "args": [ - "angle_unittests" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_unittests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", - "use_isolated_scripts_api": true - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "app_shell_unittests", - "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "aura_unittests", - "test_id_prefix": "ninja://ui/aura:aura_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_common_unittests", - "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_fuzzer_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_heap_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_platform_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_crypto_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_ssl_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "browser_switcher_bho_unittests", - "test_id_prefix": "ninja://chrome/browser/browser_switcher/bho:browser_switcher_bho_unittests/" - }, - { - "args": [ - "--disable-features=WebRTC-H264WithOpenH264FFmpeg" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 15 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_browser_tests.filter", - "--git-revision=${got_revision}" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "pixel_browser_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "capture_unittests", - "test_id_prefix": "ninja://media/capture:capture_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cast_unittests", - "test_id_prefix": "ninja://media/cast:cast_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cc_unittests", - "test_id_prefix": "ninja://cc:cc_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_app_unittests", - "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_cleaner_unittests", - "test_id_prefix": "ninja://chrome/chrome_cleaner:chrome_cleaner_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_elf_unittests", - "test_id_prefix": "ninja://chrome/chrome_elf:chrome_elf_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chromedriver_unittests", - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "color_unittests", - "test_id_prefix": "ninja://ui/color:color_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_browsertests", - "test_id_prefix": "ninja://components:components_browsertests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "compositor_unittests", - "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" - }, - { - "args": [ - "--disable-features=WebRTC-H264WithOpenH264FFmpeg" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_unittests", - "test_id_prefix": "ninja://content/test:content_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "courgette_unittests", - "test_id_prefix": "ninja://courgette:courgette_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crashpad_tests", - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_tests", - "test_id_prefix": "ninja://components/cronet:cronet_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_unittests", - "test_id_prefix": "ninja://components/cronet:cronet_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crypto_unittests", - "test_id_prefix": "ninja://crypto:crypto_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "delayloads_unittests", - "test_id_prefix": "ninja://chrome/test:delayloads_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "device_unittests", - "test_id_prefix": "ninja://device:device_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "display_unittests", - "test_id_prefix": "ninja://ui/display:display_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "elevation_service_unittests", - "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "events_unittests", - "test_id_prefix": "ninja://ui/events:events_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_browsertests", - "test_id_prefix": "ninja://extensions:extensions_browsertests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_unittests", - "test_id_prefix": "ninja://extensions:extensions_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "filesystem_service_unittests", - "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcm_unit_tests", - "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcp_unittests", - "test_id_prefix": "ninja://chrome/credential_provider/test:gcp_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gfx_unittests", - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gin_unittests", - "test_id_prefix": "ninja://gin:gin_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "google_apis_unittests", - "test_id_prefix": "ninja://google_apis:google_apis_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gpu_unittests", - "test_id_prefix": "ninja://gpu:gpu_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gwp_asan_unittests", - "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_browsertests", - "test_id_prefix": "ninja://headless:headless_browsertests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_unittests", - "test_id_prefix": "ninja://headless:headless_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "install_static_unittests", - "test_id_prefix": "ninja://chrome/install_static:install_static_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "integrity": "high", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "installer_util_unittests", - "test_id_prefix": "ninja://chrome/installer/util:installer_util_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ipc_tests", - "test_id_prefix": "ninja://ipc:ipc_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "jingle_unittests", - "test_id_prefix": "ninja://jingle:jingle_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "latency_unittests", - "test_id_prefix": "ninja://ui/latency:latency_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "libjingle_xmpp_unittests", - "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "liburlpattern_unittests", - "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "media_unittests", - "test_id_prefix": "ninja://media:media_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "message_center_unittests", - "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "midi_unittests", - "test_id_prefix": "ninja://media/midi:midi_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_core_unittests", - "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_unittests", - "test_id_prefix": "ninja://mojo:mojo_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "nacl_loader_unittests", - "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "native_theme_unittests", - "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "net_unittests", - "test_id_prefix": "ninja://net:net_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "notification_helper_unittests", - "test_id_prefix": "ninja://chrome/notification_helper:notification_helper_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "pdf_unittests", - "test_id_prefix": "ninja://pdf:pdf_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "perfetto_unittests", - "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ppapi_unittests", - "test_id_prefix": "ninja://ppapi:ppapi_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "printing_unittests", - "test_id_prefix": "ninja://printing:printing_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "remoting_unittests", - "test_id_prefix": "ninja://remoting:remoting_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "integrity": "high", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_integration_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_integration_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_unittests", - "test_id_prefix": "ninja://sandbox/win:sbox_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sbox_validation_tests", - "test_id_prefix": "ninja://sandbox/win:sbox_validation_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "service_manager_unittests", - "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "services_unittests", - "test_id_prefix": "ninja://services:services_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "integrity": "high", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "setup_unittests", - "test_id_prefix": "ninja://chrome/installer/setup:setup_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "shell_dialogs_unittests", - "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "skia_unittests", - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "snapshot_unittests", - "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sql_unittests", - "test_id_prefix": "ninja://sql:sql_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "storage_unittests", - "test_id_prefix": "ninja://storage:storage_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sync_integration_tests", - "test_id_prefix": "ninja://chrome/test:sync_integration_tests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_base_unittests", - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_touch_selection_unittests", - "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "unit_tests", - "test_id_prefix": "ninja://chrome/test:unit_tests/" - }, - { - "args": [ - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests", - "test_id_prefix": "ninja://chrome/updater:updater_tests/" - }, - { - "args": [ - "--test-launcher-print-test-stdio=always", - "--test-launcher-timeout=90000", - "--ui-test-action-max-timeout=45000", - "--ui-test-action-timeout=40000", - "--ui-test-action-timeout=40000" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests_system", - "test_id_prefix": "ninja://chrome/updater:updater_tests_system/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "url_unittests", - "test_id_prefix": "ninja://url:url_unittests/" - }, - { - "args": [ - "--git-revision=${got_revision}" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_examples_unittests", - "test_id_prefix": "ninja://ui/views/examples:views_examples_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "viz_unittests", - "test_id_prefix": "ninja://components/viz:viz_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_common_unittests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_pixeltests", - "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_browsertests", - "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "weblayer_unittests", - "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wm_unittests", - "test_id_prefix": "ninja://ui/wm:wm_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wtf_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zlib_unittests", - "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" - }, - { - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zucchini_unittests", - "test_id_prefix": "ninja://components/zucchini:zucchini_unittests/" - } - ], - "isolated_scripts": [ - { - "isolate_name": "blink_python_tests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "blink_python_tests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://:blink_python_tests/" - }, - { - "args": [ - "--num-retries=3", - "--target", - "Release_x64" - ], - "isolate_name": "blink_web_tests", - "isolate_profile_data": true, - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "blink_web_tests", - "resultdb": { - "enable": true - }, - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 28 - }, - "test_id_prefix": "ninja://:blink_web_tests/" - }, - { - "args": [ - "--test-type=integration" - ], - "isolate_name": "chromedriver_py_tests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "chromedriver_py_tests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_py_tests/" - }, - { - "isolate_name": "chromedriver_replay_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "chromedriver_replay_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_replay_unittests/" - }, - { - "args": [ - "--gtest-benchmark-name=components_perftests" - ], - "isolate_name": "components_perftests", - "isolate_profile_data": true, - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "components_perftests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_perftests/" - }, - { - "isolate_name": "content_shell_crash_test", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "content_shell_crash_test", - "resultdb": { - "enable": true, - "result_format": "single" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" - }, - { - "isolate_name": "flatbuffers_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "flatbuffers_unittests", - "resultdb": { - "enable": true, - "result_format": "single" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/flatbuffers:flatbuffers_unittests/" - }, - { - "isolate_name": "grit_python_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "grit_python_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/grit:grit_python_unittests/" - }, - { - "isolate_name": "mini_installer_tests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "mini_installer_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "integrity": "high", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test/mini_installer:mini_installer_tests/" - }, - { - "isolate_name": "mojo_python_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "mojo_python_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://mojo/public/tools:mojo_python_unittests/" - }, - { - "experiment_percentage": 100, - "isolate_name": "polymer_tools_python_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "polymer_tools_python_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/polymer:polymer_tools_python_unittests/" - }, - { - "args": [ - "BrowserMinidumpTest", - "-v", - "--passthrough", - "--retry-limit=2" - ], - "isolate_name": "telemetry_perf_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_desktop_minidump_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" - }, - { - "isolate_name": "telemetry_gpu_unittests", - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_gpu_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_unittests/" - }, - { - "args": [ - "--gtest-benchmark-name=views_perftests" - ], - "isolate_name": "views_perftests", - "isolate_profile_data": true, - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "views_perftests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/views:views_perftests/" - } - ] - }, "android-backuprefptr-arm-fyi-rel": { "gtest_tests": [ { @@ -22434,6 +20097,25 @@ ], "gtest_tests": [ { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", "--", @@ -25091,6 +22773,24 @@ ], "gtest_tests": [ { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", "--", @@ -25521,6 +23221,473 @@ } ] }, + "fuchsia-fyi-x64-wst": { + "gtest_tests": [ + { + "args": [ + "--custom-image=workstation.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", + "--", + "--disable-gpu", + "--headless", + "--ozone-platform=headless", + "--custom-image=workstation.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 6 + }, + "test": "content_browsertests", + "test_id_prefix": "ninja://content/test:content_browsertests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter", + "--custom-image=workstation.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "unit_tests", + "test_id_prefix": "ninja://chrome/test:unit_tests/" + } + ], + "isolated_scripts": [ + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_validating_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "depth_capture", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "depth_capture_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--expected-vendor-id", + "0", + "--expected-device-id", + "0", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "info_collection_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release", + "--git-revision=${got_revision}" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "mediapipe", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "mediapipe_validating_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release", + "--git-revision=${got_revision}" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "trace_test", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "trace_test", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation.qemu-x64-release" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 18 + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/" + } + ] + }, "ios-asan": { "isolated_scripts": [ {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index a8250d9..d7fbdfee 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -4664,7 +4664,7 @@ "--browser=android-chromium", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer --use-gl=egl --enable-gpu-rasterization --enable-oop-rasterization --disable-software-compositing-fallback --disable-headless-mode --force-online-connection-state-for-indicator", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer --use-gl=egl --enable-gpu-rasterization --disable-software-compositing-fallback --disable-headless-mode --force-online-connection-state-for-indicator", "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", @@ -6421,18 +6421,17 @@ "--browser=cros-chrome", "--passthrough", "-v", - "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", + "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu", "--webgl-conformance-version=2.0.1", "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json", "--remote=variable_chromeos_device_hostname" ], - "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "webgl2_conformance_validating_tests", + "name": "webgl2_conformance_gles_passthrough_tests", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -6502,6 +6501,8 @@ } ] }, + "GPU FYI Android arm Builder": {}, + "GPU FYI Android arm64 Builder": {}, "GPU FYI Fuchsia Builder": { "additional_compile_targets": [ "angle_end2end_tests", @@ -11029,7 +11030,7 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --enable-oop-rasterization --use-vulkan=native", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --use-vulkan=native", "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", @@ -11073,7 +11074,7 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --enable-oop-rasterization --use-vulkan=native", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --use-vulkan=native", "--dont-restore-color-profile-after-test", "--test-filter=ScreenshotSync_GPURasterWithDivs" ], @@ -11115,7 +11116,6 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", "--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan", "--use-vulkan=native", - "--enable-oop-rasterization", "--enable-gpu-rasterization", "--disable-software-compositing-fallback", "--disable-vulkan-fallback-to-gl-for-testing", @@ -11563,7 +11563,6 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", "--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan", "--use-vulkan=native", - "--enable-oop-rasterization", "--enable-gpu-rasterization", "--disable-software-compositing-fallback", "--disable-vulkan-fallback-to-gl-for-testing",
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index eab1426..8ecfebf 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -9664,7 +9664,6 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", "--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan", "--use-vulkan=swiftshader", - "--enable-oop-rasterization", "--enable-gpu-rasterization", "--disable-software-compositing-fallback", "--disable-vulkan-fallback-to-gl-for-testing", @@ -12708,7 +12707,7 @@ "--num-retries=3", "--additional-expectations", "../../third_party/blink/web_tests/ASANExpectations", - "--time-out-ms", + "--timeout-ms", "48000", "--enable-sanitizer" ], @@ -12748,7 +12747,7 @@ "--num-retries=3", "--additional-expectations", "../../third_party/blink/web_tests/LeakExpectations", - "--time-out-ms", + "--timeout-ms", "48000", "--enable-leak-detection" ], @@ -12785,7 +12784,7 @@ "--num-retries=3", "--additional-expectations", "../../third_party/blink/web_tests/MSANExpectations", - "--time-out-ms", + "--timeout-ms", "66000", "--enable-sanitizer" ],
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 5277ffe8..aacaa6e3 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -8780,7 +8780,7 @@ "args": [ "--num-retries=3", "--debug", - "--time-out-ms", + "--timeout-ms", "60000" ], "experiment_percentage": 100,
diff --git a/testing/buildbot/filters/fuchsia.content_browsertests.filter b/testing/buildbot/filters/fuchsia.content_browsertests.filter index cd3ff7e..72ef74e 100644 --- a/testing/buildbot/filters/fuchsia.content_browsertests.filter +++ b/testing/buildbot/filters/fuchsia.content_browsertests.filter
@@ -102,3 +102,21 @@ # crbug.com/1280308: Tests are passing on a NUC but failing on the ARM64 bots. -MSE_ClearKey/EncryptedMediaTest.Playback_VideoOnly_WebM_VP9Profile2/0 -MSE_ClearKey/EncryptedMediaTest.Playback_VideoOnly_MP4_VP9Profile2/0 + +# crbug.com/1285060 +-All/AccessibilityHitTestingBrowserTest.CachingAsyncHitTest_WithPinchZoom/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingBrowserTest.CachingAsyncHitTest/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingBrowserTest.CachingAsyncHitTestMissesElement_WithPinchZoom/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingBrowserTest.CachingAsyncHitTestMissesElement/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingBrowserTest.HitTest_WithPinchZoom/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingBrowserTest.HitTest/ZoomFactor2_UseZoomForDSFOn +-All/AccessibilityHitTestingCrossProcessBrowserTest.HitTestingInCrossProcessIframeWithScrolling/ZoomFactor2_UseZoomForDSFOn +-All/MAYBE_SitePerProcessAccessibilityDeviceScaleFactorBrowserTest.CrossSiteIframeCoordinates/0 +-All/MAYBE_SitePerProcessAccessibilityDeviceScaleFactorBrowserTest.CrossSiteIframeCoordinates/1 + +# crbug.com/1285058 +-AccessibilityActionBrowserTest.ScrollIntoView + +# crbug.com/1285057 +-AttributionsBrowserTest* +-AttributionsPrerenderBrowserTest*
diff --git a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/net_unittests.filter b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/net_unittests.filter index 6dd19098..56b92e26 100644 --- a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/net_unittests.filter +++ b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/net_unittests.filter
@@ -1230,11 +1230,11 @@ -CookiePartitionKeyTest.FromWire/0 -CookiePartitionKeyTest.FromWire/1 -CookiePartitionKeyTest.Serialization/1 --CookiePartitionKeychainTest.ContainsAll --CookiePartitionKeychainTest.EmptySet --CookiePartitionKeychainTest.FromOptional --CookiePartitionKeychainTest.MultipleElements --CookiePartitionKeychainTest.SingletonSet +-CookiePartitionKeyCollectionTest.ContainsAll +-CookiePartitionKeyCollectionTest.EmptySet +-CookiePartitionKeyCollectionTest.FromOptional +-CookiePartitionKeyCollectionTest.MultipleElements +-CookiePartitionKeyCollectionTest.SingletonSet -CookieUtilComputeSameSiteContextTest.ForRequest/0 -CookieUtilComputeSameSiteContextTest.ForRequest/1 -CookieUtilComputeSameSiteContextTest.ForRequest/2
diff --git a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/services_unittests.filter b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/services_unittests.filter index cef2e11..c396fbee 100644 --- a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/services_unittests.filter +++ b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-combined-rel/services_unittests.filter
@@ -8,7 +8,7 @@ -CertVerifierMojomTraitsTest.ConfigBasic -CertVerifierMojomTraitsTest.ConfigCRLAndAdditionalCerts -CertVerifierMojomTraitsTest.ConfigTrue --CookieManagerTraitsTest.Roundtrips_CookiePartitionKeychain +-CookieManagerTraitsTest.Roundtrips_CookiePartitionKeyCollection -CorsMojomTraitsTest.CorsErrorStatusMojoRoundTrip -CorsTest.CheckAccessAndReportMetricsForNotPermittedSecureOrigin -CorsTest.CheckAccessAndReportMetricsForPermittedNotSecureOrigin
diff --git a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/net_unittests.filter b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/net_unittests.filter index 6dd19098..56b92e26 100644 --- a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/net_unittests.filter +++ b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/net_unittests.filter
@@ -1230,11 +1230,11 @@ -CookiePartitionKeyTest.FromWire/0 -CookiePartitionKeyTest.FromWire/1 -CookiePartitionKeyTest.Serialization/1 --CookiePartitionKeychainTest.ContainsAll --CookiePartitionKeychainTest.EmptySet --CookiePartitionKeychainTest.FromOptional --CookiePartitionKeychainTest.MultipleElements --CookiePartitionKeychainTest.SingletonSet +-CookiePartitionKeyCollectionTest.ContainsAll +-CookiePartitionKeyCollectionTest.EmptySet +-CookiePartitionKeyCollectionTest.FromOptional +-CookiePartitionKeyCollectionTest.MultipleElements +-CookiePartitionKeyCollectionTest.SingletonSet -CookieUtilComputeSameSiteContextTest.ForRequest/0 -CookieUtilComputeSameSiteContextTest.ForRequest/1 -CookieUtilComputeSameSiteContextTest.ForRequest/2
diff --git a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/services_unittests.filter b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/services_unittests.filter index cef2e11..c396fbee 100644 --- a/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/services_unittests.filter +++ b/testing/buildbot/filters/stable_test_filters/linux-stable-filter-rel/services_unittests.filter
@@ -8,7 +8,7 @@ -CertVerifierMojomTraitsTest.ConfigBasic -CertVerifierMojomTraitsTest.ConfigCRLAndAdditionalCerts -CertVerifierMojomTraitsTest.ConfigTrue --CookieManagerTraitsTest.Roundtrips_CookiePartitionKeychain +-CookieManagerTraitsTest.Roundtrips_CookiePartitionKeyCollection -CorsMojomTraitsTest.CorsErrorStatusMojoRoundTrip -CorsTest.CheckAccessAndReportMetricsForNotPermittedSecureOrigin -CorsTest.CheckAccessAndReportMetricsForPermittedNotSecureOrigin
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 7642edb2..72701d1 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -547,7 +547,7 @@ elif isinstance(a[key], list) and isinstance(b[key], list): # Args arrays are lists of strings. Just concatenate them, # and don't sort them, in order to keep some needed - # arguments adjacent (like --time-out-ms [arg], etc.) + # arguments adjacent (like --timeout-ms [arg], etc.) if all(isinstance(x, str) for x in itertools.chain(a[key], b[key])): a[key] = self.maybe_fixup_args_array(a[key] + b[key])
diff --git a/testing/buildbot/infra.json b/testing/buildbot/infra.json deleted file mode 100644 index a5e4ab0..0000000 --- a/testing/buildbot/infra.json +++ /dev/null
@@ -1,46 +0,0 @@ -{ - "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, - "AAAAA2 See generate_buildbot_json.py to make changes": {}, - "linux-bootstrap-tests": { - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - } - ] - }, - "win-bootstrap-tests": { - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Windows-10-19042" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - } - ] - } -}
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index 08a6f9e..bd09c44 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1129,7 +1129,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R96-14268.67.0", + "cros_img": "octopus-release/R97-14324.62.0", "name": "lacros_fyi_tast_tests_OCTOPUS_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1170,7 +1170,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R96-14268.67.0", + "cros_img": "octopus-release/R97-14324.62.0", "name": "ozone_unittests_OCTOPUS_STABLE", "swarming": {}, "test": "ozone_unittests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index ebc61fc..631efff 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -317,7 +317,7 @@ 'args': [ '--additional-expectations', '../../third_party/blink/web_tests/ASANExpectations', - '--time-out-ms', + '--timeout-ms', '48000', '--enable-sanitizer', ], @@ -329,7 +329,7 @@ 'args': [ '--additional-expectations', '../../third_party/blink/web_tests/LeakExpectations', - '--time-out-ms', + '--timeout-ms', '48000', '--enable-leak-detection', ], @@ -341,7 +341,7 @@ 'args': [ '--additional-expectations', '../../third_party/blink/web_tests/MSANExpectations', - '--time-out-ms', + '--timeout-ms', '66000', '--enable-sanitizer', ], @@ -376,19 +376,10 @@ 'Debug_x64', ], }, - 'Win10 Tests x64 20h2': { - 'args': [ - '--target', - 'Release_x64', - ], - 'swarming': { - "shards": 28 - }, - }, 'Win7 Tests (dbg)(1)': { 'args': [ '--debug', - '--time-out-ms', + '--timeout-ms', '60000' ], 'experiment_percentage': 100, @@ -682,17 +673,6 @@ 'quickrun_shards': 30, } }, - 'Win10 Tests x64 20h2': { - # crbug.com/868082 - 'args': [ - '--disable-features=WebRTC-H264WithOpenH264FFmpeg', - ], - 'swarming': { - # This is for slow test execution that often becomes a critical path of - # swarming jobs. crbug.com/868114 - 'shards': 15, - } - }, 'Win7 Tests (1)': { # This is for slow test execution that often becomes a critical path of # swarming jobs. crbug.com/868114 @@ -1110,10 +1090,6 @@ ], }, 'components_browsertests': { - 'remove_from': [ - 'fuchsia-fyi-arm64-rel', # https://crbug.com/961457 - 'fuchsia-fyi-x64-rel', # https://crbug.com/961457 - ], 'modifications': { 'android-11-x86-rel': { 'swarming': { @@ -1261,12 +1237,6 @@ '--disable-features=WebRTC-H264WithOpenH264FFmpeg', ], }, - 'Win10 Tests x64 20h2': { - # crbug.com/868082 - 'args': [ - '--disable-features=WebRTC-H264WithOpenH264FFmpeg', - ], - }, 'android-11-x86-rel': { # TODO(crbug.com/1137474): Remove after the test suite is green. 'experiment_percentage': 100, @@ -2397,8 +2367,6 @@ 'ToTWin64', 'ToTWin64(dbg)', 'ToTWin64(dll)', - 'ToTWinCFI', - 'ToTWinCFI64', ], }, 'overlay_prioritization_viz_unittests': { @@ -2995,7 +2963,6 @@ 'Linux - Future (dbg)', # client.v8.chromium 'Win10 Tests x64', 'Win10 Tests x64 (dbg)', - 'Win10 Tests x64 20h2', ], }, 'telemetry_unittests': { @@ -3013,7 +2980,6 @@ 'Mac10.11 Tests', 'Win10 Tests x64', - 'Win10 Tests x64 20h2', # TODO(https://crbug.com/1267161): Re-enable when platform is supported. 'mac11-arm64-rel-tests', @@ -3246,9 +3212,8 @@ }, 'webgl2_conformance_gles_passthrough_tests': { 'remove_from': [ - # Not enough CrOS hardware capacity to run on anything other than VMs. - # See https://crbug.com/1238070. - 'ChromeOS FYI Release (kevin)', + # Not enough CrOS hardware capacity to run both on anything other than + # VMs. See https://crbug.com/1238070. 'Lacros FYI x64 Release (Intel)', ], 'modifications': { @@ -3286,6 +3251,9 @@ }, 'webgl2_conformance_validating_tests': { 'remove_from': [ + # Passthrough version run on this configuration, not enough capacity for + # both. See https://crbug.com/1238070. + 'ChromeOS FYI Release (kevin)', # The Mac NVIDIA Retina bots don't have the capacity to run # this test suite on mac_optional_gpu_tests_rel. 'Optional Mac Retina Release (NVIDIA)', @@ -3350,7 +3318,7 @@ # Increase the timeout with ASAN (crbug.com/1208253) 'Dawn Win10 x64 ASAN Release': { 'args': [ - '--time-out-ms=48000', + '--timeout-ms=48000', ], }, }, @@ -3510,6 +3478,9 @@ }, }, 'webview_64_cts_tests': { + 'remove_from': [ + 'android-12-x64-fyi-rel', # crbug.com/1260194 + ], 'modifications': { 'android-pie-arm64-rel': { # TODO(crbug.com/1111436): Move this back to walleye if/when additional
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 309a8e4..fb5f283 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -494,12 +494,6 @@ }, }, - # This is for testing the chromium bootstrapper, the actual tests aren't - # important, just that the tester will actually run some test - 'bootstrap_tests': { - 'base_unittests': {}, - }, - 'cast_audio_specific_chromium_gtests': { 'cast_audio_backend_unittests': {}, 'cast_base_unittests': {}, @@ -2816,7 +2810,6 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter', '--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan', '--use-vulkan=native', - '--enable-oop-rasterization', '--enable-gpu-rasterization', '--disable-software-compositing-fallback', '--disable-vulkan-fallback-to-gl-for-testing', @@ -2847,7 +2840,6 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter', '--enable-features=UseSkiaRenderer,UiGpuRasterization,Vulkan', '--use-vulkan=swiftshader', - '--enable-oop-rasterization', '--enable-gpu-rasterization', '--disable-software-compositing-fallback', '--disable-vulkan-fallback-to-gl-for-testing', @@ -3245,7 +3237,7 @@ '--extra-browser-args=--enable-features=UseSkiaRenderer,SkiaDawn', ], 'linux_args': [ - '--extra-browser-args=--enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --enable-oop-rasterization --use-vulkan=native', + '--extra-browser-args=--enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --use-vulkan=native', ], 'mixins': [ 'chrome-gpu-gold-service-account', @@ -3269,7 +3261,7 @@ '--test-filter=ScreenshotSync_GPURasterWithDivs::ScreenshotSync_SWRasterWithDivs', ], 'linux_args': [ - '--extra-browser-args=--enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --enable-oop-rasterization --use-vulkan=native', + '--extra-browser-args=--enable-features=UseSkiaRenderer,UiGpuRasterization,SkiaDawn --enable-gpu-rasterization --use-vulkan=native', '--test-filter=ScreenshotSync_GPURasterWithDivs', ], 'mixins': [ @@ -3285,7 +3277,7 @@ '--dont-restore-color-profile-after-test', '--test-machine-name', '${buildername}', - '--extra-browser-args=--enable-features=UseSkiaRenderer --use-gl=egl --enable-gpu-rasterization --enable-oop-rasterization --disable-software-compositing-fallback --disable-headless-mode', + '--extra-browser-args=--enable-features=UseSkiaRenderer --use-gl=egl --enable-gpu-rasterization --disable-software-compositing-fallback --disable-headless-mode', ], 'android_args': [ # TODO(crbug.com/1093085): Remove this once we fix the tests. @@ -4040,7 +4032,7 @@ '--initialize-webgpu-adapter-at-startup-timeout-ms=60000', '--flag-specific=webgpu-with-backend-validation', # Increase the timeout when using backend validation layers (crbug.com/1208253) - '--time-out-ms=30000', + '--timeout-ms=30000', ], 'win64_args': [ '--target=Release_x64' ], 'mac_args': [ @@ -4108,7 +4100,7 @@ '--initialize-webgpu-adapter-at-startup-timeout-ms=60000', '--flag-specific=webgpu-with-partial-backend-validation', # Increase the timeout when using backend validation layers (crbug.com/1208253) - '--time-out-ms=30000', + '--timeout-ms=30000', ], 'win64_args': [ '--target=Release_x64' ], 'mac_args': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 9d597a6..f945df280 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -581,8 +581,8 @@ 'CROS_ATLAS_BETA': { 'skylab': { 'cros_board': 'atlas', - 'cros_chrome_version': '97.0.4692.63', - 'cros_img': 'atlas-release/R97-14324.49.0', + 'cros_chrome_version': '97.0.4692.70', + 'cros_img': 'atlas-release/R97-14324.56.0', }, 'enabled': True, 'identifier': 'ATLAS_BETA', @@ -590,8 +590,8 @@ 'CROS_ATLAS_STABLE': { 'skylab': { 'cros_board': 'atlas', - 'cros_chrome_version': '96.0.4664.111', - 'cros_img': 'atlas-release/R96-14268.67.0', + 'cros_chrome_version': '97.0.4692.77', + 'cros_img': 'atlas-release/R97-14324.62.0', }, 'enabled': True, 'identifier': 'ATLAS_STABLE', @@ -617,8 +617,8 @@ 'CROS_EVE_BETA': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '97.0.4692.63', - 'cros_img': 'eve-release/R97-14324.49.0', + 'cros_chrome_version': '97.0.4692.70', + 'cros_img': 'eve-release/R97-14324.56.0', }, 'enabled': True, 'identifier': 'EVE_BETA', @@ -671,8 +671,8 @@ 'CROS_OCTOPUS_STABLE': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '96.0.4664.111', - 'cros_img': 'octopus-release/R96-14268.67.0', + 'cros_chrome_version': '97.0.4692.77', + 'cros_img': 'octopus-release/R97-14324.62.0', }, 'enabled': True, 'identifier': 'OCTOPUS_STABLE',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 0a3216dd..d7a91ae 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1997,24 +1997,6 @@ 'all', ], }, - 'ToTWinCFI': { - 'test_suites': { - 'gtest_tests': 'chromium_win_gtests', - 'isolated_scripts': 'win_specific_isolated_scripts', - }, - 'additional_compile_targets': [ - 'all', - ], - }, - 'ToTWinCFI64': { - 'test_suites': { - 'gtest_tests': 'chromium_win_gtests', - 'isolated_scripts': 'win_specific_isolated_scripts', - }, - 'additional_compile_targets': [ - 'all', - ], - }, 'ToTWinOfficial': { 'mixins': [ 'chrome-tester-service-account', @@ -2696,17 +2678,6 @@ 'scripts': 'chromium_win_scripts', }, }, - 'Win10 Tests x64 20h2': { - 'mixins': [ - 'x86-64', - 'win10', - 'isolate_profile_data', - ], - 'test_suites': { - 'gtest_tests': 'chromium_win10_gtests', - 'isolated_scripts': 'chromium_win_rel_isolated_scripts', - }, - }, 'android-backuprefptr-arm-fyi-rel': { 'test_suites': { 'gtest_tests': 'backuprefptr_gtests', @@ -2919,6 +2890,27 @@ 'gtest_tests': 'fuchsia_experimental_gtests', }, }, + 'fuchsia-fyi-x64-wst': { + 'browser_config': 'web-engine-shell', + 'os_type': 'linux', + 'mixins': [ + 'linux-bionic', + ], + 'args': [ + '--custom-image=workstation.qemu-x64-release', + ], + 'swarming': { + 'dimension_sets': [ + { + 'kvm': '1', + }, + ], + }, + 'test_suites': { + 'gpu_telemetry_tests': 'fuchsia_gpu_telemetry_tests', + 'gtest_tests': 'fuchsia_experimental_gtests', + }, + }, 'ios-asan': { 'mixins': [ 'has_native_resultdb_integration', @@ -4140,6 +4132,8 @@ 'gpu_telemetry_tests': 'gpu_fyi_chromeos_release_telemetry_tests', }, }, + 'GPU FYI Android arm Builder': {}, + 'GPU FYI Android arm64 Builder': {}, 'GPU FYI Fuchsia Builder' : { 'additional_compile_targets': [ 'angle_end2end_tests', @@ -6394,24 +6388,6 @@ }, }, { - 'name': 'infra', - 'mixins': ['chromium-tester-service-account'], - 'machines': { - 'linux-bootstrap-tests': { - 'mixins': ['linux-bionic'], - 'test_suites': { - 'gtest_tests': 'bootstrap_tests', - } - }, - 'win-bootstrap-tests': { - 'mixins': ['win10'], - 'test_suites': { - 'gtest_tests': 'bootstrap_tests', - } - }, - } - }, - { 'project': 'chrome', 'bucket': 'ci', 'name': 'internal.chromeos.fyi',
diff --git a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc index 46814c5..55e94d1 100644 --- a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc +++ b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
@@ -1303,7 +1303,7 @@ break; case ValidVerb::kConic_Verb: num_conics += 1; - FALLTHROUGH; + [[fallthrough]]; case ValidVerb::kQuad_Verb: num_points += 2; break;
diff --git a/testing/merge_scripts/PRESUBMIT.py b/testing/merge_scripts/PRESUBMIT.py index 3c01237..0c000cb9 100644 --- a/testing/merge_scripts/PRESUBMIT.py +++ b/testing/merge_scripts/PRESUBMIT.py
@@ -12,7 +12,9 @@ def CommonChecks(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, output_api, '.', [ r'^.+_test\.py$']) + input_api, output_api, '.', [ r'^.+_test\.py$'], + run_on_python2 = not USE_PYTHON3, + skip_shebang_check = True) def CheckChangeOnUpload(input_api, output_api): return CommonChecks(input_api, output_api)
diff --git a/testing/merge_scripts/code_coverage/merge_js_lib.py b/testing/merge_scripts/code_coverage/merge_js_lib.py index 92c32614..19fbd6bb 100644 --- a/testing/merge_scripts/code_coverage/merge_js_lib.py +++ b/testing/merge_scripts/code_coverage/merge_js_lib.py
@@ -102,6 +102,7 @@ stack = [] segments = [] + # pylint: disable=unsupported-assignment-operation def _append(end, count): """Append a new range segment to |segments|. @@ -148,7 +149,9 @@ _append(top['endOffset'], top['count']) return segments + # pylint: enable=unsupported-assignment-operation +# pylint: disable=unsupported-assignment-operation def _merge_segments(segments_a, segments_b): """Merges 2 lists of disjoint segments into one @@ -200,6 +203,7 @@ j += 1 return segments +# pylint: enable=unsupported-assignment-operation def _get_paths_with_suffix(input_dir, suffix): @@ -233,14 +237,14 @@ if not json_files: logging.info('No JavaScript coverage files found in %s', coverage_dir) - return + return None for file_path in json_files: coverage_data = _parse_json_file(file_path) if 'result' not in coverage_data: raise RuntimeError('%r does not have a result field' % - json_file_path) + file_path) for script_coverage in coverage_data['result']: script_url = script_coverage['url']
diff --git a/testing/merge_scripts/code_coverage/merge_lib_test.py b/testing/merge_scripts/code_coverage/merge_lib_test.py index 97c1fbef..b3f00554 100755 --- a/testing/merge_scripts/code_coverage/merge_lib_test.py +++ b/testing/merge_scripts/code_coverage/merge_lib_test.py
@@ -16,7 +16,7 @@ class MergeLibTest(unittest.TestCase): def __init__(self, *args, **kwargs): - super(MergeLibTest, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.maxDiff = None @mock.patch.object(subprocess, 'check_output')
diff --git a/testing/merge_scripts/code_coverage/merge_results.py b/testing/merge_scripts/code_coverage/merge_results.py index b921e7f..2788b25 100755 --- a/testing/merge_scripts/code_coverage/merge_results.py +++ b/testing/merge_scripts/code_coverage/merge_results.py
@@ -124,7 +124,7 @@ javascript_merger.merge_istanbul_reports( istanbul_coverage_dir, parsed_scripts, coverage_file_path) except RuntimeError as e: - logging.warn('Failed executing istanbul tasks: %s', e.message) + logging.warn('Failed executing istanbul tasks: %s', e) # Ensure JavaScript coverage dir exists. if not os.path.exists(params.javascript_coverage_dir):
diff --git a/testing/merge_scripts/code_coverage/merge_results_test.py b/testing/merge_scripts/code_coverage/merge_results_test.py index cb08ff6..4f3d5ec 100755 --- a/testing/merge_scripts/code_coverage/merge_results_test.py +++ b/testing/merge_scripts/code_coverage/merge_results_test.py
@@ -20,7 +20,7 @@ class MergeProfilesTest(unittest.TestCase): def __init__(self, *args, **kwargs): - super(MergeProfilesTest, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.maxDiff = None def test_merge_script_api_parameters(self):
diff --git a/testing/merge_scripts/common_merge_script_tests.py b/testing/merge_scripts/common_merge_script_tests.py index fd56905..f925f880 100644 --- a/testing/merge_scripts/common_merge_script_tests.py +++ b/testing/merge_scripts/common_merge_script_tests.py
@@ -12,7 +12,7 @@ class CommandLineTest(unittest.TestCase): def __init__(self, methodName, module): - super(CommandLineTest, self).__init__(methodName) + super().__init__(methodName) self._module = module def setUp(self): @@ -48,4 +48,4 @@ '--output-json', output_json, shard0_json, ] - self.assertEquals(0, self._module.main(raw_args)) + self.assertEqual(0, self._module.main(raw_args))
diff --git a/testing/merge_scripts/noop_merge.py b/testing/merge_scripts/noop_merge.py index f7a93cd..5dd8bef 100755 --- a/testing/merge_scripts/noop_merge.py +++ b/testing/merge_scripts/noop_merge.py
@@ -21,8 +21,8 @@ jsons_to_merge: A list of paths to JSON files. """ if len(jsons_to_merge) > 1: - print >> sys.stderr, ( - 'Multiple JSONs provided: %s' % ','.join(jsons_to_merge)) + print('Multiple JSONs provided: %s' % (','.join(jsons_to_merge)), + file=sys.stderr) return 1 if jsons_to_merge: shutil.copyfile(jsons_to_merge[0], output_json)
diff --git a/testing/merge_scripts/noop_merge_test.py b/testing/merge_scripts/noop_merge_test.py index 4cda1bf..335979c 100755 --- a/testing/merge_scripts/noop_merge_test.py +++ b/testing/merge_scripts/noop_merge_test.py
@@ -22,12 +22,12 @@ class NoopMergeTest(unittest.TestCase): def setUp(self): - super(NoopMergeTest, self).setUp() + super().setUp() self.temp_dir = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.temp_dir) - super(NoopMergeTest, self).tearDown() + super().tearDown() def test_copies_first_json(self): input_json = os.path.join(self.temp_dir, 'input.json') @@ -62,7 +62,7 @@ class CommandLineTest(common_merge_script_tests.CommandLineTest): def __init__(self, methodName='runTest'): - super(CommandLineTest, self).__init__(methodName, noop_merge) + super().__init__(methodName, noop_merge) if __name__ == '__main__':
diff --git a/testing/merge_scripts/results_merger.py b/testing/merge_scripts/results_merger.py index 3c05dfe..4bb9f636 100755 --- a/testing/merge_scripts/results_merger.py +++ b/testing/merge_scripts/results_merger.py
@@ -69,8 +69,8 @@ if 'seconds_since_epoch' in shard_results_list[0]: return _merge_json_test_result_format(shard_results_list) - else: - return _merge_simplified_json_format(shard_results_list) + + return _merge_simplified_json_format(shard_results_list) def _merge_simplified_json_format(shard_results_list): @@ -261,8 +261,8 @@ try: dest[key] = merge_func(source[key], dest[key]) except MergeException as e: - e.message = "MergeFailure for %s\n%s" % (key, e.message) - e.args = tuple([e.message] + list(e.args[1:])) + message = "MergeFailure for %s\n%s" % (key, e.args[0]) + e.args = (message,) + e.args[1:] raise del source[key]
diff --git a/testing/merge_scripts/results_merger_test.py b/testing/merge_scripts/results_merger_test.py index e01f789..0c1770d 100755 --- a/testing/merge_scripts/results_merger_test.py +++ b/testing/merge_scripts/results_merger_test.py
@@ -162,13 +162,13 @@ maxDiff = None # Show full diff if assertion fail def test_merge_tries(self): - self.assertEquals( + self.assertEqual( {'a': 'A', 'b': {'c': 'C'}}, results_merger.merge_tries( {'a': 'A', 'b': {}}, {'b': {'c': 'C'}})) def test_merge_tries_unmergable(self): - with self.assertRaisesRegexp(results_merger.MergeException, "a:b"): + with self.assertRaisesRegex(results_merger.MergeException, "a:b"): results_merger.merge_tries( {'a': {'b': 'A'}}, {'a': {'b': 'C'}}) @@ -178,7 +178,7 @@ merged_results = results_merger.merge_test_results( [extend(GOOD_JSON_TEST_RESULT_0, metadata1), extend(GOOD_JSON_TEST_RESULT_1, metadata2)]) - self.assertEquals( + self.assertEqual( merged_results['metadata']['tags'], ['foo', 'bat']) def test_merge_json_test_results_nop(self): @@ -190,8 +190,8 @@ for j in good_json_results: # Clone so we can check the input dictionaries are not modified a = copy.deepcopy(j) - self.assertEquals(results_merger.merge_test_results([a]), j) - self.assertEquals(a, j) + self.assertEqual(results_merger.merge_test_results([a]), j) + self.assertEqual(a, j) def test_merge_json_test_results_invalid_version(self): with self.assertRaises(results_merger.MergeException): @@ -242,7 +242,7 @@ ]) def test_merge_json_test_results_multiple(self): - self.assertEquals( + self.assertEqual( results_merger.merge_test_results([ GOOD_JSON_TEST_RESULT_0, GOOD_JSON_TEST_RESULT_1, @@ -251,7 +251,7 @@ GOOD_JSON_TEST_RESULT_MERGED) def test_merge_json_test_results_optional_matches(self): - self.assertEquals( + self.assertEqual( results_merger.merge_test_results([ extend(GOOD_JSON_TEST_RESULT_0, {'path_delimiter': '.'}), extend(GOOD_JSON_TEST_RESULT_1, {'path_delimiter': '.'}), @@ -268,7 +268,7 @@ ]) def test_merge_json_test_results_optional_count(self): - self.assertEquals( + self.assertEqual( results_merger.merge_test_results([ extend(GOOD_JSON_TEST_RESULT_0, {'fixable': 1}), extend(GOOD_JSON_TEST_RESULT_1, {'fixable': 2}), @@ -277,7 +277,7 @@ extend(GOOD_JSON_TEST_RESULT_MERGED, {'fixable': 6})) def test_merge_nothing(self): - self.assertEquals( + self.assertEqual( results_merger.merge_test_results([]), {})
diff --git a/testing/merge_scripts/standard_gtest_merge.py b/testing/merge_scripts/standard_gtest_merge.py index 5a3729f..a93edde 100755 --- a/testing/merge_scripts/standard_gtest_merge.py +++ b/testing/merge_scripts/standard_gtest_merge.py
@@ -145,7 +145,7 @@ if not matching_json_files: print('shard %s test output missing' % index, file=sys.stderr) return (None, 'shard %s test output was missing' % index) - elif len(matching_json_files) > 1: + if len(matching_json_files) > 1: print('duplicate test output for shard %s' % index, file=sys.stderr) return (None, 'shard %s test output was duplicated' % index) @@ -183,7 +183,7 @@ output_json, summary_json, jsons_to_merge): output = merge_shard_results(summary_json, jsons_to_merge) - with open(output_json, 'wb') as f: + with open(output_json, 'w') as f: json.dump(output, f) return 0
diff --git a/testing/merge_scripts/standard_gtest_merge_test.py b/testing/merge_scripts/standard_gtest_merge_test.py index 2de820c4..42d37f2 100755 --- a/testing/merge_scripts/standard_gtest_merge_test.py +++ b/testing/merge_scripts/standard_gtest_merge_test.py
@@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import cStringIO +import io import json import logging import os @@ -429,7 +429,7 @@ """Tests for merge_shard_results function.""" def setUp(self): - super(MergeShardResultsTest, self).setUp() + super().setUp() self.summary = None self.test_files = [] @@ -440,7 +440,7 @@ self.test_files.append(abs_path) def call(self): - stdout = cStringIO.StringIO() + stdout = io.StringIO() with mock.patch('sys.stdout', stdout): merged = standard_gtest_merge.merge_shard_results( self.summary, self.test_files) @@ -601,7 +601,7 @@ class CommandLineTest(common_merge_script_tests.CommandLineTest): def __init__(self, methodName='runTest'): - super(CommandLineTest, self).__init__(methodName, standard_gtest_merge) + super().__init__(methodName, standard_gtest_merge) if __name__ == '__main__':
diff --git a/testing/merge_scripts/standard_isolated_script_merge.py b/testing/merge_scripts/standard_isolated_script_merge.py index b4e49b9..a16896f 100755 --- a/testing/merge_scripts/standard_isolated_script_merge.py +++ b/testing/merge_scripts/standard_isolated_script_merge.py
@@ -47,8 +47,8 @@ with open(output_path) as f: try: json_contents = json.load(f) - except ValueError: - raise ValueError('Failed to parse JSON from %s' % j) + except ValueError as e: + raise ValueError('Failed to parse JSON from %s' % j) from e shard_results_list.append(json_contents) merged_results = results_merger.merge_test_results(shard_results_list) @@ -85,7 +85,7 @@ if not matching_json_files: print('shard %s test output missing' % index, file=sys.stderr) return None - elif len(matching_json_files) > 1: + if len(matching_json_files) > 1: print('duplicate test output for shard %s' % index, file=sys.stderr) return None
diff --git a/testing/merge_scripts/standard_isolated_script_merge_test.py b/testing/merge_scripts/standard_isolated_script_merge_test.py index 131199a..d46915c 100755 --- a/testing/merge_scripts/standard_isolated_script_merge_test.py +++ b/testing/merge_scripts/standard_isolated_script_merge_test.py
@@ -37,7 +37,7 @@ def tearDown(self): shutil.rmtree(self.temp_dir) - super(StandardIsolatedScriptMergeTest, self).tearDown() + super().tearDown() def _write_temp_file(self, path, content): abs_path = os.path.join(self.temp_dir, path.replace('/', os.sep)) @@ -104,7 +104,7 @@ class InputParsingTest(StandardIsolatedScriptMergeTest): def setUp(self): - super(InputParsingTest, self).setUp() + super().setUp() self.merge_test_results_args = [] def mock_merge_test_results(results_list): @@ -174,7 +174,7 @@ class CommandLineTest(common_merge_script_tests.CommandLineTest): def __init__(self, methodName='runTest'): - super(CommandLineTest, self).__init__( + super().__init__( methodName, standard_isolated_script_merge)
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c51b516c2..16f5e83 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1812,7 +1812,8 @@ { "platforms": [ "android", - "windows" + "windows", + "mac" ], "experiments": [ { @@ -2174,6 +2175,7 @@ { "name": "CandidateB", "params": { + "MaxSigninPromoImpressions": "5", "hide_switch_when_no_incognito_tabs": "true", "open_ntp_instead_of_start": "true", "show_last_active_tab_only": "true", @@ -2185,6 +2187,7 @@ "tab_switcher_on_return_time_ms": "3600000" }, "enable_features": [ + "EnhancedProtectionPromoCard", "StartSurfaceAndroid", "TabSwitcherOnReturn" ] @@ -2898,9 +2901,8 @@ ], "experiments": [ { - "name": "Enabled_with_OOPR_Canvas", + "name": "Enabled_20220104", "enable_features": [ - "CanvasOopRasterization", "DefaultPassthroughCommandDecoder" ] } @@ -3699,10 +3701,11 @@ ] } ], - "FilesSystemWebApp": [ + "FilesSWA": [ { "platforms": [ - "chromeos" + "chromeos", + "chromeos_lacros" ], "experiments": [ { @@ -4850,6 +4853,21 @@ ] } ], + "LongMessageDurationIOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enable_14s_20220104", + "enable_features": [ + "EnableLongMessageDuration" + ] + } + ] + } + ], "MacCAOverlayQuads": [ { "platforms": [ @@ -5695,6 +5713,27 @@ ] } ], + "OptimizeUpdateLoadInfo": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OptimizeUpdateLoadInfo" + ] + } + ] + } + ], "OptimizedRealtimeThreadingMac": [ { "platforms": [ @@ -6563,6 +6602,18 @@ ] }, { + "name": "EnabledContextMenuWithRootAsDefault_20211206", + "params": { + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "ReadLater" + ], + "disable_features": [ + "BookmarkBottomSheet" + ] + }, + { "name": "EnabledDedicatedSaveFlow", "params": { "autodismiss_enabled": "true", @@ -6673,19 +6724,12 @@ ], "experiments": [ { - "name": "Enabled_IPH", - "enable_features": [ - "IPH_ReadingListMessages", - "ReadingListMessages" - ] - }, - { - "name": "Enabled_NO_IPH", + "name": "Enabled", + "params": { + "javascript_only": "true" + }, "enable_features": [ "ReadingListMessages" - ], - "disable_features": [ - "IPH_ReadingListMessages" ] } ] @@ -8054,21 +8098,6 @@ ] } ], - "UseFluentLanguageModel": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "UseFluentLanguageModel" - ] - } - ] - } - ], "UseSkiaRenderer": [ { "platforms": [ @@ -8547,21 +8576,6 @@ ] } ], - "WebApkInstallCompleteNotification": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "WebApkInstallCompleteNotification" - ] - } - ] - } - ], "WebFeedsMVP": [ { "platforms": [
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index c9db3784b..8eaa1612 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: 04610889a913d29037205ca72e9d7fd7acc925fe +Revision: c498947f8cf6dd4eb7bf4d589ca0f3816fd77d36 Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.bazel b/third_party/abseil-cpp/absl/flags/BUILD.bazel index d20deab4..020b791 100644 --- a/third_party/abseil-cpp/absl/flags/BUILD.bazel +++ b/third_party/abseil-cpp/absl/flags/BUILD.bazel
@@ -204,6 +204,7 @@ "//absl/base", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:dynamic_annotations", "//absl/memory", "//absl/meta:type_traits", "//absl/strings",
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.gn b/third_party/abseil-cpp/absl/flags/BUILD.gn index 287e2bad..7cf60e87 100644 --- a/third_party/abseil-cpp/absl/flags/BUILD.gn +++ b/third_party/abseil-cpp/absl/flags/BUILD.gn
@@ -129,6 +129,7 @@ "//third_party/abseil-cpp/absl/base", "//third_party/abseil-cpp/absl/base:config", "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/base:dynamic_annotations", "//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/meta:type_traits", "//third_party/abseil-cpp/absl/strings",
diff --git a/third_party/abseil-cpp/absl/flags/CMakeLists.txt b/third_party/abseil-cpp/absl/flags/CMakeLists.txt index 7f3298e..29c85ad 100644 --- a/third_party/abseil-cpp/absl/flags/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/flags/CMakeLists.txt
@@ -105,6 +105,7 @@ ${ABSL_DEFAULT_LINKOPTS} DEPS absl::config + absl::dynamic_annotations absl::fast_type_id )
diff --git a/third_party/abseil-cpp/absl/flags/internal/flag.cc b/third_party/abseil-cpp/absl/flags/internal/flag.cc index 7102559..55892d7 100644 --- a/third_party/abseil-cpp/absl/flags/internal/flag.cc +++ b/third_party/abseil-cpp/absl/flags/internal/flag.cc
@@ -30,6 +30,7 @@ #include "absl/base/call_once.h" #include "absl/base/casts.h" #include "absl/base/config.h" +#include "absl/base/dynamic_annotations.h" #include "absl/base/optimization.h" #include "absl/flags/config.h" #include "absl/flags/internal/commandlineflag.h" @@ -160,6 +161,8 @@ std::memcpy(buf.data() + Sizeof(op_), &initialized, sizeof(initialized)); } + // Type can contain valid uninitialized bits, e.g. padding. + ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(buf.data(), buf.size()); OneWordValue().store(absl::bit_cast<int64_t>(buf), std::memory_order_release); break;
diff --git a/third_party/abseil-cpp/absl/random/bernoulli_distribution.h b/third_party/abseil-cpp/absl/random/bernoulli_distribution.h index 25bd0d5..d81b6ae 100644 --- a/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +++ b/third_party/abseil-cpp/absl/random/bernoulli_distribution.h
@@ -138,16 +138,16 @@ // 64 bits. // // Second, `c` is constructed by first casting explicitly to a signed - // integer and then converting implicitly to an unsigned integer of the same + // integer and then casting explicitly to an unsigned integer of the same // size. This is done because the hardware conversion instructions produce // signed integers from double; if taken as a uint64_t the conversion would // be wrong for doubles greater than 2^63 (not relevant in this use-case). // If converted directly to an unsigned integer, the compiler would end up // emitting code to handle such large values that are not relevant due to // the known bounds on `c`. To avoid these extra instructions this - // implementation converts first to the signed type and then use the - // implicit conversion to unsigned (which is a no-op). - const uint64_t c = static_cast<int64_t>(p * kP32); + // implementation converts first to the signed type and then convert to + // unsigned (which is a no-op). + const uint64_t c = static_cast<uint64_t>(static_cast<int64_t>(p * kP32)); const uint32_t v = fast_u32(g); // FAST PATH: this path fails with probability 1/2^32. Note that simply // returning v <= c would approximate P very well (up to an absolute error
diff --git a/third_party/blink/public/common/frame/sandbox_flags.h b/third_party/blink/public/common/frame/sandbox_flags.h deleted file mode 100644 index cdff078..0000000 --- a/third_party/blink/public/common/frame/sandbox_flags.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_SANDBOX_FLAGS_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_SANDBOX_FLAGS_H_ - -#include <bitset> -#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom-shared.h" - -namespace blink { -namespace mojom { - -inline constexpr WebSandboxFlags operator&(WebSandboxFlags a, - WebSandboxFlags b) { - return static_cast<WebSandboxFlags>(static_cast<int>(a) & - static_cast<int>(b)); -} - -inline constexpr WebSandboxFlags operator|(WebSandboxFlags a, - WebSandboxFlags b) { - return static_cast<WebSandboxFlags>(static_cast<int>(a) | - static_cast<int>(b)); -} - -inline WebSandboxFlags& operator|=(WebSandboxFlags& a, WebSandboxFlags b) { - return a = a | b; -} - -inline constexpr WebSandboxFlags operator~(WebSandboxFlags flags) { - return static_cast<WebSandboxFlags>(~static_cast<int>(flags)); -} - -} // namespace mojom -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_SANDBOX_FLAGS_H_
diff --git a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom index 73ca247..e76fce09 100644 --- a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom +++ b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom
@@ -60,6 +60,26 @@ AllBuyers all_buyers; }; +// Subset of AuctionAdConfig that can be handled by the same loaded +// SellerWorklet when the other parameters (seller, script and signals URLs, +// and top window origin) are all exactly the same. +struct ShareableAuctionAdConfig { + // Owners of interest groups allowed to participate in the auction. + blink.mojom.InterestGroupBuyers? interest_group_buyers; + + // Opaque JSON data, passed as object to auction worklet. + string? auction_signals; + + // Opaque JSON data, passed as object to auction worklet. + string? seller_signals; + + // Keys of `per_buyer_signals` must be a subset of origins specified by + // `interest_group_buyers`. Value is opaque JSON data, passed as object to + // auction worklet. + map<url.mojom.Origin, string>? + per_buyer_signals; +}; + // Configuration to pass to RunAdAuction(). // // All URLs and origins must use https. @@ -79,21 +99,10 @@ // `decision_logic_url`'s origin must match the the seller's origin. url.mojom.Url decision_logic_url; - // Base URL for per-bid data passed to the seller worklet. Must be same origin with `seller`. + // Base URL for per-bid data passed to the seller worklet. Must be same + // origin with `seller`. url.mojom.Url? trusted_scoring_signals_url; - // Owners of interest groups allowed to participate in the auction. - InterestGroupBuyers? interest_group_buyers; - - // Opaque JSON data, passed as object to auction worklet. - string? auction_signals; - - // Opaque JSON data, passed as object to auction worklet. - string? seller_signals; - - // Keys of `per_buyer_signals` must be a subset of origins specified by - // `interest_group_buyers`. Value is opaque JSON data, passed as object to - // auction worklet. - map<url.mojom.Origin, string>? - per_buyer_signals; + // Other parameters are grouped in a struct that is passed to SellerWorklets. + ShareableAuctionAdConfig shareable_auction_ad_config; };
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 4faa57bb..2afe53cf 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3408,6 +3408,7 @@ kLayerXYWithCanvasTarget = 4099, kLayerXYWithFrameTarget = 4100, kLayerXYWithSVGTarget = 4101, + kHTMLObjectElementFallback = 4102, // Add new features immediately above this line. Don't change assigned
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni index 5a20cf8f..8e33b477 100644 --- a/third_party/blink/renderer/bindings/bindings.gni +++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -62,9 +62,10 @@ "core/v8/native_value_traits_buffer_sources.cc", "core/v8/native_value_traits_impl.cc", "core/v8/native_value_traits_impl.h", - "core/v8/observable_array.cc", "core/v8/observable_array.h", "core/v8/observable_array_exotic_object_handler.h", + "core/v8/observable_array_exotic_object_impl.cc", + "core/v8/observable_array_exotic_object_impl.h", "core/v8/profiler_trace_builder.cc", "core/v8/profiler_trace_builder.h", "core/v8/referrer_script_info.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/observable_array.h b/third_party/blink/renderer/bindings/core/v8/observable_array.h index 73ce179..4658098 100644 --- a/third_party/blink/renderer/bindings/core/v8/observable_array.h +++ b/third_party/blink/renderer/bindings/core/v8/observable_array.h
@@ -5,43 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_OBSERVABLE_ARRAY_H_ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_OBSERVABLE_ARRAY_H_ -#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.h" #include "third_party/blink/renderer/platform/bindings/observable_array_base.h" -#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" #include "third_party/blink/renderer/platform/heap/heap_traits.h" namespace blink { namespace bindings { -// The implementation class of ObservableArrayExoticObject. -class CORE_EXPORT ObservableArrayExoticObjectImpl final - : public ObservableArrayExoticObject { - DEFINE_WRAPPERTYPEINFO(); - - public: - // Returns the backing list object extracted from the proxy target object - // of type JS Array. - static bindings::ObservableArrayBase* ProxyTargetToObservableArrayBase( - v8::Isolate* isolate, - v8::Local<v8::Array> v8_proxy_target); - - explicit ObservableArrayExoticObjectImpl( - bindings::ObservableArrayBase* observable_array_backing_list_object); - ~ObservableArrayExoticObjectImpl() override = default; - - // ScriptWrappable overrides - v8::MaybeLocal<v8::Value> Wrap(ScriptState* script_state) override; - WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper( - v8::Isolate* isolate, - const WrapperTypeInfo* wrapper_type_info, - v8::Local<v8::Object> wrapper) override; - - private: - static const WrapperTypeInfo wrapper_type_info_body_; - static const V8PrivateProperty::SymbolKey kV8ProxyTargetToV8WrapperKey; -}; - template <typename ElementType> class ObservableArrayImplHelper : public bindings::ObservableArrayBase { public:
diff --git a/third_party/blink/renderer/bindings/core/v8/observable_array.cc b/third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.cc similarity index 94% rename from third_party/blink/renderer/bindings/core/v8/observable_array.cc rename to third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.cc index a0f505a..8672414 100644 --- a/third_party/blink/renderer/bindings/core/v8/observable_array.cc +++ b/third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/platform/bindings/dom_data_store.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" #include "v8/include/v8-container.h" #include "v8/include/v8-object.h" #include "v8/include/v8-proxy.h" @@ -16,8 +17,11 @@ namespace bindings { -// static -const WrapperTypeInfo ObservableArrayExoticObjectImpl::wrapper_type_info_body_{ +namespace { + +const V8PrivateProperty::SymbolKey kV8ProxyTargetToV8WrapperKey; + +const WrapperTypeInfo kWrapperTypeInfoBody{ gin::kEmbedderBlink, /*install_interface_template_func=*/nullptr, /*install_context_dependent_props_func=*/nullptr, @@ -30,13 +34,11 @@ WrapperTypeInfo::kIdlObservableArray, }; -// static -const WrapperTypeInfo& ObservableArrayExoticObjectImpl::wrapper_type_info_ = - ObservableArrayExoticObjectImpl::wrapper_type_info_body_; +} // namespace // static -const V8PrivateProperty::SymbolKey - ObservableArrayExoticObjectImpl::kV8ProxyTargetToV8WrapperKey; +const WrapperTypeInfo& ObservableArrayExoticObjectImpl::wrapper_type_info_ = + kWrapperTypeInfoBody; // static bindings::ObservableArrayBase*
diff --git a/third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.h b/third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.h new file mode 100644 index 0000000..163005e --- /dev/null +++ b/third_party/blink/renderer/bindings/core/v8/observable_array_exotic_object_impl.h
@@ -0,0 +1,45 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_OBSERVABLE_ARRAY_EXOTIC_OBJECT_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_OBSERVABLE_ARRAY_EXOTIC_OBJECT_IMPL_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/bindings/observable_array_base.h" + +namespace blink { + +namespace bindings { + +class ObservableArrayBase; + +// The implementation class of ObservableArrayExoticObject. +class CORE_EXPORT ObservableArrayExoticObjectImpl final + : public ObservableArrayExoticObject { + DEFINE_WRAPPERTYPEINFO(); + + public: + // Returns the backing list object extracted from the proxy target object + // of type JS Array. + static bindings::ObservableArrayBase* ProxyTargetToObservableArrayBase( + v8::Isolate* isolate, + v8::Local<v8::Array> v8_proxy_target); + + explicit ObservableArrayExoticObjectImpl( + bindings::ObservableArrayBase* observable_array_backing_list_object); + ~ObservableArrayExoticObjectImpl() override = default; + + // ScriptWrappable overrides + v8::MaybeLocal<v8::Value> Wrap(ScriptState* script_state) override; + WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper( + v8::Isolate* isolate, + const WrapperTypeInfo* wrapper_type_info, + v8::Local<v8::Object> wrapper) override; +}; + +} // namespace bindings + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_OBSERVABLE_ARRAY_EXOTIC_OBJECT_IMPL_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/third_party/blink/renderer/bindings/core/v8/script_promise.cc index a176bda..d9be9eb 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -72,38 +72,24 @@ } private: - class AdapterFunction : public ScriptFunction { + class AdapterFunction : public NewScriptFunction::Callable { public: enum ResolveType { kFulfilled, kRejected, }; - static v8::Local<v8::Function> Create(ScriptState* script_state, - ResolveType resolve_type, - wtf_size_t index, - PromiseAllHandler* handler) { - AdapterFunction* self = MakeGarbageCollected<AdapterFunction>( - script_state, resolve_type, index, handler); - return self->BindToV8Function(); - } - - AdapterFunction(ScriptState* script_state, - ResolveType resolve_type, + AdapterFunction(ResolveType resolve_type, wtf_size_t index, PromiseAllHandler* handler) - : ScriptFunction(script_state), - resolve_type_(resolve_type), - index_(index), - handler_(handler) {} + : resolve_type_(resolve_type), index_(index), handler_(handler) {} void Trace(Visitor* visitor) const override { visitor->Trace(handler_); - ScriptFunction::Trace(visitor); + NewScriptFunction::Callable::Trace(visitor); } - private: - ScriptValue Call(ScriptValue value) override { + ScriptValue Call(ScriptState*, ScriptValue value) override { if (resolve_type_ == kFulfilled) handler_->OnFulfilled(index_, value); else @@ -112,6 +98,7 @@ return ScriptValue(); } + private: const ResolveType resolve_type_; const wtf_size_t index_; Member<PromiseAllHandler> handler_; @@ -119,13 +106,17 @@ v8::Local<v8::Function> CreateFulfillFunction(ScriptState* script_state, wtf_size_t index) { - return AdapterFunction::Create(script_state, AdapterFunction::kFulfilled, - index, this); + return MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<AdapterFunction>( + AdapterFunction::kFulfilled, index, this)) + ->V8Function(); } v8::Local<v8::Function> CreateRejectFunction(ScriptState* script_state) { - return AdapterFunction::Create(script_state, AdapterFunction::kRejected, 0, - this); + return MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<AdapterFunction>( + AdapterFunction::kRejected, 0, this)) + ->V8Function(); } void OnFulfilled(wtf_size_t index, const ScriptValue& value) {
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc index 4695d03..ec4105b 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
@@ -30,47 +30,30 @@ namespace { -class NotReached : public ScriptFunction { +class NotReachedFunction : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - NotReached* self = MakeGarbageCollected<NotReached>(script_state); - return self->BindToV8Function(); - } + NotReachedFunction() = default; - explicit NotReached(ScriptState* script_state) - : ScriptFunction(script_state) {} - - private: - ScriptValue Call(ScriptValue) override; + ScriptValue Call(ScriptState*, ScriptValue) override; }; -ScriptValue NotReached::Call(ScriptValue) { +ScriptValue NotReachedFunction::Call(ScriptState*, ScriptValue) { EXPECT_TRUE(false) << "'Unreachable' code was reached"; return ScriptValue(); } -class StubFunction : public ScriptFunction { +class StubFunction : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, - ScriptValue& value, - size_t& call_count) { - StubFunction* self = - MakeGarbageCollected<StubFunction>(script_state, value, call_count); - return self->BindToV8Function(); - } + StubFunction(ScriptValue& value, size_t& call_count) + : value_(value), call_count_(call_count) {} - StubFunction(ScriptState* script_state, - ScriptValue& value, - size_t& call_count) - : ScriptFunction(script_state), value_(value), call_count_(call_count) {} - - private: - ScriptValue Call(ScriptValue arg) override { + ScriptValue Call(ScriptState*, ScriptValue arg) override { value_ = arg; call_count_++; return ScriptValue(); } + private: ScriptValue& value_; size_t& call_count_; }; @@ -98,32 +81,26 @@ Member<Property> property_; }; -class ScriptPromisePropertyResetter : public ScriptFunction { +class ScriptPromisePropertyResetter : public NewScriptFunction::Callable { public: using Property = ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, Member<GarbageCollectedScriptWrappable>>; - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, - Property* property) { - auto* self = MakeGarbageCollected<ScriptPromisePropertyResetter>( - script_state, property); - return self->BindToV8Function(); - } - ScriptPromisePropertyResetter(ScriptState* script_state, Property* property) - : ScriptFunction(script_state), property_(property) {} + explicit ScriptPromisePropertyResetter(Property* property) + : property_(property) {} void Trace(Visitor* visitor) const override { visitor->Trace(property_); - ScriptFunction::Trace(visitor); + NewScriptFunction::Callable::Trace(visitor); } - private: - ScriptValue Call(ScriptValue arg) override { + ScriptValue Call(ScriptState*, ScriptValue arg) override { property_->Reset(); return ScriptValue(); } + private: const Member<Property> property_; }; @@ -163,12 +140,17 @@ void Gc() { ThreadState::Current()->CollectAllGarbageForTesting(); } v8::Local<v8::Function> NotReached(ScriptState* script_state) { - return NotReached::CreateFunction(script_state); + return MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<NotReachedFunction>()) + ->V8Function(); } v8::Local<v8::Function> Stub(ScriptState* script_state, ScriptValue& value, size_t& call_count) { - return StubFunction::CreateFunction(script_state, value, call_count); + return MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<StubFunction>(value, call_count)) + ->V8Function(); } template <typename T> @@ -560,8 +542,10 @@ GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks); main_v8_resolution = ToV8(resolution, MainScriptState()).As<v8::Object>(); v8::PropertyDescriptor descriptor( - ScriptPromisePropertyResetter::CreateFunction(MainScriptState(), - GetProperty()), + MakeGarbageCollected<NewScriptFunction>( + MainScriptState(), + MakeGarbageCollected<ScriptPromisePropertyResetter>(GetProperty())) + ->V8Function(), v8::Undefined(GetIsolate())); ASSERT_EQ( v8::Just(true), @@ -575,8 +559,10 @@ GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks); other_v8_resolution = ToV8(resolution, OtherScriptState()).As<v8::Object>(); v8::PropertyDescriptor descriptor( - ScriptPromisePropertyResetter::CreateFunction(OtherScriptState(), - GetProperty()), + MakeGarbageCollected<NewScriptFunction>( + OtherScriptState(), + MakeGarbageCollected<ScriptPromisePropertyResetter>(GetProperty())) + ->V8Function(), v8::Undefined(GetIsolate())); ASSERT_EQ( v8::Just(true),
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc index 2818fea..87010aa 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
@@ -24,27 +24,18 @@ namespace { -class TestHelperFunction : public ScriptFunction { +class TestHelperFunction : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, - String* value) { - TestHelperFunction* self = - MakeGarbageCollected<TestHelperFunction>(script_state, value); - return self->BindToV8Function(); - } + explicit TestHelperFunction(String* value) : value_(value) {} - TestHelperFunction(ScriptState* script_state, String* value) - : ScriptFunction(script_state), value_(value) {} - - private: - ScriptValue Call(ScriptValue value) override { + ScriptValue Call(ScriptState* script_state, ScriptValue value) override { DCHECK(!value.IsEmpty()); - *value_ = ToCoreString(value.V8Value() - ->ToString(GetScriptState()->GetContext()) - .ToLocalChecked()); + *value_ = ToCoreString( + value.V8Value()->ToString(script_state->GetContext()).ToLocalChecked()); return value; } + private: String* value_; }; @@ -87,9 +78,12 @@ ASSERT_FALSE(promise.IsEmpty()); { ScriptState::Scope scope(GetScriptState()); - promise.Then( - TestHelperFunction::CreateFunction(GetScriptState(), &on_fulfilled), - TestHelperFunction::CreateFunction(GetScriptState(), &on_rejected)); + promise.Then(MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_fulfilled)), + MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_rejected))); } EXPECT_EQ(String(), on_fulfilled); @@ -136,9 +130,12 @@ ASSERT_FALSE(promise.IsEmpty()); { ScriptState::Scope scope(GetScriptState()); - promise.Then( - TestHelperFunction::CreateFunction(GetScriptState(), &on_fulfilled), - TestHelperFunction::CreateFunction(GetScriptState(), &on_rejected)); + promise.Then(MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_fulfilled)), + MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_rejected))); } EXPECT_EQ(String(), on_fulfilled); @@ -185,9 +182,12 @@ ASSERT_FALSE(promise.IsEmpty()); { ScriptState::Scope scope(GetScriptState()); - promise.Then( - TestHelperFunction::CreateFunction(GetScriptState(), &on_fulfilled), - TestHelperFunction::CreateFunction(GetScriptState(), &on_rejected)); + promise.Then(MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_fulfilled)), + MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_rejected))); } GetExecutionContext()->NotifyContextDestroyed(); @@ -337,9 +337,12 @@ ASSERT_FALSE(promise.IsEmpty()); { ScriptState::Scope scope(GetScriptState()); - promise.Then( - TestHelperFunction::CreateFunction(GetScriptState(), &on_fulfilled), - TestHelperFunction::CreateFunction(GetScriptState(), &on_rejected)); + promise.Then(MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_fulfilled)), + MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_rejected))); } resolver->Resolve(); @@ -362,9 +365,12 @@ ASSERT_FALSE(promise.IsEmpty()); { ScriptState::Scope scope(GetScriptState()); - promise.Then( - TestHelperFunction::CreateFunction(GetScriptState(), &on_fulfilled), - TestHelperFunction::CreateFunction(GetScriptState(), &on_rejected)); + promise.Then(MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_fulfilled)), + MakeGarbageCollected<NewScriptFunction>( + GetScriptState(), + MakeGarbageCollected<TestHelperFunction>(&on_rejected))); } resolver->Reject();
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc index 987f646..9d2fc328 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
@@ -54,44 +54,19 @@ script_state, MakeGarbageCollected<T>(std::forward<Args>(args)...)); } -class FunctionForScriptPromiseTest : public ScriptFunction { +class FunctionForScriptPromiseTest : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, - ScriptValue* output) { - FunctionForScriptPromiseTest* self = - MakeGarbageCollected<FunctionForScriptPromiseTest>(script_state, - output); - return self->BindToV8Function(); - } + explicit FunctionForScriptPromiseTest(ScriptValue* output) + : output_(output) {} - FunctionForScriptPromiseTest(ScriptState* script_state, ScriptValue* output) - : ScriptFunction(script_state), output_(output) {} - - private: - ScriptValue Call(ScriptValue value) override { + ScriptValue Call(ScriptState*, ScriptValue value) override { DCHECK(!value.IsEmpty()); *output_ = value; return value; } - ScriptValue* output_; -}; - -class ThrowingFunction : public ScriptFunction { - public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - auto* self = MakeGarbageCollected<ThrowingFunction>(script_state); - return self->BindToV8Function(); - } - - ThrowingFunction(ScriptState* script_state) : ScriptFunction(script_state) {} - private: - ScriptValue Call(ScriptValue value) override { - v8::Isolate* isolate = GetScriptState()->GetIsolate(); - isolate->ThrowException(v8::Undefined(isolate)); - return ScriptValue(); - } + ScriptValue* output_; }; class ThrowingCallable : public NewScriptFunction::Callable { @@ -161,9 +136,9 @@ Resolver resolver(scope.GetScriptState()); ScriptPromise promise = resolver.Promise(); ScriptValue on_fulfilled, on_rejected; - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -210,9 +185,9 @@ ScriptPromise promise = resolver.Promise(); ScriptValue on_fulfilled, on_rejected; resolver.Resolve(V8String(scope.GetIsolate(), "hello")); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -248,9 +223,9 @@ Resolver resolver(scope.GetScriptState()); ScriptPromise promise = resolver.Promise(); ScriptValue on_fulfilled, on_rejected; - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -298,12 +273,12 @@ ScriptValue on_rejected, on_fulfilled2, on_rejected2; promise = - promise.Then(ThrowingFunction::CreateFunction(scope.GetScriptState()), - FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<ThrowingCallable>(scope.GetScriptState()), + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled2), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected2)); ASSERT_FALSE(promise.IsEmpty()); @@ -358,12 +333,12 @@ ScriptValue on_fulfilled, on_fulfilled2, on_rejected2; promise = - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled2), - ThrowingFunction::CreateFunction(scope.GetScriptState())); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<ThrowingCallable>(scope.GetScriptState())); + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled2), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected2)); ASSERT_FALSE(promise.IsEmpty()); @@ -417,9 +392,9 @@ ScriptPromise promise = resolver.Promise(); ScriptValue on_fulfilled, on_rejected; resolver.Reject(V8String(scope.GetIsolate(), "hello")); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -470,13 +445,13 @@ ScriptPromise::Cast(scope.GetScriptState(), ScriptValue(value)); ScriptPromise promise2 = ScriptPromise::Cast(scope.GetScriptState(), ScriptValue(value)); - promise1.Then(FunctionForScriptPromiseTest::CreateFunction( + promise1.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled1), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected1)); - promise2.Then(FunctionForScriptPromiseTest::CreateFunction( + promise2.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled2), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected2)); ASSERT_FALSE(promise1.IsEmpty()); @@ -507,9 +482,9 @@ ScriptValue(scope.GetIsolate(), V8String(scope.GetIsolate(), "hello")); ScriptPromise promise = ScriptPromise::Reject(scope.GetScriptState(), ScriptValue(value)); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -531,9 +506,9 @@ scope.GetScriptState(), MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, "some syntax error")); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); ASSERT_FALSE(promise.IsEmpty()); @@ -555,9 +530,9 @@ ScriptPromise::All(scope.GetScriptState(), HeapVector<ScriptPromise>()); ASSERT_FALSE(promise.IsEmpty()); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); EXPECT_TRUE(on_fulfilled.IsEmpty()); @@ -582,9 +557,9 @@ ScriptPromise promise = ScriptPromise::All(scope.GetScriptState(), promises); ASSERT_FALSE(promise.IsEmpty()); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); EXPECT_TRUE(on_fulfilled.IsEmpty()); @@ -612,9 +587,9 @@ ScriptPromise promise = ScriptPromise::All(scope.GetScriptState(), promises); ASSERT_FALSE(promise.IsEmpty()); - promise.Then(FunctionForScriptPromiseTest::CreateFunction( + promise.Then(CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_fulfilled), - FunctionForScriptPromiseTest::CreateFunction( + CreateFunction<FunctionForScriptPromiseTest>( scope.GetScriptState(), &on_rejected)); EXPECT_TRUE(on_fulfilled.IsEmpty());
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc index c38b7839..47f0505d 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc
@@ -15,25 +15,13 @@ namespace blink { -class ScriptPromiseTester::ThenFunction : public ScriptFunction { +class ScriptPromiseTester::ThenFunction : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> CreateFunction( - ScriptState* script_state, - base::WeakPtr<ScriptPromiseTester> owner, - ScriptPromiseTester::State target_state) { - ThenFunction* self = MakeGarbageCollected<ThenFunction>( - script_state, std::move(owner), target_state); - return self->BindToV8Function(); - } - - ThenFunction(ScriptState* script_state, - base::WeakPtr<ScriptPromiseTester> owner, + ThenFunction(base::WeakPtr<ScriptPromiseTester> owner, ScriptPromiseTester::State target_state) - : ScriptFunction(script_state), - owner_(std::move(owner)), - target_state_(target_state) {} + : owner_(std::move(owner)), target_state_(target_state) {} - ScriptValue Call(ScriptValue value) override { + ScriptValue Call(ScriptState*, ScriptValue value) override { if (!owner_) return value; @@ -55,10 +43,12 @@ : script_state_(script_state) { DCHECK(script_state); script_promise.Then( - ThenFunction::CreateFunction(script_state, weak_factory_.GetWeakPtr(), - State::kFulfilled), - ThenFunction::CreateFunction(script_state, weak_factory_.GetWeakPtr(), - State::kRejected)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ThenFunction>( + weak_factory_.GetWeakPtr(), State::kFulfilled)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ThenFunction>( + weak_factory_.GetWeakPtr(), State::kRejected))); } void ScriptPromiseTester::WaitUntilSettled() {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 7d55c62..e1179a6e 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -782,20 +782,13 @@ return result; } -class ModuleEvaluationRejectionCallback final : public ScriptFunction { +class ModuleEvaluationRejectionCallback final + : public NewScriptFunction::Callable { public: - explicit ModuleEvaluationRejectionCallback(ScriptState* script_state) - : ScriptFunction(script_state) {} + ModuleEvaluationRejectionCallback() = default; - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - ModuleEvaluationRejectionCallback* self = - MakeGarbageCollected<ModuleEvaluationRejectionCallback>(script_state); - return self->BindToV8Function(); - } - - private: - ScriptValue Call(ScriptValue value) override { - ModuleRecord::ReportException(GetScriptState(), value.V8Value()); + ScriptValue Call(ScriptState* script_state, ScriptValue value) override { + ModuleRecord::ReportException(script_state, value.V8Value()); return ScriptValue(); } }; @@ -905,7 +898,10 @@ // evaluationPromise with reason, report the exception given by reason // for script.</spec> v8::Local<v8::Function> callback_failure = - ModuleEvaluationRejectionCallback::CreateFunction(script_state); + MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<ModuleEvaluationRejectionCallback>()) + ->V8Function(); // Add a rejection handler to report back errors once the result // promise is rejected. result.GetPromise(script_state)
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc index f0667ee..ed8fc6f 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -286,19 +286,17 @@ } template <typename T> -class WebCryptoResultAdapter : public ScriptFunction { +class WebCryptoResultAdapter : public NewScriptFunction::Callable { public: - WebCryptoResultAdapter(ScriptState* script_state, - base::RepeatingCallback<void(T)> function) - : ScriptFunction(script_state), function_(std::move(function)) {} + explicit WebCryptoResultAdapter(base::RepeatingCallback<void(T)> function) + : function_(std::move(function)) {} - private: - ScriptValue Call(ScriptValue value) final { - function_.Run( - ConvertCryptoResult<T>(GetScriptState()->GetIsolate(), value)); - return ScriptValue::From(GetScriptState(), ToV8UndefinedGenerator()); + ScriptValue Call(ScriptState* script_state, ScriptValue value) final { + function_.Run(ConvertCryptoResult<T>(script_state->GetIsolate(), value)); + return ScriptValue::From(script_state, ToV8UndefinedGenerator()); } + private: base::RepeatingCallback<void(T)> function_; template <typename U> friend WebCryptoResult ToWebCryptoResult(ScriptState*, @@ -310,14 +308,17 @@ base::RepeatingCallback<void(T)> function) { auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state); result->Promise().Then( - (MakeGarbageCollected<WebCryptoResultAdapter<T>>(script_state, - std::move(function))) - ->BindToV8Function(), - (MakeGarbageCollected<WebCryptoResultAdapter<DOMException*>>( - script_state, WTF::BindRepeating([](DOMException* exception) { - CHECK(false) << "crypto operation failed"; - }))) - ->BindToV8Function()); + (MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<WebCryptoResultAdapter<T>>( + std::move(function)))) + ->V8Function(), + (MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<WebCryptoResultAdapter<DOMException*>>( + WTF::BindRepeating([](DOMException* exception) { + CHECK(false) << "crypto operation failed"; + })))) + ->V8Function()); return result->Result(); }
diff --git a/third_party/blink/renderer/build/scripts/gperf.py b/third_party/blink/renderer/build/scripts/gperf.py index db72660d4..34b18c9f 100644 --- a/third_party/blink/renderer/build/scripts/gperf.py +++ b/third_party/blink/renderer/build/scripts/gperf.py
@@ -39,7 +39,7 @@ # so replace gperf's /*FALLTHROUGH*/ comment with the statement. # https://savannah.gnu.org/bugs/index.php?53029 gperf_output = gperf_output.replace('/*FALLTHROUGH*/', - ' FALLTHROUGH;') + ' [[fallthrough]];') # -Wpointer-to-int-cast warns about casting pointers to smaller ints # Replace {(int)(long)&(foo), bar} with # {static_cast<int>(reinterpret_cast<uintptr_t>(&(foo)), bar}
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl index d1209bbf..ddd0027 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl
@@ -77,9 +77,9 @@ {%- endif %} {% endmacro %} -{% macro compare(is_pointer_type, expr, other_name) %} -{% if is_pointer_type -%} - DataEquivalent({{expr}}, {{other_name}}.{{expr}}) +{% macro compare(wrapper_pointer_name, expr, other_name) %} +{% if wrapper_pointer_name -%} + base::ValuesEquivalent({{expr}}, {{other_name}}.{{expr}}) {%- else -%} {{expr}} == {{other_name}}.{{expr}} {%- endif %} @@ -158,7 +158,7 @@ {% macro diff_field(is_pointer_type, expr) %} {% if is_pointer_type -%} -!DataEquivalent(a.{{expr}}, b.{{expr}}) +!base::ValuesEquivalent(a.{{expr}}, b.{{expr}}) {%- else -%} a.{{expr}} != b.{{expr}} {%- endif %}
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 4d300e5..78ee8dd 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -2,6 +2,7 @@ "+base/atomic_sequence_num.h", "+base/barrier_closure.h", "+base/cancelable_callback.h", + "+base/memory/values_equivalent.h", "+base/files/file.h", "+base/guid.h", "+base/mac/foundation_util.h",
diff --git a/third_party/blink/renderer/core/animation/css/css_timing_data.cc b/third_party/blink/renderer/core/animation/css/css_timing_data.cc index fe027ea..a9d0096 100644 --- a/third_party/blink/renderer/core/animation/css/css_timing_data.cc +++ b/third_party/blink/renderer/core/animation/css/css_timing_data.cc
@@ -40,8 +40,8 @@ return false; for (wtf_size_t i = 0; i < timing_function_list_.size(); i++) { - if (!DataEquivalent(timing_function_list_.at(i), - other.timing_function_list_.at(i))) { + if (!ValuesEquivalent(timing_function_list_.at(i), + other.timing_function_list_.at(i))) { return false; } }
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc index b1bb84f..cbfea5a 100644 --- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_value_list.h" @@ -15,7 +16,6 @@ #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" #include "third_party/blink/renderer/core/style/basic_shapes.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style/shape_clip_path_operation.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -82,8 +82,8 @@ private: bool IsValid(const StyleResolverState& state, const InterpolationValue&) const final { - return DataEquivalent(inherited_shape_.get(), - GetBasicShape(property_, *state.ParentStyle())); + return base::ValuesEquivalent( + inherited_shape_.get(), GetBasicShape(property_, *state.ParentStyle())); } const CSSProperty& property_;
diff --git a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc index aa886124..a8d0f26d 100644 --- a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
@@ -65,7 +65,7 @@ switch (syntax_repeat_) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSSyntaxRepeat::kSpaceSeparated: list = CSSValueList::CreateSpaceSeparated(); break;
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc index 47d37d7..173ecdd6 100644 --- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -26,7 +26,7 @@ switch (property.PropertyID()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSPropertyID::kBackdropFilter: return style.BackdropFilter(); case CSSPropertyID::kFilter:
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc index 5e1141b8..c286e01 100644 --- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -92,7 +92,7 @@ private: bool IsValid(const StyleResolverState& state, const InterpolationValue&) const final { - return DataEquivalent( + return ValuesEquivalent( settings_.get(), state.ParentStyle()->GetFontDescription().VariationSettings()); }
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc index d52bbbf..630ec6d5 100644 --- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_crossfade_value.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" @@ -45,8 +46,8 @@ bool IsSingle() const { return is_single_; } bool Equals(const CSSImageNonInterpolableValue& other) const { - return DataEquivalent(start_, other.start_) && - DataEquivalent(end_, other.end_); + return base::ValuesEquivalent(start_, other.start_) && + base::ValuesEquivalent(end_, other.end_); } static scoped_refptr<CSSImageNonInterpolableValue> Merge(
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_interpolation_type.cc index fc1b1df..f73b2ff 100644 --- a/third_party/blink/renderer/core/animation/css_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/animation/css_interpolation_environment.h" #include "third_party/blink/renderer/core/animation/string_keyframe.h" #include "third_party/blink/renderer/core/css/computed_style_css_value_mapping.h" @@ -27,7 +28,6 @@ #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" #include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { @@ -49,7 +49,7 @@ // full CSSValue resolve. const CSSValue* resolved_value = css_environment.Resolve( PropertyHandle(CSSProperty::Get(property_)), variable_reference_); - return DataEquivalent(resolved_value_.Get(), resolved_value); + return base::ValuesEquivalent(resolved_value_.Get(), resolved_value); } CSSPropertyID property_; @@ -77,7 +77,7 @@ if (!inherited_value) { inherited_value = initial_value_.Get(); } - return DataEquivalent(inherited_value_.Get(), inherited_value); + return base::ValuesEquivalent(inherited_value_.Get(), inherited_value); } AtomicString name_; @@ -106,7 +106,7 @@ if (const auto* decl = DynamicTo<CSSCustomPropertyDeclaration>(resolved)) resolved_tokens = decl->Value(); - return DataEquivalent(resolved_tokens, resolved_tokens_); + return base::ValuesEquivalent(resolved_tokens, resolved_tokens_); } PropertyHandle property_; @@ -133,7 +133,8 @@ const auto& css_environment = To<CSSInterpolationEnvironment>(environment); const CSSValue* current_resolved_value = css_environment.Resolve(property_handle_, RevertValueType::Create()); - return DataEquivalent(resolved_value_.Get(), current_resolved_value); + return base::ValuesEquivalent(resolved_value_.Get(), + current_resolved_value); } PropertyHandle property_handle_;
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc index 4719ada..1dd5b36b 100644 --- a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc +++ b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
@@ -238,7 +238,7 @@ case CSSPropertyID::kOffsetPath: applicable_types->push_back( std::make_unique<CSSRayInterpolationType>(used_property)); - FALLTHROUGH; + [[fallthrough]]; case CSSPropertyID::kD: applicable_types->push_back( std::make_unique<CSSPathInterpolationType>(used_property));
diff --git a/third_party/blink/renderer/core/animation/image_slice_property_functions.h b/third_party/blink/renderer/core/animation/image_slice_property_functions.h index 41167c1..15a7d83 100644 --- a/third_party/blink/renderer/core/animation/image_slice_property_functions.h +++ b/third_party/blink/renderer/core/animation/image_slice_property_functions.h
@@ -34,7 +34,7 @@ switch (property.PropertyID()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSPropertyID::kBorderImageSlice: return ImageSlice(style.BorderImageSlices(), style.BorderImageSlicesFill());
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index 66b9db7..c11e903 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -6,6 +6,7 @@ #include <tuple> +#include "base/memory/values_equivalent.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" @@ -272,7 +273,7 @@ return false; wtf_size_t size = scroll_offsets_.size(); for (wtf_size_t i = 0; i < size; ++i) { - if (!DataEquivalent(scroll_offsets_.at(i), other.at(i))) + if (!base::ValuesEquivalent(scroll_offsets_.at(i), other.at(i))) return false; } return true;
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc b/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc index 08836dc..5479631 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" +#include "base/memory/values_equivalent.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" @@ -13,7 +14,6 @@ #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" @@ -224,7 +224,7 @@ } bool ScrollTimelineOffset::operator==(const ScrollTimelineOffset& o) const { - return DataEquivalent(length_based_offset_, o.length_based_offset_) && + return base::ValuesEquivalent(length_based_offset_, o.length_based_offset_) && ElementBasedOffsetsEqual(element_based_offset_, o.element_based_offset_); }
diff --git a/third_party/blink/renderer/core/animation/timing.h b/third_party/blink/renderer/core/animation/timing.h index 33e58a1..0bbe113 100644 --- a/third_party/blink/renderer/core/animation/timing.h +++ b/third_party/blink/renderer/core/animation/timing.h
@@ -32,10 +32,10 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_H_ #include "base/memory/scoped_refptr.h" +#include "base/memory/values_equivalent.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_time_delta.h" #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/animation/timing_function.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -112,7 +112,8 @@ iteration_count == other.iteration_count && iteration_duration == other.iteration_duration && direction == other.direction && - DataEquivalent(timing_function.get(), other.timing_function.get()); + base::ValuesEquivalent(timing_function.get(), + other.timing_function.get()); } bool operator!=(const Timing& other) const { return !(*this == other); }
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer.cc b/third_party/blink/renderer/core/clipboard/data_transfer.cc index 46fb5e0..cbd94d3 100644 --- a/third_party/blink/renderer/core/clipboard/data_transfer.cc +++ b/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -123,7 +123,7 @@ gfx::RectF bounding_box = layer->GetLayoutObject() - .AbsoluteToLocalQuad(FloatQuad(absolute_bounding_box)) + .AbsoluteToLocalQuad(gfx::QuadF(gfx::RectF(absolute_bounding_box))) .BoundingBox(); gfx::RectF cull_rect = bounding_box; cull_rect.Offset(
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator.cc b/third_party/blink/renderer/core/css/container_query_evaluator.cc index d4bea15..6e5e79d 100644 --- a/third_party/blink/renderer/core/css/container_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/container_query_evaluator.cc
@@ -65,7 +65,7 @@ for (Element* element = container; element; element = LayoutTreeBuilderTraversal::ParentElement(*element)) { if (const ComputedStyle* style = element->GetComputedStyle()) { - if (style->IsContainerForContainerQueries() && + if (style->IsContainerForContainerQueries(*element) && Matches(*style, container_selector)) { return element; }
diff --git a/third_party/blink/renderer/core/css/css_basic_shape_values.cc b/third_party/blink/renderer/core/css/css_basic_shape_values.cc index 5527f82..5f3649a 100644 --- a/third_party/blink/renderer/core/css/css_basic_shape_values.cc +++ b/third_party/blink/renderer/core/css/css_basic_shape_values.cc
@@ -138,9 +138,9 @@ bool CSSBasicShapeCircleValue::Equals( const CSSBasicShapeCircleValue& other) const { - return DataEquivalent(center_x_, other.center_x_) && - DataEquivalent(center_y_, other.center_y_) && - DataEquivalent(radius_, other.radius_); + return base::ValuesEquivalent(center_x_, other.center_x_) && + base::ValuesEquivalent(center_y_, other.center_y_) && + base::ValuesEquivalent(radius_, other.radius_); } void CSSBasicShapeCircleValue::TraceAfterDispatch( @@ -221,10 +221,10 @@ bool CSSBasicShapeEllipseValue::Equals( const CSSBasicShapeEllipseValue& other) const { - return DataEquivalent(center_x_, other.center_x_) && - DataEquivalent(center_y_, other.center_y_) && - DataEquivalent(radius_x_, other.radius_x_) && - DataEquivalent(radius_y_, other.radius_y_); + return base::ValuesEquivalent(center_x_, other.center_x_) && + base::ValuesEquivalent(center_y_, other.center_y_) && + base::ValuesEquivalent(radius_x_, other.radius_x_) && + base::ValuesEquivalent(radius_y_, other.radius_y_); } void CSSBasicShapeEllipseValue::TraceAfterDispatch( @@ -428,14 +428,15 @@ bool CSSBasicShapeInsetValue::Equals( const CSSBasicShapeInsetValue& other) const { - return DataEquivalent(top_, other.top_) && - DataEquivalent(right_, other.right_) && - DataEquivalent(bottom_, other.bottom_) && - DataEquivalent(left_, other.left_) && - DataEquivalent(top_left_radius_, other.top_left_radius_) && - DataEquivalent(top_right_radius_, other.top_right_radius_) && - DataEquivalent(bottom_right_radius_, other.bottom_right_radius_) && - DataEquivalent(bottom_left_radius_, other.bottom_left_radius_); + return base::ValuesEquivalent(top_, other.top_) && + base::ValuesEquivalent(right_, other.right_) && + base::ValuesEquivalent(bottom_, other.bottom_) && + base::ValuesEquivalent(left_, other.left_) && + base::ValuesEquivalent(top_left_radius_, other.top_left_radius_) && + base::ValuesEquivalent(top_right_radius_, other.top_right_radius_) && + base::ValuesEquivalent(bottom_right_radius_, + other.bottom_right_radius_) && + base::ValuesEquivalent(bottom_left_radius_, other.bottom_left_radius_); } void CSSBasicShapeInsetValue::TraceAfterDispatch(
diff --git a/third_party/blink/renderer/core/css/css_border_image_slice_value.cc b/third_party/blink/renderer/core/css/css_border_image_slice_value.cc index d18e899..b624946 100644 --- a/third_party/blink/renderer/core/css/css_border_image_slice_value.cc +++ b/third_party/blink/renderer/core/css/css_border_image_slice_value.cc
@@ -48,7 +48,7 @@ bool CSSBorderImageSliceValue::Equals( const CSSBorderImageSliceValue& other) const { - return fill_ == other.fill_ && DataEquivalent(slices_, other.slices_); + return fill_ == other.fill_ && base::ValuesEquivalent(slices_, other.slices_); } void CSSBorderImageSliceValue::TraceAfterDispatch(
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc index 4d87ad3..746bcf66 100644 --- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -25,6 +25,7 @@ #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" #include "base/cxx17_backports.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/computed_style_css_value_mapping.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" @@ -361,7 +362,7 @@ } } const CSSValue* value = GetPropertyCSSValue(property_id); - return DataEquivalent(value, &property_value); + return base::ValuesEquivalent(value, &property_value); } MutableCSSPropertyValueSet* CSSComputedStyleDeclaration::CopyProperties()
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.cc b/third_party/blink/renderer/core/css/css_crossfade_value.cc index a83e61a0..d2746ef 100644 --- a/third_party/blink/renderer/core/css/css_crossfade_value.cc +++ b/third_party/blink/renderer/core/css/css_crossfade_value.cc
@@ -59,9 +59,9 @@ } bool CSSCrossfadeValue::Equals(const CSSCrossfadeValue& other) const { - return DataEquivalent(from_value_, other.from_value_) && - DataEquivalent(to_value_, other.to_value_) && - DataEquivalent(percentage_value_, other.percentage_value_); + return base::ValuesEquivalent(from_value_, other.from_value_) && + base::ValuesEquivalent(to_value_, other.to_value_) && + base::ValuesEquivalent(percentage_value_, other.percentage_value_); } class CSSCrossfadeValue::ObserverProxy final
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.cc b/third_party/blink/renderer/core/css/css_cursor_image_value.cc index 0e3b368e..849ce9c 100644 --- a/third_party/blink/renderer/core/css/css_cursor_image_value.cc +++ b/third_party/blink/renderer/core/css/css_cursor_image_value.cc
@@ -54,7 +54,7 @@ return (hot_spot_specified_ ? other.hot_spot_specified_ && hot_spot_ == other.hot_spot_ : !other.hot_spot_specified_) && - DataEquivalent(image_value_, other.image_value_); + base::ValuesEquivalent(image_value_, other.image_value_); } void CSSCursorImageValue::TraceAfterDispatch(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/css_element_offset_value.cc b/third_party/blink/renderer/core/css/css_element_offset_value.cc index 2016383..2cfcd28 100644 --- a/third_party/blink/renderer/core/css/css_element_offset_value.cc +++ b/third_party/blink/renderer/core/css/css_element_offset_value.cc
@@ -3,8 +3,8 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/css/css_element_offset_value.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_function_value.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -39,9 +39,9 @@ } bool CSSElementOffsetValue::Equals(const CSSElementOffsetValue& other) const { - return DataEquivalent(target_, other.target_) && - DataEquivalent(edge_, other.edge_) && - DataEquivalent(threshold_, other.threshold_); + return base::ValuesEquivalent(target_, other.target_) && + base::ValuesEquivalent(edge_, other.edge_) && + base::ValuesEquivalent(threshold_, other.threshold_); } void CSSElementOffsetValue::TraceAfterDispatch(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc index 79c5b8b..63d0b08c 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.cc +++ b/third_party/blink/renderer/core/css/css_gradient_value.cc
@@ -31,6 +31,7 @@ #include <utility> #include "base/cxx17_backports.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_color.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_math_expression_node.h" @@ -1039,29 +1040,34 @@ return false; if (gradient_type_ == kCSSDeprecatedLinearGradient) { - return DataEquivalent(first_x_, other.first_x_) && - DataEquivalent(first_y_, other.first_y_) && - DataEquivalent(second_x_, other.second_x_) && - DataEquivalent(second_y_, other.second_y_) && stops_ == other.stops_; + return base::ValuesEquivalent(first_x_, other.first_x_) && + base::ValuesEquivalent(first_y_, other.first_y_) && + base::ValuesEquivalent(second_x_, other.second_x_) && + base::ValuesEquivalent(second_y_, other.second_y_) && + stops_ == other.stops_; } if (repeating_ != other.repeating_) return false; - if (angle_) - return DataEquivalent(angle_, other.angle_) && stops_ == other.stops_; + if (angle_) { + return base::ValuesEquivalent(angle_, other.angle_) && + stops_ == other.stops_; + } if (other.angle_) return false; bool equal_xand_y = false; if (first_x_ && first_y_) { - equal_xand_y = DataEquivalent(first_x_, other.first_x_) && - DataEquivalent(first_y_, other.first_y_); + equal_xand_y = base::ValuesEquivalent(first_x_, other.first_x_) && + base::ValuesEquivalent(first_y_, other.first_y_); } else if (first_x_) { - equal_xand_y = DataEquivalent(first_x_, other.first_x_) && !other.first_y_; + equal_xand_y = + base::ValuesEquivalent(first_x_, other.first_x_) && !other.first_y_; } else if (first_y_) { - equal_xand_y = DataEquivalent(first_y_, other.first_y_) && !other.first_x_; + equal_xand_y = + base::ValuesEquivalent(first_y_, other.first_y_) && !other.first_x_; } else { equal_xand_y = !other.first_x_ && !other.first_y_; } @@ -1447,27 +1453,28 @@ bool CSSRadialGradientValue::Equals(const CSSRadialGradientValue& other) const { if (gradient_type_ == kCSSDeprecatedRadialGradient) return other.gradient_type_ == gradient_type_ && - DataEquivalent(first_x_, other.first_x_) && - DataEquivalent(first_y_, other.first_y_) && - DataEquivalent(second_x_, other.second_x_) && - DataEquivalent(second_y_, other.second_y_) && - DataEquivalent(first_radius_, other.first_radius_) && - DataEquivalent(second_radius_, other.second_radius_) && + base::ValuesEquivalent(first_x_, other.first_x_) && + base::ValuesEquivalent(first_y_, other.first_y_) && + base::ValuesEquivalent(second_x_, other.second_x_) && + base::ValuesEquivalent(second_y_, other.second_y_) && + base::ValuesEquivalent(first_radius_, other.first_radius_) && + base::ValuesEquivalent(second_radius_, other.second_radius_) && stops_ == other.stops_; if (repeating_ != other.repeating_) return false; - if (!DataEquivalent(first_x_, other.first_x_) || - !DataEquivalent(first_y_, other.first_y_)) + if (!base::ValuesEquivalent(first_x_, other.first_x_) || + !base::ValuesEquivalent(first_y_, other.first_y_)) return false; // There's either a size keyword or an explicit size specification. if (end_horizontal_size_) { // Explicit size specification. One <length> or two <length-percentage>. - if (!DataEquivalent(end_horizontal_size_, other.end_horizontal_size_)) + if (!base::ValuesEquivalent(end_horizontal_size_, + other.end_horizontal_size_)) return false; - if (!DataEquivalent(end_vertical_size_, other.end_vertical_size_)) + if (!base::ValuesEquivalent(end_vertical_size_, other.end_vertical_size_)) return false; } else { if (other.end_horizontal_size_) @@ -1564,9 +1571,10 @@ } bool CSSConicGradientValue::Equals(const CSSConicGradientValue& other) const { - return repeating_ == other.repeating_ && DataEquivalent(x_, other.x_) && - DataEquivalent(y_, other.y_) && - DataEquivalent(from_angle_, other.from_angle_) && + return repeating_ == other.repeating_ && + base::ValuesEquivalent(x_, other.x_) && + base::ValuesEquivalent(y_, other.y_) && + base::ValuesEquivalent(from_angle_, other.from_angle_) && stops_ == other.stops_; }
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.h b/third_party/blink/renderer/core/css/css_gradient_value.h index f3649c0..75d31116 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.h +++ b/third_party/blink/renderer/core/css/css_gradient_value.h
@@ -63,8 +63,8 @@ DISALLOW_NEW(); bool operator==(const CSSGradientColorStop& other) const { - return DataEquivalent(color_, other.color_) && - DataEquivalent(offset_, other.offset_); + return base::ValuesEquivalent(color_, other.color_) && + base::ValuesEquivalent(offset_, other.offset_); } bool IsHint() const {
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node.cc b/third_party/blink/renderer/core/css/css_math_expression_node.cc index ecd8b7ce..47b6d6e 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node.cc +++ b/third_party/blink/renderer/core/css/css_math_expression_node.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/css/css_math_expression_node.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_value_clamping_utils.h" @@ -313,8 +314,8 @@ if (!other.IsNumericLiteral()) return false; - return DataEquivalent(value_, - To<CSSMathExpressionNumericLiteral>(other).value_); + return base::ValuesEquivalent( + value_, To<CSSMathExpressionNumericLiteral>(other).value_); } CSSPrimitiveValue::UnitType CSSMathExpressionNumericLiteral::ResolvedUnitType() @@ -725,8 +726,8 @@ const CSSMathExpressionBinaryOperation& other = To<CSSMathExpressionBinaryOperation>(exp); - return DataEquivalent(left_side_, other.left_side_) && - DataEquivalent(right_side_, other.right_side_) && + return base::ValuesEquivalent(left_side_, other.left_side_) && + base::ValuesEquivalent(right_side_, other.right_side_) && operator_ == other.operator_; } @@ -1003,7 +1004,7 @@ if (operands_.size() != other.operands_.size()) return false; for (wtf_size_t i = 0; i < operands_.size(); ++i) { - if (!DataEquivalent(operands_[i], other.operands_[i])) + if (!base::ValuesEquivalent(operands_[i], other.operands_[i])) return false; } return true;
diff --git a/third_party/blink/renderer/core/css/css_math_function_value.cc b/third_party/blink/renderer/core/css/css_math_function_value.cc index 12de49ec..cd08b4e3 100644 --- a/third_party/blink/renderer/core/css/css_math_function_value.cc +++ b/third_party/blink/renderer/core/css/css_math_function_value.cc
@@ -118,7 +118,7 @@ } bool CSSMathFunctionValue::Equals(const CSSMathFunctionValue& other) const { - return DataEquivalent(expression_, other.expression_); + return base::ValuesEquivalent(expression_, other.expression_); } double CSSMathFunctionValue::ClampToPermittedRange(double value) const {
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 70d4aa7..034f1f62 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -753,6 +753,15 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"], interpolable: true, inherited: true, + // color isn't strictly independent of all other properties; + // it determines currentColor, which in turn can affect the used value of + // other properties (such as border colors, stops in gradients, etc.). + // However, changes to color generally also trigger paint invalidation, + // and paint invalidation resolves the color anew. (For the special case + // of gradient stops, we have logic within ComputedStyle::AdjustDiffForBackgroundVisuallyEqual + // that forces paint invalidation, recomputing the gradient and repainting + // the element.) + independent: true, field_group: "inherited", field_template: "external", include_paths: ["third_party/blink/renderer/core/css/style_color.h"], @@ -6401,7 +6410,7 @@ { name: "text-emphasis", longhands: ["text-emphasis-style", "text-emphasis-color"], - property_methods: ["ParseShorthand"], + property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"], }, { name: "-webkit-text-stroke",
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc index b4749b7..2d51760b4 100644 --- a/third_party/blink/renderer/core/css/css_property_equality.cc +++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -4,10 +4,10 @@ #include "third_party/blink/renderer/core/css/css_property_equality.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/animation/property_handle.h" #include "third_party/blink/renderer/core/css/css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style/shadow_list.h" // TODO(ikilpatrick): generate this file. @@ -42,7 +42,7 @@ return false; break; case CSSPropertyID::kBackgroundImage: - if (!DataEquivalent(a_layer->GetImage(), b_layer->GetImage())) + if (!base::ValuesEquivalent(a_layer->GetImage(), b_layer->GetImage())) return false; break; default: @@ -65,7 +65,8 @@ const ComputedStyle& b) { if (property.IsCSSCustomProperty()) { const AtomicString& name = property.CustomPropertyName(); - return DataEquivalent(a.GetVariableValue(name), b.GetVariableValue(name)); + return base::ValuesEquivalent(a.GetVariableValue(name), + b.GetVariableValue(name)); } switch (property.GetCSSProperty().PropertyID()) { case CSSPropertyID::kBackgroundColor: @@ -101,7 +102,8 @@ case CSSPropertyID::kBorderImageSlice: return a.BorderImageSlices() == b.BorderImageSlices(); case CSSPropertyID::kBorderImageSource: - return DataEquivalent(a.BorderImageSource(), b.BorderImageSource()); + return base::ValuesEquivalent(a.BorderImageSource(), + b.BorderImageSource()); case CSSPropertyID::kBorderImageWidth: return a.BorderImageWidth() == b.BorderImageWidth(); case CSSPropertyID::kBorderLeftColor: @@ -129,7 +131,7 @@ case CSSPropertyID::kBottom: return a.Bottom() == b.Bottom(); case CSSPropertyID::kBoxShadow: - return DataEquivalent(a.BoxShadow(), b.BoxShadow()); + return base::ValuesEquivalent(a.BoxShadow(), b.BoxShadow()); case CSSPropertyID::kCaretColor: return a.CaretColor() == b.CaretColor() && a.InternalVisitedCaretColor() == b.InternalVisitedCaretColor(); @@ -167,8 +169,8 @@ case CSSPropertyID::kFontStretch: return a.GetFontStretch() == b.GetFontStretch(); case CSSPropertyID::kFontVariationSettings: - return DataEquivalent(a.GetFontDescription().VariationSettings(), - b.GetFontDescription().VariationSettings()); + return base::ValuesEquivalent(a.GetFontDescription().VariationSettings(), + b.GetFontDescription().VariationSettings()); case CSSPropertyID::kFontWeight: return a.GetFontWeight() == b.GetFontWeight(); case CSSPropertyID::kHeight: @@ -184,7 +186,7 @@ case CSSPropertyID::kTabSize: return a.GetTabSize() == b.GetTabSize(); case CSSPropertyID::kListStyleImage: - return DataEquivalent(a.ListStyleImage(), b.ListStyleImage()); + return base::ValuesEquivalent(a.ListStyleImage(), b.ListStyleImage()); case CSSPropertyID::kMarginBottom: return a.MarginBottom() == b.MarginBottom(); case CSSPropertyID::kMarginLeft: @@ -208,7 +210,7 @@ case CSSPropertyID::kOffsetDistance: return a.OffsetDistance() == b.OffsetDistance(); case CSSPropertyID::kOffsetPath: - return DataEquivalent(a.OffsetPath(), b.OffsetPath()); + return base::ValuesEquivalent(a.OffsetPath(), b.OffsetPath()); case CSSPropertyID::kOffsetPosition: return a.OffsetPosition() == b.OffsetPosition(); case CSSPropertyID::kOffsetRotate: @@ -241,7 +243,7 @@ case CSSPropertyID::kShapeMargin: return a.ShapeMargin() == b.ShapeMargin(); case CSSPropertyID::kShapeOutside: - return DataEquivalent(a.ShapeOutside(), b.ShapeOutside()); + return base::ValuesEquivalent(a.ShapeOutside(), b.ShapeOutside()); case CSSPropertyID::kStopColor: return a.StopColor() == b.StopColor(); case CSSPropertyID::kStopOpacity: @@ -269,7 +271,7 @@ case CSSPropertyID::kTextIndent: return a.TextIndent() == b.TextIndent(); case CSSPropertyID::kTextShadow: - return DataEquivalent(a.TextShadow(), b.TextShadow()); + return base::ValuesEquivalent(a.TextShadow(), b.TextShadow()); case CSSPropertyID::kTextSizeAdjust: return a.GetTextSizeAdjust() == b.GetTextSizeAdjust(); case CSSPropertyID::kTop: @@ -285,7 +287,7 @@ case CSSPropertyID::kWebkitBorderVerticalSpacing: return a.VerticalBorderSpacing() == b.VerticalBorderSpacing(); case CSSPropertyID::kClipPath: - return DataEquivalent(a.ClipPath(), b.ClipPath()); + return base::ValuesEquivalent(a.ClipPath(), b.ClipPath()); case CSSPropertyID::kColumnCount: return a.ColumnCount() == b.ColumnCount(); case CSSPropertyID::kColumnGap: @@ -309,11 +311,12 @@ case CSSPropertyID::kWebkitMaskBoxImageSlice: return a.MaskBoxImageSlices() == b.MaskBoxImageSlices(); case CSSPropertyID::kWebkitMaskBoxImageSource: - return DataEquivalent(a.MaskBoxImageSource(), b.MaskBoxImageSource()); + return base::ValuesEquivalent(a.MaskBoxImageSource(), + b.MaskBoxImageSource()); case CSSPropertyID::kWebkitMaskBoxImageWidth: return a.MaskBoxImageWidth() == b.MaskBoxImageWidth(); case CSSPropertyID::kWebkitMaskImage: - return DataEquivalent(a.MaskImage(), b.MaskImage()); + return base::ValuesEquivalent(a.MaskImage(), b.MaskImage()); case CSSPropertyID::kWebkitMaskPositionX: return FillLayersEqual<CSSPropertyID::kWebkitMaskPositionX>( a.MaskLayers(), b.MaskLayers()); @@ -335,11 +338,12 @@ case CSSPropertyID::kTransform: return a.Transform() == b.Transform(); case CSSPropertyID::kTranslate: - return DataEquivalent<TransformOperation>(a.Translate(), b.Translate()); + return base::ValuesEquivalent<TransformOperation>(a.Translate(), + b.Translate()); case CSSPropertyID::kRotate: - return DataEquivalent<TransformOperation>(a.Rotate(), b.Rotate()); + return base::ValuesEquivalent<TransformOperation>(a.Rotate(), b.Rotate()); case CSSPropertyID::kScale: - return DataEquivalent<TransformOperation>(a.Scale(), b.Scale()); + return base::ValuesEquivalent<TransformOperation>(a.Scale(), b.Scale()); case CSSPropertyID::kTransformOrigin: return a.TransformOriginX() == b.TransformOriginX() && a.TransformOriginY() == b.TransformOriginY() && @@ -361,7 +365,7 @@ case CSSPropertyID::kWordSpacing: return a.WordSpacing() == b.WordSpacing(); case CSSPropertyID::kD: - return DataEquivalent(a.D(), b.D()); + return base::ValuesEquivalent(a.D(), b.D()); case CSSPropertyID::kCx: return a.Cx() == b.Cx(); case CSSPropertyID::kCy:
diff --git a/third_party/blink/renderer/core/css/css_property_value.cc b/third_party/blink/renderer/core/css/css_property_value.cc index bb4c818d..670b3bd0 100644 --- a/third_party/blink/renderer/core/css/css_property_value.cc +++ b/third_party/blink/renderer/core/css/css_property_value.cc
@@ -74,7 +74,7 @@ } bool CSSPropertyValue::operator==(const CSSPropertyValue& other) const { - return DataEquivalent(value_, other.value_) && + return base::ValuesEquivalent(value_, other.value_) && IsImportant() == other.IsImportant(); }
diff --git a/third_party/blink/renderer/core/css/css_quad_value.h b/third_party/blink/renderer/core/css/css_quad_value.h index 711b74b..39df17e 100644 --- a/third_party/blink/renderer/core/css/css_quad_value.h +++ b/third_party/blink/renderer/core/css/css_quad_value.h
@@ -62,10 +62,10 @@ String CustomCSSText() const; bool Equals(const CSSQuadValue& other) const { - return DataEquivalent(top_, other.top_) && - DataEquivalent(right_, other.right_) && - DataEquivalent(left_, other.left_) && - DataEquivalent(bottom_, other.bottom_); + return base::ValuesEquivalent(top_, other.top_) && + base::ValuesEquivalent(right_, other.right_) && + base::ValuesEquivalent(left_, other.left_) && + base::ValuesEquivalent(bottom_, other.bottom_); } void TraceAfterDispatch(blink::Visitor*) const;
diff --git a/third_party/blink/renderer/core/css/css_ratio_value.cc b/third_party/blink/renderer/core/css/css_ratio_value.cc index c3ea4e40..7ef3f19 100644 --- a/third_party/blink/renderer/core/css/css_ratio_value.cc +++ b/third_party/blink/renderer/core/css/css_ratio_value.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/css/css_ratio_value.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -22,8 +22,8 @@ } bool CSSRatioValue::Equals(const CSSRatioValue& other) const { - return DataEquivalent(first_, other.first_) && - DataEquivalent(second_, other.second_); + return base::ValuesEquivalent(first_, other.first_) && + base::ValuesEquivalent(second_, other.second_); } } // namespace cssvalue
diff --git a/third_party/blink/renderer/core/css/css_ray_value.cc b/third_party/blink/renderer/core/css/css_ray_value.cc index f07fc78..a03c2fb01 100644 --- a/third_party/blink/renderer/core/css/css_ray_value.cc +++ b/third_party/blink/renderer/core/css/css_ray_value.cc
@@ -31,9 +31,9 @@ } bool CSSRayValue::Equals(const CSSRayValue& other) const { - return DataEquivalent(angle_, other.angle_) && - DataEquivalent(size_, other.size_) && - DataEquivalent(contain_, other.contain_); + return base::ValuesEquivalent(angle_, other.angle_) && + base::ValuesEquivalent(size_, other.size_) && + base::ValuesEquivalent(contain_, other.contain_); } void CSSRayValue::TraceAfterDispatch(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/css_reflect_value.cc b/third_party/blink/renderer/core/css/css_reflect_value.cc index 4d92d42..3e4d5f6b 100644 --- a/third_party/blink/renderer/core/css/css_reflect_value.cc +++ b/third_party/blink/renderer/core/css/css_reflect_value.cc
@@ -40,8 +40,8 @@ bool CSSReflectValue::Equals(const CSSReflectValue& other) const { return direction_ == other.direction_ && - DataEquivalent(offset_, other.offset_) && - DataEquivalent(mask_, other.mask_); + base::ValuesEquivalent(offset_, other.offset_) && + base::ValuesEquivalent(mask_, other.mask_); } void CSSReflectValue::TraceAfterDispatch(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc index 2ceb47e..d79959d 100644 --- a/third_party/blink/renderer/core/css/css_selector.cc +++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -134,13 +134,13 @@ case kPseudoHost: if (!SelectorList()) return kClassLikeSpecificity; - FALLTHROUGH; + [[fallthrough]]; case kPseudoHostContext: DCHECK(SelectorList()->HasOneSelector()); return kClassLikeSpecificity + SelectorList()->First()->Specificity(); case kPseudoNot: DCHECK(SelectorList()); - FALLTHROUGH; + [[fallthrough]]; case kPseudoIs: return MaximumSpecificity(SelectorList()); case kPseudoHas: @@ -645,7 +645,7 @@ // but should be PseudoElement like double colon. if (match_ == kPseudoClass) match_ = kPseudoElement; - FALLTHROUGH; + [[fallthrough]]; // For pseudo elements case kPseudoBackdrop: case kPseudoCue: @@ -693,7 +693,7 @@ pseudo_type_ = kPseudoUnknown; break; } - FALLTHROUGH; + [[fallthrough]]; // For pseudo classes case kPseudoActive: case kPseudoAny:
diff --git a/third_party/blink/renderer/core/css/css_shadow_value.cc b/third_party/blink/renderer/core/css/css_shadow_value.cc index 0e25030f..dae6fae6 100644 --- a/third_party/blink/renderer/core/css/css_shadow_value.cc +++ b/third_party/blink/renderer/core/css/css_shadow_value.cc
@@ -71,10 +71,12 @@ } bool CSSShadowValue::Equals(const CSSShadowValue& other) const { - return DataEquivalent(color, other.color) && DataEquivalent(x, other.x) && - DataEquivalent(y, other.y) && DataEquivalent(blur, other.blur) && - DataEquivalent(spread, other.spread) && - DataEquivalent(style, other.style); + return base::ValuesEquivalent(color, other.color) && + base::ValuesEquivalent(x, other.x) && + base::ValuesEquivalent(y, other.y) && + base::ValuesEquivalent(blur, other.blur) && + base::ValuesEquivalent(spread, other.spread) && + base::ValuesEquivalent(style, other.style); } void CSSShadowValue::TraceAfterDispatch(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h index 95a7dca..5adf5392 100644 --- a/third_party/blink/renderer/core/css/css_value.h +++ b/third_party/blink/renderer/core/css/css_value.h
@@ -21,8 +21,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_H_ +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/custom_spaces.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -331,7 +331,7 @@ } for (wtf_size_t i = 0; i < size; i++) { - if (!DataEquivalent(first_vector[i], second_vector[i])) { + if (!base::ValuesEquivalent(first_vector[i], second_vector[i])) { return false; } }
diff --git a/third_party/blink/renderer/core/css/css_value_pair.h b/third_party/blink/renderer/core/css/css_value_pair.h index faa859c..77bf728 100644 --- a/third_party/blink/renderer/core/css/css_value_pair.h +++ b/third_party/blink/renderer/core/css/css_value_pair.h
@@ -59,8 +59,8 @@ } bool Equals(const CSSValuePair& other) const { - return DataEquivalent(first_, other.first_) && - DataEquivalent(second_, other.second_) && + return base::ValuesEquivalent(first_, other.first_) && + base::ValuesEquivalent(second_, other.second_) && identical_values_policy_ == other.identical_values_policy_; }
diff --git a/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc b/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc index ff65293..71b16c2 100644 --- a/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc +++ b/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/memory/values_equivalent.h" #include "base/synchronization/waitable_event.h" #include "base/task/single_thread_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" @@ -254,7 +255,7 @@ // Two null values are equal to each other. std::unique_ptr<CrossThreadStyleValue> null_value1(nullptr); std::unique_ptr<CrossThreadStyleValue> null_value2(nullptr); - EXPECT_TRUE(DataEquivalent(null_value1, null_value2)); + EXPECT_TRUE(base::ValuesEquivalent(null_value1, null_value2)); // If one argument is null and the other isn't they are never equal. std::unique_ptr<CrossThreadStyleValue> keyword_value( @@ -264,12 +265,12 @@ std::unique_ptr<CrossThreadStyleValue> unsupported_value( new CrossThreadUnsupportedValue("unsupported")); - EXPECT_FALSE(DataEquivalent(null_value1, keyword_value)); - EXPECT_FALSE(DataEquivalent(null_value1, unit_value)); - EXPECT_FALSE(DataEquivalent(null_value1, unsupported_value)); - EXPECT_FALSE(DataEquivalent(keyword_value, null_value1)); - EXPECT_FALSE(DataEquivalent(unit_value, null_value1)); - EXPECT_FALSE(DataEquivalent(unsupported_value, null_value1)); + EXPECT_FALSE(base::ValuesEquivalent(null_value1, keyword_value)); + EXPECT_FALSE(base::ValuesEquivalent(null_value1, unit_value)); + EXPECT_FALSE(base::ValuesEquivalent(null_value1, unsupported_value)); + EXPECT_FALSE(base::ValuesEquivalent(keyword_value, null_value1)); + EXPECT_FALSE(base::ValuesEquivalent(unit_value, null_value1)); + EXPECT_FALSE(base::ValuesEquivalent(unsupported_value, null_value1)); } TEST_F(CrossThreadStyleValueTest, ComparingDifferentTypes) { @@ -281,12 +282,12 @@ std::unique_ptr<CrossThreadStyleValue> unsupported_value( new CrossThreadUnsupportedValue("unsupported")); - EXPECT_FALSE(DataEquivalent(keyword_value, unit_value)); - EXPECT_FALSE(DataEquivalent(keyword_value, unsupported_value)); - EXPECT_FALSE(DataEquivalent(unit_value, unsupported_value)); - EXPECT_FALSE(DataEquivalent(unit_value, keyword_value)); - EXPECT_FALSE(DataEquivalent(unsupported_value, keyword_value)); - EXPECT_FALSE(DataEquivalent(unsupported_value, unit_value)); + EXPECT_FALSE(base::ValuesEquivalent(keyword_value, unit_value)); + EXPECT_FALSE(base::ValuesEquivalent(keyword_value, unsupported_value)); + EXPECT_FALSE(base::ValuesEquivalent(unit_value, unsupported_value)); + EXPECT_FALSE(base::ValuesEquivalent(unit_value, keyword_value)); + EXPECT_FALSE(base::ValuesEquivalent(unsupported_value, keyword_value)); + EXPECT_FALSE(base::ValuesEquivalent(unsupported_value, unit_value)); } TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadKeywordValue) { @@ -299,8 +300,8 @@ std::unique_ptr<CrossThreadStyleValue> keyword_value_3( new CrossThreadKeywordValue("different")); - EXPECT_TRUE(DataEquivalent(keyword_value_1, keyword_value_2)); - EXPECT_FALSE(DataEquivalent(keyword_value_1, keyword_value_3)); + EXPECT_TRUE(base::ValuesEquivalent(keyword_value_1, keyword_value_2)); + EXPECT_FALSE(base::ValuesEquivalent(keyword_value_1, keyword_value_3)); } TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnitValue) { @@ -312,17 +313,17 @@ // Same value, same unit. std::unique_ptr<CrossThreadStyleValue> unit_value_2( new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees)); - EXPECT_TRUE(DataEquivalent(unit_value_1, unit_value_2)); + EXPECT_TRUE(base::ValuesEquivalent(unit_value_1, unit_value_2)); // Same value, different unit. std::unique_ptr<CrossThreadStyleValue> unit_value_3( new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kPoints)); - EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_3)); + EXPECT_FALSE(base::ValuesEquivalent(unit_value_1, unit_value_3)); // Different value, same unit. std::unique_ptr<CrossThreadStyleValue> unit_value_4( new CrossThreadUnitValue(2, CSSPrimitiveValue::UnitType::kDegrees)); - EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_4)); + EXPECT_FALSE(base::ValuesEquivalent(unit_value_1, unit_value_4)); } TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadColorValue) { @@ -335,8 +336,8 @@ std::unique_ptr<CrossThreadStyleValue> color_value_3( new CrossThreadColorValue(Color(0, 255, 0))); - EXPECT_TRUE(DataEquivalent(color_value_1, color_value_2)); - EXPECT_FALSE(DataEquivalent(color_value_1, color_value_3)); + EXPECT_TRUE(base::ValuesEquivalent(color_value_1, color_value_2)); + EXPECT_FALSE(base::ValuesEquivalent(color_value_1, color_value_3)); } TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnsupportedValue) { @@ -349,8 +350,9 @@ std::unique_ptr<CrossThreadStyleValue> unsupported_value_3( new CrossThreadUnsupportedValue("different")); - EXPECT_TRUE(DataEquivalent(unsupported_value_1, unsupported_value_2)); - EXPECT_FALSE(DataEquivalent(unsupported_value_1, unsupported_value_3)); + EXPECT_TRUE(base::ValuesEquivalent(unsupported_value_1, unsupported_value_2)); + EXPECT_FALSE( + base::ValuesEquivalent(unsupported_value_1, unsupported_value_3)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc index 44ae896..613345f 100644 --- a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc +++ b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
@@ -92,7 +92,7 @@ if (identifier_value && identifier_value->GetValueID() == CSSValueID::kAuto) return CSSKeywordValue::Create("auto"); - FALLTHROUGH; + [[fallthrough]]; } case CSSPropertyID::kBackgroundColor: case CSSPropertyID::kBorderBottomColor: @@ -151,7 +151,7 @@ // offset-anchor and offset-position can be 'auto' if (value.IsIdentifierValue()) return CreateStyleValue(value); - FALLTHROUGH; + [[fallthrough]]; case CSSPropertyID::kObjectPosition: case CSSPropertyID::kPerspectiveOrigin: case CSSPropertyID::kTransformOrigin:
diff --git a/third_party/blink/renderer/core/css/has_argument_match_context.cc b/third_party/blink/renderer/core/css/has_argument_match_context.cc index 07c14bd..4bd9532 100644 --- a/third_party/blink/renderer/core/css/has_argument_match_context.cc +++ b/third_party/blink/renderer/core/css/has_argument_match_context.cc
@@ -69,7 +69,7 @@ switch (relation) { case CSSSelector::kRelativeDescendant: leftmost_relation_ = relation; - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kDescendant: descendant_traversal_depth_ = kInfiniteDepth; adjacent_traversal_distance_ = 0; @@ -77,7 +77,7 @@ case CSSSelector::kRelativeChild: leftmost_relation_ = relation; - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kChild: if (descendant_traversal_depth_ != kInfiniteDepth) { descendant_traversal_depth_++; @@ -87,7 +87,7 @@ case CSSSelector::kRelativeDirectAdjacent: leftmost_relation_ = relation; - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kDirectAdjacent: if (adjacent_traversal_distance_ != kInfiniteAdjacentDistance) adjacent_traversal_distance_++; @@ -95,7 +95,7 @@ case CSSSelector::kRelativeIndirectAdjacent: leftmost_relation_ = relation; - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kIndirectAdjacent: adjacent_traversal_distance_ = kInfiniteAdjacentDistance; break;
diff --git a/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc b/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc index 2d11858c..92d4924e 100644 --- a/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc +++ b/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
@@ -33,10 +33,10 @@ #include <memory> #include <utility> +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -82,10 +82,10 @@ const auto& other_sibling = To<SiblingInvalidationSet>(other); if ((this_sibling.MaxDirectAdjacentSelectors() != other_sibling.MaxDirectAdjacentSelectors()) || - !DataEquivalent(this_sibling.Descendants(), - other_sibling.Descendants()) || - !DataEquivalent(this_sibling.SiblingDescendants(), - other_sibling.SiblingDescendants())) { + !base::ValuesEquivalent(this_sibling.Descendants(), + other_sibling.Descendants()) || + !base::ValuesEquivalent(this_sibling.SiblingDescendants(), + other_sibling.SiblingDescendants())) { return false; } }
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc index 150c3b1a..618ca6be 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -494,7 +494,7 @@ stream.UncheckedConsume(); continue; } - FALLTHROUGH; + [[fallthrough]]; default: rule = ConsumeQualifiedRule(stream, allowed_rules); break;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_token.cc b/third_party/blink/renderer/core/css/parser/css_parser_token.cc index 8b67aad..e9777a95 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_token.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_token.cc
@@ -165,7 +165,7 @@ case kHashToken: if (hash_token_type_ != other.hash_token_type_) return false; - FALLTHROUGH; + [[fallthrough]]; case kIdentToken: case kFunctionToken: case kStringToken: @@ -174,7 +174,7 @@ case kDimensionToken: if (!ValueDataCharRawEqual(other)) return false; - FALLTHROUGH; + [[fallthrough]]; case kNumberToken: case kPercentageToken: return numeric_sign_ == other.numeric_sign_ &&
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc index 8f8074b..50b2b92 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -1032,7 +1032,7 @@ case kDelimiterToken: if (token.Delimiter() == '=') return CSSSelector::kAttributeExact; - FALLTHROUGH; + [[fallthrough]]; default: failed_parsing_ = true; return CSSSelector::kAttributeExact;
diff --git a/third_party/blink/renderer/core/css/parser/css_tokenizer_test.cc b/third_party/blink/renderer/core/css/parser/css_tokenizer_test.cc index 0a43c71f..d24998d 100644 --- a/third_party/blink/renderer/core/css/parser/css_tokenizer_test.cc +++ b/third_party/blink/renderer/core/css/parser/css_tokenizer_test.cc
@@ -38,7 +38,7 @@ break; case kNumberToken: ASSERT_EQ(expected.GetNumericSign(), actual.GetNumericSign()); - FALLTHROUGH; + [[fallthrough]]; case kPercentageToken: ASSERT_EQ(expected.GetNumericValueType(), actual.GetNumericValueType()); ASSERT_DOUBLE_EQ(expected.NumericValue(), actual.NumericValue());
diff --git a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc index 07d4132..e541c96 100644 --- a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc +++ b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc
@@ -186,7 +186,7 @@ if (token.FunctionId() != CSSValueID::kCalc) return false; // "calc(" is the same as "(" - FALLTHROUGH; + [[fallthrough]]; case kLeftParenthesisToken: // If the token is a left parenthesis, then push it onto the stack. stack.push_back(token); @@ -204,7 +204,7 @@ break; case kCommentToken: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case kCDOToken: case kCDCToken: case kAtKeywordToken:
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 92f7e65..ac3e471 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1052,15 +1052,15 @@ CSSValue* east_asian_value = ValueForFontVariantEastAsian(style); // FIXME: Use DataEquivalent<CSSValue>(...) once http://crbug.com/729447 is // resolved. - if (!DataEquivalent(ligatures_value, - static_cast<CSSValue*>( - CSSIdentifierValue::Create(CSSValueID::kNormal))) || - !DataEquivalent(numeric_value, - static_cast<CSSValue*>( - CSSIdentifierValue::Create(CSSValueID::kNormal))) || - !DataEquivalent(east_asian_value, - static_cast<CSSValue*>( - CSSIdentifierValue::Create(CSSValueID::kNormal)))) + if (!base::ValuesEquivalent(ligatures_value, + static_cast<CSSValue*>(CSSIdentifierValue::Create( + CSSValueID::kNormal))) || + !base::ValuesEquivalent(numeric_value, + static_cast<CSSValue*>(CSSIdentifierValue::Create( + CSSValueID::kNormal))) || + !base::ValuesEquivalent(east_asian_value, + static_cast<CSSValue*>(CSSIdentifierValue::Create( + CSSValueID::kNormal)))) return nullptr; if (!ValueForFontStretchAsKeyword(style)) @@ -2746,9 +2746,11 @@ if (!top_value || !right_value || !bottom_value || !left_value) return nullptr; - bool show_left = !DataEquivalent(right_value, left_value); - bool show_bottom = !DataEquivalent(top_value, bottom_value) || show_left; - bool show_right = !DataEquivalent(top_value, right_value) || show_bottom; + bool show_left = !base::ValuesEquivalent(right_value, left_value); + bool show_bottom = + !base::ValuesEquivalent(top_value, bottom_value) || show_left; + bool show_right = + !base::ValuesEquivalent(top_value, right_value) || show_bottom; list->Append(*top_value); if (show_right)
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index 02a7b24a..669cfad 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -821,7 +821,7 @@ case CSSPrimitiveValue::UnitType::kQuirkyEms: if (context.Mode() != kUASheetMode) return nullptr; - FALLTHROUGH; + [[fallthrough]]; case CSSPrimitiveValue::UnitType::kEms: case CSSPrimitiveValue::UnitType::kRems: case CSSPrimitiveValue::UnitType::kChs: @@ -2509,7 +2509,7 @@ "standardized. It will be removed in the future.")); } } - FALLTHROUGH; + [[fallthrough]]; // This function distinguishes 'appearance' and '-webkit-appearance' // though other property aliases are handles as their aliased properties. // See Appearance::ParseSingleValue().
diff --git a/third_party/blink/renderer/core/css/properties/css_property_test.cc b/third_party/blink/renderer/core/css/properties/css_property_test.cc index 66d7dd0..3018c112 100644 --- a/third_party/blink/renderer/core/css/properties/css_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/css/properties/css_property.h" +#include "base/memory/values_equivalent.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_test_helpers.h" @@ -14,7 +15,6 @@ #include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" namespace blink { @@ -107,7 +107,8 @@ GetDocument(), *visited, initial_value->CssText()); // The properties should have identical parsing behavior. - EXPECT_TRUE(DataEquivalent(parsed_regular_value, parsed_visited_value)); + EXPECT_TRUE( + base::ValuesEquivalent(parsed_regular_value, parsed_visited_value)); num_visited++; }
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 98becd7..2cadb6ab 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -1533,6 +1533,7 @@ void Color::ApplyInitial(StyleResolverState& state) const { state.Style()->SetColor(state.Style()->InitialColorForColorScheme()); + state.Style()->SetColorIsInherited(false); } void Color::ApplyInherit(StyleResolverState& state) const { @@ -1543,6 +1544,7 @@ } else { style->SetColor(state.ParentStyle()->GetColor()); } + style->SetColorIsInherited(true); } void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const { @@ -1556,10 +1558,11 @@ if (value.IsInitialColorValue()) { DCHECK_EQ(state.GetElement(), state.GetDocument().documentElement()); state.Style()->SetColor(state.Style()->InitialColorForColorScheme()); - return; + } else { + state.Style()->SetColor( + StyleBuilderConverter::ConvertStyleColor(state, value)); } - state.Style()->SetColor( - StyleBuilderConverter::ConvertStyleColor(state, value)); + state.Style()->SetColorIsInherited(false); } const CSSValue* ColorInterpolation::CSSValueFromComputedStyleInternal( @@ -2203,7 +2206,7 @@ switch (item_identifier_value->GetValueID()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSValueID::kOpenQuote: quote_type = QuoteType::kOpen; break; @@ -8315,7 +8318,7 @@ style.TextEmphasisCustomMark()); case TextEmphasisMark::kAuto: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case TextEmphasisMark::kDot: case TextEmphasisMark::kCircle: case TextEmphasisMark::kDoubleCircle:
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc index 2fac9cd5..337b64ed 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/cxx17_backports.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_content_distribution_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" @@ -308,7 +309,7 @@ const CSSValue* value_end = GetCSSPropertyBorderBlockEnd().CSSValueFromComputedStyle( style, layout_object, allow_visited_style); - if (!DataEquivalent(value_start, value_end)) { + if (!base::ValuesEquivalent(value_start, value_end)) { return nullptr; } return value_start; @@ -446,7 +447,7 @@ for (size_t i = 0; i < base::size(kProperties); ++i) { const CSSValue* value_for_side = kProperties[i]->CSSValueFromComputedStyle( style, layout_object, allow_visited_style); - if (!DataEquivalent(value, value_for_side)) { + if (!base::ValuesEquivalent(value, value_for_side)) { return nullptr; } } @@ -569,7 +570,7 @@ const CSSValue* value_end = GetCSSPropertyBorderInlineEnd().CSSValueFromComputedStyle( style, layout_object, allow_visited_style); - if (!DataEquivalent(value_start, value_end)) { + if (!base::ValuesEquivalent(value_start, value_end)) { return nullptr; } return value_start; @@ -3078,6 +3079,14 @@ textEmphasisShorthand(), important, context, range, properties); } +const CSSValue* TextEmphasis::CSSValueFromComputedStyleInternal( + const ComputedStyle& style, + const LayoutObject* layout_object, + bool allow_visited_style) const { + return ComputedStyleUtils::ValuesForShorthandProperty( + textEmphasisShorthand(), style, layout_object, allow_visited_style); +} + bool WebkitTextStroke::ParseShorthand( bool important, CSSParserTokenRange& range,
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.cc b/third_party/blink/renderer/core/css/resolver/font_builder.cc index 6e8f039..20c4441 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder.cc
@@ -84,7 +84,7 @@ switch (generic_family) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case FontDescription::kNoFamily: return AtomicString(); case FontDescription::kStandardFamily:
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 2c82f8de..ef99edb6 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1532,7 +1532,7 @@ switch (value_id) { case CSSValueID::kInvalid: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSValueID::kInternalQuirkInherit: case CSSValueID::kWebkitLink: case CSSValueID::kWebkitActivelink:
diff --git a/third_party/blink/renderer/core/css/resolver/transform_builder.cc b/third_party/blink/renderer/core/css/resolver/transform_builder.cc index 10c9a3a..fe1b90d 100644 --- a/third_party/blink/renderer/core/css/resolver/transform_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/transform_builder.cc
@@ -58,7 +58,7 @@ switch (type) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case CSSValueID::kScale: return TransformOperation::kScale; case CSSValueID::kScaleX:
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc index 88c67a2..1782339f 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -33,6 +33,7 @@ #include <algorithm> #include <bitset> #include "base/auto_reset.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" @@ -45,7 +46,6 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -272,7 +272,7 @@ auto it = b.find(entry.key); if (it == b.end()) return false; - if (!DataEquivalent(entry.value, it->value)) + if (!base::ValuesEquivalent(entry.value, it->value)) return false; } return true; @@ -429,13 +429,14 @@ other.attribute_invalidation_sets_) && InvalidationSetMapsEqual<CSSSelector::PseudoType>( pseudo_invalidation_sets_, other.pseudo_invalidation_sets_) && - DataEquivalent(universal_sibling_invalidation_set_, - other.universal_sibling_invalidation_set_) && - DataEquivalent(nth_invalidation_set_, other.nth_invalidation_set_) && - DataEquivalent(universal_sibling_invalidation_set_, - other.universal_sibling_invalidation_set_) && - DataEquivalent(type_rule_invalidation_set_, - other.type_rule_invalidation_set_) && + base::ValuesEquivalent(universal_sibling_invalidation_set_, + other.universal_sibling_invalidation_set_) && + base::ValuesEquivalent(nth_invalidation_set_, + other.nth_invalidation_set_) && + base::ValuesEquivalent(universal_sibling_invalidation_set_, + other.universal_sibling_invalidation_set_) && + base::ValuesEquivalent(type_rule_invalidation_set_, + other.type_rule_invalidation_set_) && viewport_dependent_media_query_results_ == other.viewport_dependent_media_query_results_ && device_dependent_media_query_results_ == @@ -1148,7 +1149,7 @@ return kSelectorNeverMatches; } found_host_pseudo = true; - FALLTHROUGH; + [[fallthrough]]; default: if (const CSSSelectorList* selector_list = current->SelectorList()) { for (const CSSSelector* sub_selector = selector_list->First();
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index d6af836..7b46258f 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -319,7 +319,7 @@ case CSSSelector::kRelativeDescendant: DCHECK(result.has_argument_leftmost_compound_matches); result.has_argument_leftmost_compound_matches->push_back(context.element); - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kDescendant: if (next_context.selector->GetPseudoType() == CSSSelector::kPseudoScope) { if (next_context.selector->IsLastInTagHistory()) { @@ -342,7 +342,7 @@ case CSSSelector::kRelativeChild: DCHECK(result.has_argument_leftmost_compound_matches); result.has_argument_leftmost_compound_matches->push_back(context.element); - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kChild: { if (next_context.selector->GetPseudoType() == CSSSelector::kPseudoScope) { if (next_context.selector->IsLastInTagHistory()) { @@ -360,7 +360,7 @@ case CSSSelector::kRelativeDirectAdjacent: DCHECK(result.has_argument_leftmost_compound_matches); result.has_argument_leftmost_compound_matches->push_back(context.element); - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kDirectAdjacent: if (mode_ == kResolvingStyle) { if (ContainerNode* parent = @@ -375,7 +375,7 @@ case CSSSelector::kRelativeIndirectAdjacent: DCHECK(result.has_argument_leftmost_compound_matches); result.has_argument_leftmost_compound_matches->push_back(context.element); - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kIndirectAdjacent: if (mode_ == kResolvingStyle) { if (ContainerNode* parent = @@ -1257,7 +1257,7 @@ mode_ == kQueryingRules ? WebFeature::kCSSSelectorHostContextInSnapshotProfile : WebFeature::kCSSSelectorHostContextInLiveProfile); - FALLTHROUGH; + [[fallthrough]]; case CSSSelector::kPseudoHost: return CheckPseudoHost(context, result); case CSSSelector::kPseudoSpatialNavigationFocus: @@ -1432,7 +1432,7 @@ UseCounter::Count(context.element->GetDocument(), WebFeature::kCSSSelectorTargetText); } - FALLTHROUGH; + [[fallthrough]]; default: DCHECK_NE(mode_, kQueryingRules); result.dynamic_pseudo =
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc index 9a46e76..f73f4fd 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -26,6 +26,7 @@ #include <bitset> #include "base/cxx17_backports.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/animation/css/css_animation_data.h" #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" @@ -387,7 +388,7 @@ longhands[0]->IsPendingSubstitutionValue()) { bool success = true; for (int i = 1; i < longhand_count; i++) { - if (!DataEquivalent(longhands[i], longhands[0])) { + if (!base::ValuesEquivalent(longhands[i], longhands[0])) { // This should just return emptyString but some shorthands currently // allow 'initial' for their longhands. success = false; @@ -779,7 +780,7 @@ DynamicTo<cssvalue::CSSPendingSystemFontValue>(first)) { for (unsigned i = 1; i < length; i++) { const CSSValue* value = property_set_.GetPropertyCSSValue(*longhands[i]); - if (!DataEquivalent(first, value)) + if (!base::ValuesEquivalent(first, value)) return g_empty_string; } return getValueName(system_font->SystemFontId()); @@ -987,7 +988,7 @@ property_set_.PropertyAt(start_value_index); PropertyValueForSerializer end = property_set_.PropertyAt(end_value_index); - bool show_end = !DataEquivalent(start.Value(), end.Value()); + bool show_end = !base::ValuesEquivalent(start.Value(), end.Value()); StringBuilder result; result.Append(start.Value()->CssText()); @@ -1021,9 +1022,11 @@ property_set_.PropertyAt(bottom_value_index); PropertyValueForSerializer left = property_set_.PropertyAt(left_value_index); - bool show_left = !DataEquivalent(right.Value(), left.Value()); - bool show_bottom = !DataEquivalent(top.Value(), bottom.Value()) || show_left; - bool show_right = !DataEquivalent(top.Value(), right.Value()) || show_bottom; + bool show_left = !base::ValuesEquivalent(right.Value(), left.Value()); + bool show_bottom = + !base::ValuesEquivalent(top.Value(), bottom.Value()) || show_left; + bool show_right = + !base::ValuesEquivalent(top.Value(), right.Value()) || show_bottom; StringBuilder result; result.Append(top.Value()->CssText());
diff --git a/third_party/blink/renderer/core/css/style_recalc_change.cc b/third_party/blink/renderer/core/css/style_recalc_change.cc index 3200a6f..cf608ec6 100644 --- a/third_party/blink/renderer/core/css/style_recalc_change.cc +++ b/third_party/blink/renderer/core/css/style_recalc_change.cc
@@ -125,7 +125,7 @@ // changes, we will enter another container query recalc for this subtree // from layout. const ComputedStyle* old_style = element.GetComputedStyle(); - if (old_style && old_style->IsContainerForContainerQueries()) + if (old_style && old_style->IsContainerForContainerQueries(element)) result &= ~kRecalcContainer; }
diff --git a/third_party/blink/renderer/core/css/style_rule_counter_style.cc b/third_party/blink/renderer/core/css/style_rule_counter_style.cc index e7a0561..58585bb 100644 --- a/third_party/blink/renderer/core/css/style_rule_counter_style.cc +++ b/third_party/blink/renderer/core/css/style_rule_counter_style.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/css/style_rule_counter_style.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/cascade_layer.h" #include "third_party/blink/renderer/core/css/counter_style.h" #include "third_party/blink/renderer/core/css/css_counter_style_rule.h" @@ -100,7 +101,7 @@ const CSSValue* new_value) { Member<const CSSValue>& original_value = GetDescriptorReference(descriptor_id); - if (DataEquivalent(original_value.Get(), new_value)) + if (base::ValuesEquivalent(original_value.Get(), new_value)) return false; switch (descriptor_id) {
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index e354908..10227b4 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1997,7 +1997,7 @@ (allow_dirty_container_subtrees && element->GetLayoutObject() && element->GetLayoutObject() ->StyleRef() - .IsContainerForContainerQueries())) { + .IsContainerForContainerQueries(*element))) { node = FlatTreeTraversal::NextSkippingChildren(*node); continue; } @@ -5896,7 +5896,7 @@ break; case mojom::blink::PermissionStatus::DENIED: document->expressly_denied_storage_access_ = true; - FALLTHROUGH; + [[fallthrough]]; case mojom::blink::PermissionStatus::ASK: default: FireRequestStorageAccessHistogram( @@ -7239,15 +7239,14 @@ return node; } -void Document::AdjustFloatQuadsForScrollAndAbsoluteZoom( - Vector<FloatQuad>& quads, +void Document::AdjustQuadsForScrollAndAbsoluteZoom( + Vector<gfx::QuadF>& quads, const LayoutObject& layout_object) const { if (!View()) return; - for (wtf_size_t i = 0; i < quads.size(); ++i) { - AdjustForAbsoluteZoom::AdjustFloatQuad(quads[i], layout_object); - } + for (auto& quad : quads) + AdjustForAbsoluteZoom::AdjustQuad(quad, layout_object); } void Document::AdjustRectForScrollAndAbsoluteZoom(
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index b36bfbf..796f548 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -86,6 +86,7 @@ } namespace gfx { +class QuadF; class RectF; } @@ -148,7 +149,6 @@ template <typename EventType> class EventWithHitTestResults; class ExceptionState; -class FloatQuad; class FontMatchingMetrics; class FormController; class FrameCallback; @@ -1396,8 +1396,8 @@ const ElementRegistrationOptions*, ExceptionState&); - void AdjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>&, - const LayoutObject&) const; + void AdjustQuadsForScrollAndAbsoluteZoom(Vector<gfx::QuadF>&, + const LayoutObject&) const; void AdjustRectForScrollAndAbsoluteZoom(gfx::RectF&, const LayoutObject&) const;
diff --git a/third_party/blink/renderer/core/dom/document_init.cc b/third_party/blink/renderer/core/dom/document_init.cc index 463e3e5e7..4155bfc2 100644 --- a/third_party/blink/renderer/core/dom/document_init.cc +++ b/third_party/blink/renderer/core/dom/document_init.cc
@@ -282,7 +282,7 @@ case Type::kText: return MakeGarbageCollected<TextDocument>(*this); case Type::kUnspecified: - FALLTHROUGH; + [[fallthrough]]; default: break; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 18936bd4..c5ca775 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1999,7 +1999,7 @@ if (!view) return gfx::Rect(); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; // TODO(pdr): Unify the quad/bounds code with Element::ClientQuads. @@ -2014,7 +2014,7 @@ // TODO(pdr): This should include stroke. if (IsA<SVGGraphicsElement>(svg_element)) { quads.push_back(GetLayoutObject()->LocalToAbsoluteQuad( - FloatQuad(GetLayoutObject()->ObjectBoundingBox()))); + gfx::QuadF(GetLayoutObject()->ObjectBoundingBox()))); } } else { // Get the bounding rectangle from the box model. @@ -2025,11 +2025,11 @@ if (quads.IsEmpty()) return gfx::Rect(); - gfx::Rect result = quads[0].EnclosingBoundingBox(); - for (wtf_size_t i = 1; i < quads.size(); ++i) - result.Union(quads[i].EnclosingBoundingBox()); + gfx::RectF result; + for (auto& quad : quads) + result.Union(quad.BoundingBox()); - return view->FrameToViewport(result); + return view->FrameToViewport(gfx::ToEnclosingRect(result)); } Vector<gfx::Rect> Element::OutlineRectsInVisualViewport( @@ -2107,7 +2107,7 @@ return visible_rect; } -void Element::ClientQuads(Vector<FloatQuad>& quads) const { +void Element::ClientQuads(Vector<gfx::QuadF>& quads) const { LayoutObject* element_layout_object = GetLayoutObject(); if (!element_layout_object) return; @@ -2125,7 +2125,7 @@ // If stroke is desired, we can update this to use AbsoluteQuads, below. if (IsA<SVGGraphicsElement>(svg_element)) { quads.push_back(element_layout_object->LocalToAbsoluteQuad( - FloatQuad(element_layout_object->ObjectBoundingBox()))); + gfx::QuadF(element_layout_object->ObjectBoundingBox()))); } return; } @@ -2139,27 +2139,27 @@ DOMRectList* Element::getClientRects() { GetDocument().EnsurePaintLocationDataValidForNode( this, DocumentUpdateReason::kJavaScript); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; ClientQuads(quads); if (quads.IsEmpty()) return MakeGarbageCollected<DOMRectList>(); LayoutObject* element_layout_object = GetLayoutObject(); DCHECK(element_layout_object); - GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom( - quads, *element_layout_object); + GetDocument().AdjustQuadsForScrollAndAbsoluteZoom(quads, + *element_layout_object); return MakeGarbageCollected<DOMRectList>(quads); } gfx::RectF Element::GetBoundingClientRectNoLifecycleUpdate() const { - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; ClientQuads(quads); if (quads.IsEmpty()) return gfx::RectF(); - gfx::RectF result = quads[0].BoundingBox(); - for (wtf_size_t i = 1; i < quads.size(); ++i) - result.Union(quads[i].BoundingBox()); + gfx::RectF result; + for (auto& quad : quads) + result.Union(quad.BoundingBox()); LayoutObject* element_layout_object = GetLayoutObject(); DCHECK(element_layout_object); @@ -2340,13 +2340,6 @@ setAttribute(name, AtomicString(string)); } -static inline AtomicString MakeIdForStyleResolution(const AtomicString& value, - bool in_quirks_mode) { - if (in_quirks_mode) - return value.LowerASCII(); - return value; -} - DISABLE_CFI_PERF void Element::AttributeChanged(const AttributeModificationParams& params) { const QualifiedName& name = params.name; @@ -2362,8 +2355,10 @@ params.new_value); if (name == html_names::kIdAttr) { - AtomicString new_id = MakeIdForStyleResolution( - params.new_value, GetDocument().InQuirksMode()); + AtomicString lowercase_id; + if (GetDocument().InQuirksMode() && !params.new_value.IsLowerASCII()) + lowercase_id = params.new_value.LowerASCII(); + const AtomicString& new_id = lowercase_id ? lowercase_id : params.new_value; if (new_id != GetElementData()->IdForStyleResolution()) { AtomicString old_id = GetElementData()->SetIdForStyleResolution(new_id); GetDocument().GetStyleEngine().IdChangedForElement(old_id, new_id, *this); @@ -2895,7 +2890,7 @@ DCHECK(ChildNeedsReattachLayoutTree()); DCHECK(!GetShadowRoot()); DCHECK(GetLayoutObject()); - DCHECK(GetLayoutObject()->StyleRef().IsContainerForContainerQueries()); + DCHECK(GetLayoutObject()->StyleRef().IsContainerForContainerQueries(*this)); constexpr bool performing_reattach = true; @@ -3109,7 +3104,7 @@ if (RuntimeEnabledFeatures::CSSContainerQueriesEnabled()) { if (const ComputedStyle* style = GetComputedStyle()) { - if (style->IsContainerForContainerQueries()) { + if (style->IsContainerForContainerQueries(*this)) { if (RuntimeEnabledFeatures::CSSContainerSkipStyleRecalcEnabled()) { if (change.IsSuppressed()) { // IsSuppressed() means we are at the root of a container subtree @@ -3197,7 +3192,7 @@ Element& element, const ComputedStyle* old_style, const ComputedStyle& new_style) { - if (!new_style.IsContainerForContainerQueries()) + if (!new_style.IsContainerForContainerQueries(element)) return nullptr; // If we're switching to display:contents, any existing results cached on // ContainerQueryEvaluator are no longer valid, since any style recalc @@ -4803,13 +4798,7 @@ needs_reattach = true; } } - // Even if we also previously forced legacy layout, we may need to introduce - // forced legacy layout in the ancestry, e.g. if this element no longer - // establishes a new formatting context. - if (ForceLegacyLayoutInFormattingContext(new_style)) - needs_reattach = true; - - // If we're inside an NG fragmentation context, we also need the entire + // If we're inside an NG fragmentation context, we need the entire // fragmentation context to fall back to legacy layout. Note that once this // has happened, the fragmentation context will be locked to legacy layout, // even if all the reasons for requiring it in the first place disappear @@ -4818,6 +4807,12 @@ if (new_style.InsideFragmentationContextWithNondeterministicEngine()) { if (ForceLegacyLayoutInFragmentationContext(new_style)) needs_reattach = true; + } else { + // Note that even if we also previously forced legacy layout, we may need + // to introduce forced legacy layout in the ancestry, e.g. if this element + // no longer establishes a new formatting context. + if (ForceLegacyLayoutInFormattingContext(new_style)) + needs_reattach = true; } } else if (old_force) { // TODO(mstensho): If we have ancestors that got legacy layout just because @@ -4858,7 +4853,7 @@ // CSSContainerQueries rely on LayoutNG being fully shipped before shipping. // In the meantime, make sure we do not mark containers for re-attachment // since we might be in the process of laying out the container. - if (style->IsContainerForContainerQueries()) + if (style->IsContainerForContainerQueries(*this)) break; found_fc = DefinitelyNewFormattingContext(*ancestor, *style); @@ -4882,43 +4877,35 @@ // block of the table is on the outside of the fragmentation context, we're // still going to fall back to legacy. - bool found_outer_relevant_fragmentation_context = false; Element* parent; - for (Element* walker = this; walker; walker = parent) { - parent = DynamicTo<Element>(LayoutTreeBuilderTraversal::Parent(*walker)); - if (walker->ShouldForceLegacyLayoutForChild()) + Element* legacy_root; + for (legacy_root = this;; legacy_root = parent) { + parent = + DynamicTo<Element>(LayoutTreeBuilderTraversal::Parent(*legacy_root)); + if (legacy_root->ShouldForceLegacyLayoutForChild()) return false; - if (parent && !parent->GetComputedStyle() - ->InsideFragmentationContextWithNondeterministicEngine()) - found_outer_relevant_fragmentation_context = true; - - // When we have found the outermost fragmentation context candidate, we need - // to make sure to keep walking all the way up to the element that we can - // tell for sure will establish a new formatting context. - // - // E.g. <span style="columns:1;"> will trigger legacy layout fallback (false - // positive). When this happens, we need to walk all the way up to the - // ancestor that establishes a formatting context, and this is the subtree - // that will force legacy layout. - if (found_outer_relevant_fragmentation_context && - DefinitelyNewFormattingContext(*walker, *walker->GetComputedStyle())) { - walker->SetShouldForceLegacyLayoutForChild(true); - walker->SetNeedsReattachLayoutTree(); - return true; - } + if (!parent || + !parent->GetComputedStyle() + ->InsideFragmentationContextWithNondeterministicEngine()) + break; } - if (GetDocument().Printing()) { - // Force legacy layout on the entire document, since we're printing, and - // there's some fragmentable box that needs legacy layout inside somewhere. - Element* root = GetDocument().documentElement(); - root->SetShouldForceLegacyLayoutForChild(true); - root->SetNeedsReattachLayoutTree(); - return true; - } + legacy_root->SetShouldForceLegacyLayoutForChild(true); + legacy_root->SetNeedsReattachLayoutTree(); - return false; + // When we have found the outermost fragmentation context candidate, we need + // to make sure to mark for legacy all the way up to the element that we can + // tell for sure will establish a new formatting context. + // + // E.g. <span style="columns:1;"> will trigger legacy layout fallback (false + // positive). When this happens, we need to walk all the way up to the + // ancestor that establishes a formatting context, and this is the subtree + // that will force legacy layout. + legacy_root->ForceLegacyLayoutInFormattingContext( + *legacy_root->GetComputedStyle()); + + return true; } bool Element::IsFocusedElementInDocument() const { @@ -5461,7 +5448,7 @@ ancestors.pop_back(); const ComputedStyle* style = ancestor->EnsureOwnComputedStyle(style_recalc_context, kPseudoIdNone); - if (style->IsContainerForContainerQueries()) + if (style->IsContainerForContainerQueries(*this)) style_recalc_context.container = ancestor; } @@ -5532,7 +5519,7 @@ StyleRecalcContext child_recalc_context = style_recalc_context; if (RuntimeEnabledFeatures::CSSContainerQueriesEnabled() && - element_style->IsContainerForContainerQueries()) { + element_style->IsContainerForContainerQueries(*this)) { child_recalc_context.container = this; }
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 8dd7ed65..5984063e 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -53,6 +53,7 @@ #include "ui/gfx/geometry/rect_f.h" namespace gfx { +class QuadF; class Vector2dF; } @@ -79,7 +80,6 @@ class ElementIntersectionObserverData; class ElementRareData; class ExceptionState; -class FloatQuad; class FocusOptions; class GetInnerHTMLOptions; class HTMLFieldSetElement; @@ -1259,7 +1259,7 @@ const AtomicString& new_id); void UpdateName(const AtomicString& old_name, const AtomicString& new_name); - void ClientQuads(Vector<FloatQuad>& quads) const; + void ClientQuads(Vector<gfx::QuadF>& quads) const; NodeType getNodeType() const final; bool ChildTypeAllowed(NodeType) const final;
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc b/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc index e0e0433..a1ac9bf 100644 --- a/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc +++ b/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc
@@ -83,11 +83,11 @@ case kPseudoIdMarker: if (Node* next = parent_element->GetPseudoElement(kPseudoIdBefore)) return next; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdBefore: if (Node* next = FlatTreeTraversal::FirstChild(*parent_element)) return next; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdNone: if (pseudo_id == kPseudoIdNone) { // Not falling through if (Node* next = FlatTreeTraversal::NextSibling(node)) @@ -98,7 +98,7 @@ } if (Node* next = parent_element->GetPseudoElement(kPseudoIdAfter)) return next; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdAfter: return nullptr; default: @@ -118,7 +118,7 @@ case kPseudoIdAfter: if (Node* previous = FlatTreeTraversal::LastChild(*parent_element)) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdNone: if (pseudo_id == kPseudoIdNone) { // Not falling through if (Node* previous = FlatTreeTraversal::PreviousSibling(node)) @@ -129,11 +129,11 @@ } if (Node* previous = parent_element->GetPseudoElement(kPseudoIdBefore)) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdBefore: if (Node* previous = parent_element->GetPseudoElement(kPseudoIdMarker)) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdMarker: return nullptr; default:
diff --git a/third_party/blink/renderer/core/dom/names_map.cc b/third_party/blink/renderer/core/dom/names_map.cc index bfe980c..58697de8 100644 --- a/third_party/blink/renderer/core/dom/names_map.cc +++ b/third_party/blink/renderer/core/dom/names_map.cc
@@ -214,7 +214,7 @@ case kKey: // The string ends with a key. key = AtomicString(characters + start, cur - start); - FALLTHROUGH; + [[fallthrough]]; case kPostKey: // The string ends with a key. Add(key, key); @@ -224,7 +224,7 @@ case kValue: // The string ends with a value. value = AtomicString(characters + start, cur - start); - FALLTHROUGH; + [[fallthrough]]; case kPostValue: Add(key, value); break;
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index cc8937c..07b1e53 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -391,15 +391,15 @@ case kPseudoIdAfter: if (Node* previous = parent->lastChild()) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdNone: if (Node* previous = parent->GetPseudoElement(kPseudoIdBefore)) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdBefore: if (Node* previous = parent->GetPseudoElement(kPseudoIdMarker)) return previous; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdMarker: break; default: @@ -416,15 +416,15 @@ case kPseudoIdMarker: if (Node* next = parent->GetPseudoElement(kPseudoIdBefore)) return next; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdBefore: if (parent->HasChildren()) return parent->firstChild(); - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdNone: if (Node* next = parent->GetPseudoElement(kPseudoIdAfter)) return next; - FALLTHROUGH; + [[fallthrough]]; case kPseudoIdAfter: break; default:
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc index 7aa4a2f..57af05f 100644 --- a/third_party/blink/renderer/core/dom/range.cc +++ b/third_party/blink/renderer/core/dom/range.cc
@@ -59,9 +59,9 @@ #include "third_party/blink/renderer/core/svg/svg_svg_element.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -1595,7 +1595,7 @@ this, DisplayLockContext::ForcedPhase::kLayout); owner_document_->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; GetBorderAndTextQuads(quads); return MakeGarbageCollected<DOMRectList>(quads); @@ -1606,22 +1606,22 @@ } // TODO(editing-dev): We should make -// |Document::AdjustFloatQuadsForScrollAndAbsoluteZoom()| as const function +// |Document::AdjustQuadsForScrollAndAbsoluteZoom()| as const function // and takes |const LayoutObject&|. -static Vector<FloatQuad> ComputeTextQuads(const Document& owner_document, - const LayoutText& layout_text, - unsigned start_offset, - unsigned end_offset) { - Vector<FloatQuad> text_quads; +static Vector<gfx::QuadF> ComputeTextQuads(const Document& owner_document, + const LayoutText& layout_text, + unsigned start_offset, + unsigned end_offset) { + Vector<gfx::QuadF> text_quads; layout_text.AbsoluteQuadsForRange(text_quads, start_offset, end_offset); const_cast<Document&>(owner_document) - .AdjustFloatQuadsForScrollAndAbsoluteZoom( + .AdjustQuadsForScrollAndAbsoluteZoom( text_quads, const_cast<LayoutText&>(layout_text)); return text_quads; } // https://www.w3.org/TR/cssom-view-1/#dom-range-getclientrects -void Range::GetBorderAndTextQuads(Vector<FloatQuad>& quads) const { +void Range::GetBorderAndTextQuads(Vector<gfx::QuadF>& quads) const { Node* start_container = &start_.Container(); Node* end_container = &end_.Container(); Node* stop_node = PastLastNode(); @@ -1651,10 +1651,10 @@ LayoutObject* const layout_object = element_node->GetLayoutObject(); if (!layout_object) continue; - Vector<FloatQuad> element_quads; + Vector<gfx::QuadF> element_quads; layout_object->AbsoluteQuads(element_quads); - owner_document_->AdjustFloatQuadsForScrollAndAbsoluteZoom(element_quads, - *layout_object); + owner_document_->AdjustQuadsForScrollAndAbsoluteZoom(element_quads, + *layout_object); quads.AppendVector(element_quads); continue; @@ -1724,11 +1724,11 @@ } owner_document_->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; GetBorderAndTextQuads(quads); gfx::RectF result; - for (const FloatQuad& quad : quads) + for (const gfx::QuadF& quad : quads) result.Union(quad.BoundingBox()); // Skips empty rects. // If all rects are empty, return the first rect.
diff --git a/third_party/blink/renderer/core/dom/range.h b/third_party/blink/renderer/core/dom/range.h index ec43e81e..86d1068 100644 --- a/third_party/blink/renderer/core/dom/range.h +++ b/third_party/blink/renderer/core/dom/range.h
@@ -37,6 +37,10 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" +namespace gfx { +class QuadF; +} + namespace blink { class DOMRect; @@ -45,7 +49,6 @@ class Document; class DocumentFragment; class ExceptionState; -class FloatQuad; class Node; class NodeWithIndex; class Text; @@ -139,7 +142,7 @@ gfx::Rect BoundingBox() const; // Transform-friendly - void GetBorderAndTextQuads(Vector<FloatQuad>&) const; + void GetBorderAndTextQuads(Vector<gfx::QuadF>&) const; gfx::RectF BoundingRect() const; void NodeChildrenWillBeRemoved(ContainerNode&);
diff --git a/third_party/blink/renderer/core/dom/range_test.cc b/third_party/blink/renderer/core/dom/range_test.cc index 4010e1ba..128cd66a 100644 --- a/third_party/blink/renderer/core/dom/range_test.cc +++ b/third_party/blink/renderer/core/dom/range_test.cc
@@ -26,11 +26,12 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace blink { @@ -325,27 +326,27 @@ Node* bar = GetDocument().QuerySelector("u")->lastChild(); auto* range = MakeGarbageCollected<Range>(GetDocument(), foo, 2, bar, 2); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; range->GetBorderAndTextQuads(quads); // Should get one quad for "o ", <input> and " b", respectively. ASSERT_EQ(3u, quads.size()); } -static Vector<FloatQuad> GetBorderAndTextQuads(const Position& start, - const Position& end) { +static Vector<gfx::QuadF> GetBorderAndTextQuads(const Position& start, + const Position& end) { DCHECK_LE(start, end); auto* const range = MakeGarbageCollected<Range>(*start.GetDocument(), start, end); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; range->GetBorderAndTextQuads(quads); return quads; } -static Vector<gfx::Size> ComputeSizesOfQuads(const Vector<FloatQuad>& quads) { +static Vector<gfx::Size> ComputeSizesOfQuads(const Vector<gfx::QuadF>& quads) { Vector<gfx::Size> sizes; for (const auto& quad : quads) - sizes.push_back(quad.EnclosingBoundingBox().size()); + sizes.push_back(gfx::ToEnclosingRect(quad.BoundingBox()).size()); return sizes; } @@ -368,22 +369,22 @@ const Text& text4 = *To<Text>(GetElementById("c4")->firstChild()); EXPECT_THAT(GetBorderAndTextQuads(Position(text1, 0), Position(text1, 1)), - ElementsAre(FloatQuad(gfx::RectF(3, 0, 20, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(3, 0, 20, 20)))); if (RuntimeEnabledFeatures::LayoutNGTextCombineEnabled()) { EXPECT_THAT(GetBorderAndTextQuads(Position(text2, 0), Position(text2, 2)), - ElementsAre(FloatQuad(gfx::RectF(2, 20, 22, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(2, 20, 22, 20)))); EXPECT_THAT(GetBorderAndTextQuads(Position(text3, 0), Position(text3, 3)), - ElementsAre(FloatQuad(gfx::RectF(2, 40, 22, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(2, 40, 22, 20)))); EXPECT_THAT(GetBorderAndTextQuads(Position(text4, 0), Position(text4, 4)), - ElementsAre(FloatQuad(gfx::RectF(2, 60, 22, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(2, 60, 22, 20)))); } else { EXPECT_THAT(GetBorderAndTextQuads(Position(text2, 0), Position(text2, 2)), - ElementsAre(FloatQuad(gfx::RectF(3, 20, 20, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(3, 20, 20, 20)))); EXPECT_THAT(GetBorderAndTextQuads(Position(text3, 0), Position(text3, 3)), - ElementsAre(FloatQuad(gfx::RectF(3, 40, 20, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(3, 40, 20, 20)))); EXPECT_THAT(GetBorderAndTextQuads(Position(text4, 0), Position(text4, 4)), - ElementsAre(FloatQuad(gfx::RectF(3, 60, 20, 20)))); + ElementsAre(gfx::QuadF(gfx::RectF(3, 60, 20, 20)))); } } @@ -401,18 +402,18 @@ Element* const expected = GetDocument().getElementById("expected"); Element* const sample = GetDocument().getElementById("sample"); - const Vector<FloatQuad> expected_quads = + const Vector<gfx::QuadF> expected_quads = GetBorderAndTextQuads(Position(expected, 0), Position(expected, 2)); - const Vector<FloatQuad> sample_quads = + const Vector<gfx::QuadF> sample_quads = GetBorderAndTextQuads(Position(sample, 0), Position(sample, 1)); ASSERT_EQ(2u, sample_quads.size()); ASSERT_EQ(3u, expected_quads.size()) << "expected_quads has SPAN, SPAN.firstChild and P.lastChild"; - EXPECT_EQ(expected_quads[0].EnclosingBoundingBox().size(), - sample_quads[0].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[0].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[0].BoundingBox()).size()) << "Check size of first-letter part"; - EXPECT_EQ(expected_quads[2].EnclosingBoundingBox().size(), - sample_quads[1].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[2].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[1].BoundingBox()).size()) << "Check size of first-letter part"; EXPECT_EQ(ComputeSizesOfQuads( @@ -446,18 +447,18 @@ Element* const expected = GetDocument().getElementById("expected"); Element* const sample = GetDocument().getElementById("sample"); - const Vector<FloatQuad> expected_quads = + const Vector<gfx::QuadF> expected_quads = GetBorderAndTextQuads(Position(expected, 0), Position(expected, 2)); - const Vector<FloatQuad> sample_quads = + const Vector<gfx::QuadF> sample_quads = GetBorderAndTextQuads(Position(sample, 0), Position(sample, 1)); ASSERT_EQ(2u, sample_quads.size()); ASSERT_EQ(3u, expected_quads.size()) << "expected_quads has SPAN, SPAN.firstChild and P.lastChild"; - EXPECT_EQ(expected_quads[0].EnclosingBoundingBox().size(), - sample_quads[0].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[0].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[0].BoundingBox()).size()) << "Check size of first-letter part"; - EXPECT_EQ(expected_quads[2].EnclosingBoundingBox().size(), - sample_quads[1].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[2].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[1].BoundingBox()).size()) << "Check size of first-letter part"; EXPECT_EQ(ComputeSizesOfQuads( @@ -507,18 +508,18 @@ Element* const expected = GetDocument().getElementById("expected"); Element* const sample = GetDocument().getElementById("sample"); - const Vector<FloatQuad> expected_quads = + const Vector<gfx::QuadF> expected_quads = GetBorderAndTextQuads(Position(expected, 0), Position(expected, 2)); - const Vector<FloatQuad> sample_quads = + const Vector<gfx::QuadF> sample_quads = GetBorderAndTextQuads(Position(sample, 0), Position(sample, 1)); ASSERT_EQ(2u, sample_quads.size()); ASSERT_EQ(3u, expected_quads.size()) << "expected_quads has SPAN, SPAN.firstChild and P.lastChild"; - EXPECT_EQ(expected_quads[0].EnclosingBoundingBox().size(), - sample_quads[0].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[0].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[0].BoundingBox()).size()) << "Check size of first-letter part"; - EXPECT_EQ(expected_quads[2].EnclosingBoundingBox().size(), - sample_quads[1].EnclosingBoundingBox().size()) + EXPECT_EQ(gfx::ToEnclosingRect(expected_quads[2].BoundingBox()).size(), + gfx::ToEnclosingRect(sample_quads[1].BoundingBox()).size()) << "Check size of first-letter part"; EXPECT_EQ(ComputeSizesOfQuads(GetBorderAndTextQuads(
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 5d0a50f..befdd3ab 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/editing/editing_style.h" +#include "base/memory/values_equivalent.h" #include "base/stl_util.h" #include "third_party/blink/renderer/core/css/css_color.h" #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" @@ -340,7 +341,7 @@ const CSSValue* value = AttributeValueAsCSSValue(element); const CSSValue* style_value = style->GetPropertyCSSValue(property_id_); - return DataEquivalent(value, style_value); + return base::ValuesEquivalent(value, style_value); } void HTMLAttributeEquivalent::AddToStyle(Element* element,
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc index 9328159..b08a54c6 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1685,7 +1685,7 @@ position.ComputeOffsetInContainerNode()); } -FloatQuad LocalToAbsoluteQuadOf(const LocalCaretRect& caret_rect) { +gfx::QuadF LocalToAbsoluteQuadOf(const LocalCaretRect& caret_rect) { return caret_rect.layout_object->LocalRectToAbsoluteQuad(caret_rect.rect); }
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.h b/third_party/blink/renderer/core/editing/editing_utilities.h index 7ff2288f..923a8c1 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.h +++ b/third_party/blink/renderer/core/editing/editing_utilities.h
@@ -31,10 +31,10 @@ #include "third_party/blink/renderer/core/editing/forward.h" #include "third_party/blink/renderer/core/events/input_event.h" #include "third_party/blink/renderer/core/html/html_br_element.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -368,7 +368,7 @@ // LocalCaretRect conversions // ------------------------------------------------------------------------- -FloatQuad LocalToAbsoluteQuadOf(const LocalCaretRect&); +gfx::QuadF LocalToAbsoluteQuadOf(const LocalCaretRect&); // ------------------------------------------------------------------------- // Events
diff --git a/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc b/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc index 49f13a3..f58cb7b 100644 --- a/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc +++ b/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
@@ -41,9 +41,9 @@ #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink {
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc index a1dc1570..99a2f5b 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.cc +++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -85,10 +85,10 @@ #include "third_party/blink/renderer/core/page/spatial_navigation.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/text/unicode_utilities.h" +#include "ui/gfx/geometry/quad_f.h" #define EDIT_DEBUG 0
diff --git a/third_party/blink/renderer/core/editing/local_caret_rect.cc b/third_party/blink/renderer/core/editing/local_caret_rect.cc index d56538a..fc7f026 100644 --- a/third_party/blink/renderer/core/editing/local_caret_rect.cc +++ b/third_party/blink/renderer/core/editing/local_caret_rect.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace blink { @@ -203,7 +204,7 @@ position, extra_width_to_end_of_line, rule); if (caret_rect.IsEmpty()) return gfx::Rect(); - return LocalToAbsoluteQuadOf(caret_rect).EnclosingBoundingBox(); + return gfx::ToEnclosingRect(LocalToAbsoluteQuadOf(caret_rect).BoundingBox()); } gfx::Rect AbsoluteCaretBoundsOf(const PositionWithAffinity& position, @@ -221,7 +222,7 @@ LocalSelectionRectOfPosition(visible_position.ToPositionWithAffinity()); if (caret_rect.IsEmpty()) return gfx::Rect(); - return LocalToAbsoluteQuadOf(caret_rect).EnclosingBoundingBox(); + return gfx::ToEnclosingRect(LocalToAbsoluteQuadOf(caret_rect).BoundingBox()); } gfx::Rect AbsoluteSelectionBoundsOf(const VisiblePosition& visible_position) {
diff --git a/third_party/blink/renderer/core/editing/visible_position.cc b/third_party/blink/renderer/core/editing/visible_position.cc index 3bf5a98d..b3d48a4 100644 --- a/third_party/blink/renderer/core/editing/visible_position.cc +++ b/third_party/blink/renderer/core/editing/visible_position.cc
@@ -43,7 +43,7 @@ #include "third_party/blink/renderer/core/layout/line/root_inline_box.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink {
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc index 003698b2..f0a3c88 100644 --- a/third_party/blink/renderer/core/editing/visible_units.cc +++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -63,6 +63,7 @@ #include "third_party/blink/renderer/core/svg_element_type_helpers.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/text/text_boundaries.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace blink { @@ -1276,7 +1277,7 @@ } template <typename Strategy> -static Vector<FloatQuad> ComputeTextBounds( +static Vector<gfx::QuadF> ComputeTextBounds( const EphemeralRangeTemplate<Strategy>& range) { const PositionTemplate<Strategy>& start_position = range.StartPosition(); const PositionTemplate<Strategy>& end_position = range.EndPosition(); @@ -1286,7 +1287,7 @@ DCHECK(end_container); DCHECK(!start_container->GetDocument().NeedsLayoutTreeUpdate()); - Vector<FloatQuad> result; + Vector<gfx::QuadF> result; for (const Node& node : range.Nodes()) { LayoutObject* const layout_object = node.GetLayoutObject(); if (!layout_object || !layout_object->IsText()) @@ -1312,11 +1313,11 @@ } gfx::Rect ComputeTextRect(const EphemeralRange& range) { - return ToEnclosingRect(ComputeTextRectTemplate(range)); + return gfx::ToEnclosingRect(ComputeTextRectTemplate(range)); } gfx::Rect ComputeTextRect(const EphemeralRangeInFlatTree& range) { - return ToEnclosingRect(ComputeTextRectTemplate(range)); + return gfx::ToEnclosingRect(ComputeTextRectTemplate(range)); } gfx::RectF ComputeTextRectF(const EphemeralRange& range) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc index 7512936..92ef166a 100644 --- a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc +++ b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -531,8 +531,11 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) : data_pipe_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, - std::move(task_runner)) {} - ~FetchDataLoaderAsDataPipe() override {} + task_runner), + data_pipe_close_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC, + std::move(task_runner)) {} + ~FetchDataLoaderAsDataPipe() override = default; void Start(BytesConsumer* consumer, FetchDataLoader::Client* client) override { @@ -572,8 +575,14 @@ out_data_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, WTF::BindRepeating(&FetchDataLoaderAsDataPipe::OnWritable, WrapWeakPersistent(this))); + data_pipe_close_watcher_.Watch( + out_data_pipe_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED, + MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, + WTF::BindRepeating(&FetchDataLoaderAsDataPipe::OnPeerClosed, + WrapWeakPersistent(this))); data_pipe_watcher_.ArmOrNotify(); + data_pipe_close_watcher_.ArmOrNotify(); } // Give the resulting pipe consumer handle to the client. @@ -588,6 +597,11 @@ OnStateChange(); } + void OnPeerClosed(MojoResult result, const mojo::HandleSignalsState& state) { + StopInternal(); + client_->DidFetchDataLoadFailed(); + } + void OnWritable(MojoResult) { OnStateChange(); } // Implements BytesConsumer::Client. @@ -652,17 +666,21 @@ private: void StopInternal() { consumer_->Cancel(); - data_pipe_watcher_.Cancel(); - out_data_pipe_.reset(); + Dispose(); } - void Dispose() { data_pipe_watcher_.Cancel(); } + void Dispose() { + data_pipe_watcher_.Cancel(); + data_pipe_close_watcher_.Cancel(); + out_data_pipe_.reset(); + } Member<BytesConsumer> consumer_; Member<FetchDataLoader::Client> client_; mojo::ScopedDataPipeProducerHandle out_data_pipe_; mojo::SimpleWatcher data_pipe_watcher_; + mojo::SimpleWatcher data_pipe_close_watcher_; }; } // namespace
diff --git a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc index 95d3d9e..b4d4da2 100644 --- a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc +++ b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/scoped_persistent.h" +#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -174,6 +175,16 @@ void ReadableStreamBytesConsumer::Cancel() { if (state_ == PublicState::kClosed || state_ == PublicState::kErrored) return; + // BytesConsumer::Cancel can be called with ScriptForbiddenScope (e.g., + // in ExecutionContextLifecycleObserver::ContextDestroyed()). We don't run + // ReadableStreamDefaultReader::cancel in such a case. + if (!ScriptForbiddenScope::IsScriptForbidden()) { + ScriptState::Scope scope(script_state_); + ExceptionState exception_state(script_state_->GetIsolate(), + ExceptionState::kUnknownContext, "", ""); + reader_->cancel(script_state_, exception_state); + // We ignore exceptions as we can do nothing here. + } state_ = PublicState::kClosed; ClearClient(); reader_ = nullptr;
diff --git a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc index 4873528..4f92919 100644 --- a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc +++ b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
@@ -468,6 +468,29 @@ EXPECT_EQ(Result::kError, consumer->BeginRead(&buffer, &available)); } +TEST(ReadableStreamBytesConsumerTest, Cancel) { + V8TestingScope scope; + ScriptState* script_state = scope.GetScriptState(); + + auto* underlying_source = + MakeGarbageCollected<TestUnderlyingSource>(script_state); + auto* stream = ReadableStream::CreateWithCountQueueingStrategy( + script_state, underlying_source, 0); + underlying_source->Enqueue(ScriptValue(script_state->GetIsolate(), + v8::Null(script_state->GetIsolate()))); + underlying_source->Close(); + + Persistent<BytesConsumer> consumer = + MakeGarbageCollected<ReadableStreamBytesConsumer>(script_state, stream); + Persistent<MockClient> client = MakeGarbageCollected<MockClient>(); + consumer->SetClient(client); + + consumer->Cancel(); + + EXPECT_TRUE(underlying_source->IsCancelled()); + EXPECT_TRUE(underlying_source->IsCancelledWithUndefined()); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc index 108481f..9ceb13d 100644 --- a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc +++ b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc
@@ -30,7 +30,7 @@ case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpenee: case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOther: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpener: case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOther: return String(); @@ -46,7 +46,7 @@ case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpenee: case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOther: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpenee: case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOther: return String(); @@ -62,7 +62,7 @@ case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpenee: case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOther: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpenee: case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpener: return String();
diff --git a/third_party/blink/renderer/core/frame/dom_visual_viewport.cc b/third_party/blink/renderer/core/frame/dom_visual_viewport.cc index b9943c0..8b347b3 100644 --- a/third_party/blink/renderer/core/frame/dom_visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
@@ -204,8 +204,8 @@ const float page_zoom_factor = frame->PageZoomFactor(); const float scale_factor = dips_to_blink / page_zoom_factor; for (auto const& web_segment : web_segments) { - blink::FloatQuad quad = blink::FloatQuad(web_segment); - quad.Scale(scale_factor, scale_factor); + gfx::QuadF quad((gfx::RectF(web_segment))); + quad.Scale(scale_factor); viewport_segments.push_back(DOMRect::FromRectF(quad.BoundingBox())); }
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.cc b/third_party/blink/renderer/core/frame/event_handler_registry.cc index 107b576..cd40d94f 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.cc +++ b/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -245,7 +245,7 @@ case kTouchStartOrMoveEventBlockingLowLatency: GetPage()->GetChromeClient().SetNeedsLowLatencyInput(frame, has_active_handlers); - FALLTHROUGH; + [[fallthrough]]; case kTouchAction: case kTouchStartOrMoveEventBlocking: case kTouchStartOrMoveEventPassive:
diff --git a/third_party/blink/renderer/core/frame/find_in_page.cc b/third_party/blink/renderer/core/frame/find_in_page.cc index 22c97f56..11bc63d 100644 --- a/third_party/blink/renderer/core/frame/find_in_page.cc +++ b/third_party/blink/renderer/core/frame/find_in_page.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/editing/finder/text_finder.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/core/page/page.h" @@ -342,13 +343,23 @@ : mojom::blink::FindMatchUpdateType::kMoreUpdatesComing); } -void FindInPage::ReportFindInPageSelection(int request_id, - int active_match_ordinal, - const gfx::Rect& selection_rect, - bool final_update) { +void FindInPage::ReportFindInPageSelection( + int request_id, + int active_match_ordinal, + const gfx::Rect& local_selection_rect, + bool final_update) { // In tests, |client_| might not be set. if (!client_) return; + + float device_scale_factor = 1.f; + if (LocalFrame* local_frame = frame_->GetFrame()) { + device_scale_factor = + local_frame->GetPage()->GetChromeClient().WindowToViewportScalar( + local_frame, 1.0f); + } + auto selection_rect = gfx::ScaleToEnclosingRect(local_selection_rect, + 1.f / device_scale_factor); client_->SetActiveMatch( request_id, selection_rect, active_match_ordinal, final_update ? mojom::blink::FindMatchUpdateType::kFinalUpdate
diff --git a/third_party/blink/renderer/core/frame/frame_view.cc b/third_party/blink/renderer/core/frame/frame_view.cc index c244a59..e488952 100644 --- a/third_party/blink/renderer/core/frame/frame_view.cc +++ b/third_party/blink/renderer/core/frame/frame_view.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/page.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/transform.h" namespace blink { @@ -129,7 +130,8 @@ .Inverse(); if (geometry.IsIntersecting()) { PhysicalRect intersection_rect = PhysicalRect::EnclosingRect( - matrix.ProjectQuad(FloatQuad(gfx::RectF(geometry.IntersectionRect()))) + matrix + .ProjectQuad(gfx::QuadF(gfx::RectF(geometry.IntersectionRect()))) .BoundingBox()); // Don't let EnclosingRect turn an empty rect into a non-empty one. @@ -162,7 +164,7 @@ mainframe_intersection_rect = PhysicalRect::EnclosingRect( matrix .ProjectQuad( - FloatQuad(gfx::RectF(geometry.UnclippedIntersectionRect()))) + gfx::QuadF(gfx::RectF(geometry.UnclippedIntersectionRect()))) .BoundingBox()); if (mainframe_intersection_rect.IsEmpty()) { @@ -216,10 +218,10 @@ UpdateFrameVisibility(!viewport_intersection.IsEmpty()); if (ShouldReportMainFrameIntersection()) { - gfx::Rect projected_rect = ToEnclosingRect(PhysicalRect::EnclosingRect( + gfx::Rect projected_rect = gfx::ToEnclosingRect( main_frame_transform_matrix - .ProjectQuad(FloatQuad(gfx::Rect(mainframe_intersection))) - .BoundingBox())); + .ProjectQuad(gfx::QuadF(gfx::RectF(mainframe_intersection))) + .BoundingBox()); // Return <0, 0, 0, 0> if there is no area. if (projected_rect.IsEmpty()) projected_rect.set_origin(gfx::Point(0, 0));
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 147bc5f2..f42d6ff 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -149,7 +149,6 @@ #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_performance.h" #include "third_party/blink/renderer/platform/geometry/double_rect.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings_builder.h" @@ -172,6 +171,7 @@ #include "ui/base/cursor/cursor.h" #include "ui/base/cursor/mojom/cursor_type.mojom-blink.h" #include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_f.h" // Used to check for dirty layouts violating document lifecycle rules. @@ -211,11 +211,11 @@ } } -FloatQuad GetQuadForTimelinePaintEvent(const scoped_refptr<cc::Layer>& layer) { +gfx::QuadF GetQuadForTimelinePaintEvent(const scoped_refptr<cc::Layer>& layer) { gfx::RectF rect(layer->update_rect()); if (layer->transform_tree_index() != -1) layer->ScreenSpaceTransform().TransformRect(&rect); - return FloatQuad(rect); + return gfx::QuadF(rect); } // Default value for how long we want to delay the @@ -1562,7 +1562,8 @@ return; DEVTOOLS_TIMELINE_TRACE_EVENT_INSTANT_WITH_CATEGORIES( TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", - inspector_invalidate_layout_event::Data, frame_.Get()); + inspector_invalidate_layout_event::Data, frame_.Get(), + GetLayoutView()->OwnerNodeId()); ClearLayoutSubtreeRootsAndMarkContainingBlocks(); @@ -1610,7 +1611,8 @@ } DEVTOOLS_TIMELINE_TRACE_EVENT_INSTANT_WITH_CATEGORIES( TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", - inspector_invalidate_layout_event::Data, frame_.Get()); + inspector_invalidate_layout_event::Data, frame_.Get(), + relayout_root->OwnerNodeId()); } bool LocalFrameView::LayoutPending() const {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc index f638dfd6..074af47c 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -158,7 +158,7 @@ TransformationMatrix matrix = local_root_transform_state.AccumulatedTransform().Inverse(); PhysicalRect local_viewport_rect = PhysicalRect::EnclosingRect( - matrix.ProjectQuad(FloatQuad(viewport_rect)).BoundingBox()); + matrix.ProjectQuad(gfx::QuadF(gfx::RectF(viewport_rect))).BoundingBox()); compositing_rect_ = ToEnclosingRect(local_viewport_rect); gfx::Size frame_size = Size();
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc index b50c6a9..d996862 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -138,13 +138,13 @@ return LayoutViewport().GetLayoutBox(); } -FloatQuad RootFrameViewport::LocalToVisibleContentQuad( - const FloatQuad& quad, +gfx::QuadF RootFrameViewport::LocalToVisibleContentQuad( + const gfx::QuadF& quad, const LayoutObject* local_object, unsigned flags) const { if (!layout_viewport_) return quad; - FloatQuad viewport_quad = + gfx::QuadF viewport_quad = layout_viewport_->LocalToVisibleContentQuad(quad, local_object, flags); if (visual_viewport_) { viewport_quad = visual_viewport_->LocalToVisibleContentQuad( @@ -411,8 +411,18 @@ ScrollableArea& secondary = scroll_first == kVisualViewport ? LayoutViewport() : GetVisualViewport(); - ScrollOffset target_offset = primary.ClampScrollOffset( + // Compute the clamped offsets for both viewports before performing any + // scrolling since the order of distribution can vary (and is typically + // visualViewport-first) but, per-spec, if we scroll both viewports the + // scroll event must be sent to the DOMWindow first, then to the + // VisualViewport. Thus, we'll always perform the scrolls in that order, + // regardless of the order of distribution. + ScrollOffset primary_offset = primary.ClampScrollOffset( primary.GetScrollAnimator().CurrentOffset() + delta); + ScrollOffset unconsumed_by_primary = + (primary.GetScrollAnimator().CurrentOffset() + delta) - primary_offset; + ScrollOffset secondary_offset = secondary.ClampScrollOffset( + secondary.GetScrollAnimator().CurrentOffset() + unconsumed_by_primary); auto all_done = on_finish ? base::BarrierClosure(2, std::move(on_finish)) : base::RepeatingClosure(); @@ -421,24 +431,15 @@ // so we assume that aborting sequenced smooth scrolls has been handled. // It can also be called from inside an animation to set the offset in // each frame. In that case, we shouldn't abort sequenced smooth scrolls. - primary.SetScrollOffset(target_offset, scroll_type, behavior, all_done); - // Scroll the secondary viewport if all of the scroll was not applied to the - // primary viewport. - ScrollOffset updated_offset = - secondary.GetScrollAnimator().CurrentOffset() + target_offset; - ScrollOffset applied = updated_offset - old_offset; - delta -= applied; - - if (delta.IsZero()) { - if (all_done) - all_done.Run(); - return; - } - - target_offset = secondary.ClampScrollOffset( - secondary.GetScrollAnimator().CurrentOffset() + delta); - secondary.SetScrollOffset(target_offset, scroll_type, behavior, all_done); + // Actually apply the scroll the layout viewport first so that the DOM event + // is dispatched to the DOMWindow before the VisualViewport. + LayoutViewport().SetScrollOffset( + scroll_first == kLayoutViewport ? primary_offset : secondary_offset, + scroll_type, behavior, all_done); + GetVisualViewport().SetScrollOffset( + scroll_first == kVisualViewport ? primary_offset : secondary_offset, + scroll_type, behavior, all_done); } gfx::Vector2d RootFrameViewport::ScrollOffsetInt() const {
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h index e0852fab..7dd2bef 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -114,9 +114,9 @@ mojom::blink::ColorScheme UsedColorScheme() const override; void ClearScrollableArea() override; LayoutBox* GetLayoutBox() const override; - FloatQuad LocalToVisibleContentQuad(const FloatQuad&, - const LayoutObject*, - unsigned = 0) const final; + gfx::QuadF LocalToVisibleContentQuad(const gfx::QuadF&, + const LayoutObject*, + unsigned = 0) const final; scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final; ScrollbarTheme& GetPageScrollbarTheme() const override;
diff --git a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc index adbc3c22..cc22906a 100644 --- a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
@@ -445,7 +445,7 @@ // Document type node can be in DOM? case Node::kDocumentTypeNode: param->have_seen_doc_type = true; - FALLTHROUGH; + [[fallthrough]]; default: // For other type node, call default action. SaveHTMLContentToBuffer(CreateMarkup(node), param);
diff --git a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc index b769df4..3bd7248 100644 --- a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc
@@ -35,11 +35,11 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "ui/gfx/geometry/quad_f.h" #include "v8/include/v8.h" namespace blink {
diff --git a/third_party/blink/renderer/core/geometry/dom_rect_list.cc b/third_party/blink/renderer/core/geometry/dom_rect_list.cc index 9ae50e7..c7721bf 100644 --- a/third_party/blink/renderer/core/geometry/dom_rect_list.cc +++ b/third_party/blink/renderer/core/geometry/dom_rect_list.cc
@@ -30,7 +30,7 @@ DOMRectList::DOMRectList() = default; -DOMRectList::DOMRectList(const Vector<FloatQuad>& quads) { +DOMRectList::DOMRectList(const Vector<gfx::QuadF>& quads) { list_.ReserveInitialCapacity(quads.size()); for (const auto& quad : quads) list_.push_back(DOMRect::FromRectF(quad.BoundingBox()));
diff --git a/third_party/blink/renderer/core/geometry/dom_rect_list.h b/third_party/blink/renderer/core/geometry/dom_rect_list.h index d13885b0..c5424e7 100644 --- a/third_party/blink/renderer/core/geometry/dom_rect_list.h +++ b/third_party/blink/renderer/core/geometry/dom_rect_list.h
@@ -30,9 +30,9 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -50,7 +50,7 @@ list_.push_back(DOMRect::FromRectF(gfx::RectF(r))); } - explicit DOMRectList(const Vector<FloatQuad>&); + explicit DOMRectList(const Vector<gfx::QuadF>&); unsigned length() const; DOMRect* item(unsigned index);
diff --git a/third_party/blink/renderer/core/html/forms/external_popup_menu.cc b/third_party/blink/renderer/core/html/forms/external_popup_menu.cc index b67225c..e49235b 100644 --- a/third_party/blink/renderer/core/html/forms/external_popup_menu.cc +++ b/third_party/blink/renderer/core/html/forms/external_popup_menu.cc
@@ -49,9 +49,9 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink {
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc index e8da29d4..aaa2b2a 100644 --- a/third_party/blink/renderer/core/html/html_object_element.cc +++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -363,6 +363,7 @@ } // TODO(dcheng): Detach the content frame here. + UseCounter::Count(GetDocument(), WebFeature::kHTMLObjectElementFallback); use_fallback_content_ = true; ReattachFallbackContent(); }
diff --git a/third_party/blink/renderer/core/html/parser/atomic_html_token.cc b/third_party/blink/renderer/core/html/parser/atomic_html_token.cc index 8adbeba..0aa0405 100644 --- a/third_party/blink/renderer/core/html/parser/atomic_html_token.cc +++ b/third_party/blink/renderer/core/html/parser/atomic_html_token.cc
@@ -45,7 +45,7 @@ case HTMLToken::kEndTag: if (self_closing_) printf(" selfclosing"); - FALLTHROUGH; + [[fallthrough]]; case HTMLToken::DOCTYPE: printf(" name \"%s\"", name_.GetString().Utf8().c_str()); break;
diff --git a/third_party/blink/renderer/core/html/parser/atomic_html_token.h b/third_party/blink/renderer/core/html/parser/atomic_html_token.h index f527403..938bc2b 100644 --- a/third_party/blink/renderer/core/html/parser/atomic_html_token.h +++ b/third_party/blink/renderer/core/html/parser/atomic_html_token.h
@@ -165,7 +165,7 @@ duplicate_attribute_ = true; } } - FALLTHROUGH; + [[fallthrough]]; case HTMLToken::kEndTag: self_closing_ = token.SelfClosing(); name_ = AtomicString(token.Data());
diff --git a/third_party/blink/renderer/core/html/parser/compact_html_token.cc b/third_party/blink/renderer/core/html/parser/compact_html_token.cc index 825b62f..4446d6d5 100644 --- a/third_party/blink/renderer/core/html/parser/compact_html_token.cc +++ b/third_party/blink/renderer/core/html/parser/compact_html_token.cc
@@ -70,10 +70,10 @@ attributes_.push_back( Attribute(attribute.NameAttemptStaticStringCreation(), attribute.Value8BitIfNecessary())); - FALLTHROUGH; + [[fallthrough]]; case HTMLToken::kEndTag: self_closing_ = token->SelfClosing(); - FALLTHROUGH; + [[fallthrough]]; case HTMLToken::kComment: case HTMLToken::kCharacter: { is_all8_bit_data_ = token->IsAll8BitData();
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index a8b373ab..1ba834a 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -1137,7 +1137,7 @@ case kInitialMode: DCHECK_EQ(GetInsertionMode(), kInitialMode); DefaultForInitial(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHTMLMode: DCHECK_EQ(GetInsertionMode(), kBeforeHTMLMode); if (token->GetName() == html_names::kHTMLTag) { @@ -1146,7 +1146,7 @@ return; } DefaultForBeforeHTML(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHeadMode: DCHECK_EQ(GetInsertionMode(), kBeforeHeadMode); if (token->GetName() == html_names::kHTMLTag) { @@ -1159,13 +1159,13 @@ return; } DefaultForBeforeHead(); - FALLTHROUGH; + [[fallthrough]]; case kInHeadMode: DCHECK_EQ(GetInsertionMode(), kInHeadMode); if (ProcessStartTagForInHead(token)) return; DefaultForInHead(); - FALLTHROUGH; + [[fallthrough]]; case kAfterHeadMode: DCHECK_EQ(GetInsertionMode(), kAfterHeadMode); if (token->GetName() == html_names::kHTMLTag) { @@ -1205,7 +1205,7 @@ return; } DefaultForAfterHead(); - FALLTHROUGH; + [[fallthrough]]; case kInBodyMode: DCHECK_EQ(GetInsertionMode(), kInBodyMode); ProcessStartTagForInBody(token); @@ -1408,7 +1408,7 @@ ProcessStartTag(token); return; } - FALLTHROUGH; + [[fallthrough]]; case kInSelectMode: DCHECK(GetInsertionMode() == kInSelectMode || GetInsertionMode() == kInSelectInTableMode); @@ -2063,7 +2063,7 @@ case kInitialMode: DCHECK_EQ(GetInsertionMode(), kInitialMode); DefaultForInitial(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHTMLMode: DCHECK_EQ(GetInsertionMode(), kBeforeHTMLMode); if (token->GetName() != html_names::kHeadTag && @@ -2074,7 +2074,7 @@ return; } DefaultForBeforeHTML(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHeadMode: DCHECK_EQ(GetInsertionMode(), kBeforeHeadMode); if (token->GetName() != html_names::kHeadTag && @@ -2085,7 +2085,7 @@ return; } DefaultForBeforeHead(); - FALLTHROUGH; + [[fallthrough]]; case kInHeadMode: DCHECK_EQ(GetInsertionMode(), kInHeadMode); // FIXME: This case should be broken out into processEndTagForInHead, @@ -2108,7 +2108,7 @@ return; } DefaultForInHead(); - FALLTHROUGH; + [[fallthrough]]; case kAfterHeadMode: DCHECK_EQ(GetInsertionMode(), kAfterHeadMode); if (token->GetName() != html_names::kBodyTag && @@ -2118,7 +2118,7 @@ return; } DefaultForAfterHead(); - FALLTHROUGH; + [[fallthrough]]; case kInBodyMode: DCHECK_EQ(GetInsertionMode(), kInBodyMode); ProcessEndTagForInBody(token); @@ -2196,7 +2196,7 @@ SetInsertionMode(kAfterAfterBodyMode); return; } - FALLTHROUGH; + [[fallthrough]]; case kAfterAfterBodyMode: DCHECK(GetInsertionMode() == kAfterBodyMode || GetInsertionMode() == kAfterAfterBodyMode); @@ -2265,7 +2265,7 @@ SetInsertionMode(kAfterAfterFramesetMode); return; } - FALLTHROUGH; + [[fallthrough]]; case kAfterAfterFramesetMode: DCHECK(GetInsertionMode() == kAfterFramesetMode || GetInsertionMode() == kAfterAfterFramesetMode); @@ -2287,7 +2287,7 @@ } return; } - FALLTHROUGH; + [[fallthrough]]; case kInSelectMode: DCHECK(GetInsertionMode() == kInSelectMode || GetInsertionMode() == kInSelectInTableMode); @@ -2393,7 +2393,7 @@ if (buffer.IsEmpty()) return; DefaultForInitial(); - FALLTHROUGH; + [[fallthrough]]; } case kBeforeHTMLMode: { DCHECK_EQ(GetInsertionMode(), kBeforeHTMLMode); @@ -2405,7 +2405,7 @@ buffer.SkipRemaining(); return; } - FALLTHROUGH; + [[fallthrough]]; } case kBeforeHeadMode: { DCHECK_EQ(GetInsertionMode(), kBeforeHeadMode); @@ -2413,7 +2413,7 @@ if (buffer.IsEmpty()) return; DefaultForBeforeHead(); - FALLTHROUGH; + [[fallthrough]]; } case kInHeadMode: { DCHECK_EQ(GetInsertionMode(), kInHeadMode); @@ -2423,7 +2423,7 @@ if (buffer.IsEmpty()) return; DefaultForInHead(); - FALLTHROUGH; + [[fallthrough]]; } case kAfterHeadMode: { DCHECK_EQ(GetInsertionMode(), kAfterHeadMode); @@ -2433,7 +2433,7 @@ if (buffer.IsEmpty()) return; DefaultForAfterHead(); - FALLTHROUGH; + [[fallthrough]]; } case kInBodyMode: case kInCaptionMode: @@ -2467,7 +2467,7 @@ ProcessCharacterBufferForInBody(buffer); break; } - FALLTHROUGH; + [[fallthrough]]; } case kInTableTextMode: { buffer.GiveRemainingTo(pending_table_characters_); @@ -2559,23 +2559,23 @@ case kInitialMode: DCHECK_EQ(GetInsertionMode(), kInitialMode); DefaultForInitial(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHTMLMode: DCHECK_EQ(GetInsertionMode(), kBeforeHTMLMode); DefaultForBeforeHTML(); - FALLTHROUGH; + [[fallthrough]]; case kBeforeHeadMode: DCHECK_EQ(GetInsertionMode(), kBeforeHeadMode); DefaultForBeforeHead(); - FALLTHROUGH; + [[fallthrough]]; case kInHeadMode: DCHECK_EQ(GetInsertionMode(), kInHeadMode); DefaultForInHead(); - FALLTHROUGH; + [[fallthrough]]; case kAfterHeadMode: DCHECK_EQ(GetInsertionMode(), kAfterHeadMode); DefaultForAfterHead(); - FALLTHROUGH; + [[fallthrough]]; case kInBodyMode: case kInCellMode: case kInCaptionMode: @@ -2614,7 +2614,7 @@ DCHECK(tree_.CurrentNode()->HasTagName(html_names::kColgroupTag) || IsA<HTMLTemplateElement>(tree_.CurrentNode())); ProcessColgroupEndTagForInColumnGroup(); - FALLTHROUGH; + [[fallthrough]]; case kInFramesetMode: case kInTableMode: case kInTableBodyMode:
diff --git a/third_party/blink/renderer/core/html/portal/portal_contents.cc b/third_party/blink/renderer/core/html/portal/portal_contents.cc index 706e9fc..d8ad0df6 100644 --- a/third_party/blink/renderer/core/html/portal/portal_contents.cc +++ b/third_party/blink/renderer/core/html/portal/portal_contents.cc
@@ -88,7 +88,7 @@ case mojom::blink::PortalActivateResult::kPredecessorWasAdopted: if (auto* page = GetDocument().GetPage()) page->SetInsidePortal(true); - FALLTHROUGH; + [[fallthrough]]; case mojom::blink::PortalActivateResult::kPredecessorWillUnload: activation_delegate_->ActivationDidSucceed(); should_destroy_contents = true;
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 29da01ab..c88d112 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -49,10 +49,10 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" #include "third_party/blink/renderer/core/timing/event_timing.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-blink.h" #include "ui/display/screen_info.h" #include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink {
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc index d920bf2..ead25005 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h"
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc index 7a41779..b3c08bd 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.cc +++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -307,7 +307,7 @@ QuadHighlightTool::QuadHighlightTool(InspectorOverlayAgent* overlay, OverlayFrontend* frontend, - std::unique_ptr<FloatQuad> quad, + std::unique_ptr<gfx::QuadF> quad, Color color, Color outline_color) : InspectTool(overlay, frontend),
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.h b/third_party/blink/renderer/core/inspector/inspect_tools.h index 1f558bec..dd55eac 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.h +++ b/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -64,7 +64,7 @@ public: QuadHighlightTool(InspectorOverlayAgent* overlay, OverlayFrontend* frontend, - std::unique_ptr<FloatQuad> quad, + std::unique_ptr<gfx::QuadF> quad, Color color, Color outline_color); QuadHighlightTool(const QuadHighlightTool&) = delete; @@ -75,7 +75,7 @@ bool HideOnHideHighlight() override; void Draw(float scale) override; String GetOverlayName() override; - std::unique_ptr<FloatQuad> quad_; + std::unique_ptr<gfx::QuadF> quad_; Color color_; Color outline_color_; };
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.h b/third_party/blink/renderer/core/inspector/inspector_dom_agent.h index 0bbb5aa..0b6f2898 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.h
@@ -39,13 +39,13 @@ #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" #include "third_party/blink/renderer/core/inspector/protocol/dom.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "ui/gfx/geometry/quad_f.h" #include "v8/include/v8-inspector.h" namespace blink { @@ -57,7 +57,6 @@ class DocumentLoader; class Element; class ExceptionState; -class FloatQuad; class HTMLFrameOwnerElement; class HTMLPortalElement; class HTMLSlotElement;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 8a2bdda4..023b1ec 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -158,7 +158,7 @@ }; std::unique_ptr<protocol::Array<double>> BuildArrayForQuad( - const FloatQuad& quad) { + const gfx::QuadF& quad) { return std::make_unique<std::vector<double>, std::initializer_list<double>>( {quad.p1().x(), quad.p1().y(), quad.p2().x(), quad.p2().y(), quad.p3().x(), quad.p3().y(), quad.p4().x(), quad.p4().y()}); @@ -174,10 +174,6 @@ return quad_path; } -Path QuadToPath(const FloatQuad& quad) { - return QuadToPath(ToGfxQuadF(quad)); -} - Path RowQuadToPath(const gfx::QuadF& quad, bool draw_end_line) { Path quad_path; quad_path.MoveTo(quad.p1()); @@ -189,10 +185,6 @@ return quad_path; } -Path RowQuadToPath(const FloatQuad& quad, bool draw_end_line) { - return RowQuadToPath(ToGfxQuadF(quad), draw_end_line); -} - Path ColumnQuadToPath(const gfx::QuadF& quad, bool draw_end_line) { Path quad_path; quad_path.MoveTo(quad.p1()); @@ -204,10 +196,6 @@ return quad_path; } -Path ColumnQuadToPath(const FloatQuad& quad, bool draw_end_line) { - return ColumnQuadToPath(ToGfxQuadF(quad), draw_end_line); -} - gfx::PointF FramePointToViewport(const LocalFrameView* view, gfx::PointF point_in_frame) { gfx::PointF point_in_root_frame = view->ConvertToRootFrame(point_in_frame); @@ -224,7 +212,7 @@ &frame_view->GetFrame(), 1.f); } -void FrameQuadToViewport(const LocalFrameView* view, FloatQuad& quad) { +void FrameQuadToViewport(const LocalFrameView* view, gfx::QuadF& quad) { quad.set_p1(FramePointToViewport(view, quad.p1())); quad.set_p2(FramePointToViewport(view, quad.p2())); quad.set_p3(FramePointToViewport(view, quad.p3())); @@ -233,7 +221,7 @@ const ShapeOutsideInfo* ShapeOutsideInfoForNode(Node* node, Shape::DisplayPaths* paths, - FloatQuad* bounds) { + gfx::QuadF* bounds) { LayoutObject* layout_object = node->GetLayoutObject(); if (!layout_object || !layout_object->IsBox() || !To<LayoutBox>(layout_object)->GetShapeOutsideInfo()) @@ -643,7 +631,7 @@ std::unique_ptr<protocol::ListValue> BuildPathFromQuad( const blink::LocalFrameView* containing_view, - FloatQuad quad) { + gfx::QuadF quad) { FrameQuadToViewport(containing_view, quad); PathBuilder builder; builder.AppendPath(QuadToPath(quad), @@ -900,7 +888,7 @@ PhysicalSize size(end_column - start_column - column_gap_offset, end_row - start_row - row_gap_offset); PhysicalRect area_rect(position, size); - FloatQuad area_quad = layout_object->LocalRectToAbsoluteQuad(area_rect); + gfx::QuadF area_quad = layout_object->LocalRectToAbsoluteQuad(area_rect); FrameQuadToViewport(containing_view, area_quad); PathBuilder area_builder; area_builder.AppendPath(QuadToPath(area_quad), scale); @@ -1126,7 +1114,7 @@ // Create the path for the flex container PathBuilder container_builder; PhysicalRect content_box = layout_box->PhysicalContentBoxRect(); - FloatQuad content_quad = layout_object->LocalRectToAbsoluteQuad(content_box); + gfx::QuadF content_quad = layout_object->LocalRectToAbsoluteQuad(content_box); FrameQuadToViewport(containing_view, content_quad); container_builder.AppendPath(QuadToPath(content_quad), scale); @@ -1145,7 +1133,7 @@ std::unique_ptr<protocol::DictionaryValue> item_info = protocol::DictionaryValue::create(); - FloatQuad item_margin_quad = + gfx::QuadF item_margin_quad = layout_object->LocalRectToAbsoluteQuad(item_data.first); FrameQuadToViewport(containing_view, item_margin_quad); PathBuilder item_builder; @@ -1316,7 +1304,7 @@ if (i != rows.size() - 1) size.height -= row_gap; PhysicalRect row(position, size); - FloatQuad row_quad = layout_object->LocalRectToAbsoluteQuad(row); + gfx::QuadF row_quad = layout_object->LocalRectToAbsoluteQuad(row); FrameQuadToViewport(containing_view, row_quad); row_builder.AppendPath( RowQuadToPath(row_quad, i == rows.size() - 1 || row_gap > 0), scale); @@ -1325,7 +1313,7 @@ PhysicalOffset gap_position(row_left, rows.at(i) - row_gap); PhysicalSize gap_size(row_width, row_gap); PhysicalRect gap(gap_position, gap_size); - FloatQuad gap_quad = layout_object->LocalRectToAbsoluteQuad(gap); + gfx::QuadF gap_quad = layout_object->LocalRectToAbsoluteQuad(gap); FrameQuadToViewport(containing_view, gap_quad); row_gap_builder.AppendPath(QuadToPath(gap_quad), scale); } @@ -1348,7 +1336,7 @@ } PhysicalOffset position(line_left, column_top); PhysicalRect column(position, size); - FloatQuad column_quad = layout_object->LocalRectToAbsoluteQuad(column); + gfx::QuadF column_quad = layout_object->LocalRectToAbsoluteQuad(column); FrameQuadToViewport(containing_view, column_quad); bool draw_end_line = is_ltr ? i == columns.size() - 1 : i == 1; column_builder.AppendPath( @@ -1364,7 +1352,7 @@ PhysicalOffset gap_position(gap_left, column_top); PhysicalSize gap_size(column_gap, column_height); PhysicalRect gap(gap_position, gap_size); - FloatQuad gap_quad = layout_object->LocalRectToAbsoluteQuad(gap); + gfx::QuadF gap_quad = layout_object->LocalRectToAbsoluteQuad(gap); FrameQuadToViewport(containing_view, gap_quad); column_gap_builder.AppendPath(QuadToPath(gap_quad), scale); } @@ -1417,7 +1405,7 @@ PhysicalOffset grid_position(row_left, column_top); PhysicalSize grid_size(row_width, column_height); PhysicalRect grid_rect(grid_position, grid_size); - FloatQuad grid_quad = layout_object->LocalRectToAbsoluteQuad(grid_rect); + gfx::QuadF grid_quad = layout_object->LocalRectToAbsoluteQuad(grid_rect); FrameQuadToViewport(containing_view, grid_quad); grid_border_builder.AppendPath(QuadToPath(grid_quad), scale); grid_info->setValue("gridBorder", grid_border_builder.Release()); @@ -1448,7 +1436,7 @@ isPrimary); } -void CollectQuadsRecursive(Node* node, Vector<FloatQuad>& out_quads) { +void CollectQuadsRecursive(Node* node, Vector<gfx::QuadF>& out_quads) { LayoutObject* layout_object = node->GetLayoutObject(); // For inline elements, absoluteQuads will return a line box based on the // line-height and font metrics, which is technically incorrect as replaced @@ -1470,13 +1458,13 @@ } } -void CollectQuads(Node* node, Vector<FloatQuad>& out_quads) { +void CollectQuads(Node* node, Vector<gfx::QuadF>& out_quads) { CollectQuadsRecursive(node, out_quads); LocalFrameView* containing_view = node->GetLayoutObject() ? node->GetLayoutObject()->GetFrameView() : nullptr; if (containing_view) { - for (FloatQuad& quad : out_quads) + for (gfx::QuadF& quad : out_quads) FrameQuadToViewport(containing_view, quad); } } @@ -1560,10 +1548,10 @@ } bool InspectorHighlightBase::BuildNodeQuads(Node* node, - FloatQuad* content, - FloatQuad* padding, - FloatQuad* border, - FloatQuad* margin) { + gfx::QuadF* content, + gfx::QuadF* padding, + gfx::QuadF* border, + gfx::QuadF* margin) { LayoutObject* layout_object = node->GetLayoutObject(); if (!layout_object) return false; @@ -1645,7 +1633,7 @@ return true; } -void InspectorHighlightBase::AppendQuad(const FloatQuad& quad, +void InspectorHighlightBase::AppendQuad(const gfx::QuadF& quad, const Color& fill_color, const Color& outline_color, const String& name) { @@ -1677,7 +1665,7 @@ int source_order_position) : InspectorHighlightBase(node), source_order_position_(source_order_position) { - FloatQuad content, padding, border, margin; + gfx::QuadF content, padding, border, margin; if (!BuildNodeQuads(node, &content, &padding, &border, &margin)) return; AppendQuad(border, Color::kTransparent, outline_color, "border"); @@ -1843,7 +1831,7 @@ Node* event_target_node, const InspectorHighlightConfig& highlight_config) { if (event_target_node->GetLayoutObject()) { - FloatQuad border, unused; + gfx::QuadF border, unused; if (BuildNodeQuads(event_target_node, &unused, &unused, &border, &unused)) AppendQuad(border, highlight_config.event_target); } @@ -1853,7 +1841,7 @@ Node* node, const InspectorHighlightConfig& config) { Shape::DisplayPaths paths; - FloatQuad bounds_quad; + gfx::QuadF bounds_quad; const ShapeOutsideInfo* shape_outside_info = ShapeOutsideInfoForNode(node, &paths, &bounds_quad); @@ -1883,7 +1871,7 @@ if (!layout_object) return; - Vector<FloatQuad> svg_quads; + Vector<gfx::QuadF> svg_quads; if (BuildSVGQuads(node, svg_quads)) { for (wtf_size_t i = 0; i < svg_quads.size(); ++i) { AppendQuad(svg_quads[i], highlight_config.content, @@ -1892,7 +1880,7 @@ return; } - FloatQuad content, padding, border, margin; + gfx::QuadF content, padding, border, margin; if (!BuildNodeQuads(node, &content, &padding, &border, &margin)) return; AppendQuad(content, highlight_config.content, @@ -2010,8 +1998,8 @@ if (!layout_object || !view) return false; - FloatQuad content, padding, border, margin; - Vector<FloatQuad> svg_quads; + gfx::QuadF content, padding, border, margin; + Vector<gfx::QuadF> svg_quads; if (BuildSVGQuads(node, svg_quads)) { if (!svg_quads.size()) return false; @@ -2024,10 +2012,10 @@ } if (use_absolute_zoom) { - AdjustForAbsoluteZoom::AdjustFloatQuad(content, *layout_object); - AdjustForAbsoluteZoom::AdjustFloatQuad(padding, *layout_object); - AdjustForAbsoluteZoom::AdjustFloatQuad(border, *layout_object); - AdjustForAbsoluteZoom::AdjustFloatQuad(margin, *layout_object); + AdjustForAbsoluteZoom::AdjustQuad(content, *layout_object); + AdjustForAbsoluteZoom::AdjustQuad(padding, *layout_object); + AdjustForAbsoluteZoom::AdjustQuad(border, *layout_object); + AdjustForAbsoluteZoom::AdjustQuad(margin, *layout_object); } float scale = PageScaleFromFrameView(view); @@ -2059,7 +2047,7 @@ .build(); Shape::DisplayPaths paths; - FloatQuad bounds_quad; + gfx::QuadF bounds_quad; protocol::ErrorSupport errors; if (const ShapeOutsideInfo* shape_outside_info = ShapeOutsideInfoForNode(node, &paths, &bounds_quad)) { @@ -2083,7 +2071,7 @@ } // static -bool InspectorHighlight::BuildSVGQuads(Node* node, Vector<FloatQuad>& quads) { +bool InspectorHighlight::BuildSVGQuads(Node* node, Vector<gfx::QuadF>& quads) { LayoutObject* layout_object = node->GetLayoutObject(); if (!layout_object) return false; @@ -2102,16 +2090,16 @@ LocalFrameView* view = node->GetDocument().View(); if (!layout_object || !view) return false; - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; CollectQuads(node, quads); float scale = PageScaleFromFrameView(view); - for (FloatQuad& quad : quads) { - AdjustForAbsoluteZoom::AdjustFloatQuad(quad, *layout_object); + for (gfx::QuadF& quad : quads) { + AdjustForAbsoluteZoom::AdjustQuad(quad, *layout_object); quad.Scale(scale, scale); } *result = std::make_unique<protocol::Array<protocol::Array<double>>>(); - for (FloatQuad& quad : quads) + for (gfx::QuadF& quad : quads) (*result)->emplace_back(BuildArrayForQuad(quad)); return true; } @@ -2189,13 +2177,14 @@ if (!container_data) return nullptr; - FloatQuad snapport_quad = - layout_box->LocalToAbsoluteQuad(FloatQuad(container_data->rect())); + gfx::QuadF snapport_quad = + layout_box->LocalToAbsoluteQuad(gfx::QuadF(container_data->rect())); scroll_snap_info->setValue("snapport", BuildPathFromQuad(containing_view, snapport_quad)); auto padding_box = layout_box->PhysicalPaddingBoxRect(); - FloatQuad padding_box_quad = layout_box->LocalRectToAbsoluteQuad(padding_box); + gfx::QuadF padding_box_quad = + layout_box->LocalRectToAbsoluteQuad(padding_box); scroll_snap_info->setValue( "paddingBox", BuildPathFromQuad(containing_view, padding_box_quad)); @@ -2219,7 +2208,8 @@ std::unique_ptr<protocol::DictionaryValue> result_area = protocol::DictionaryValue::create(); - FloatQuad area_quad = layout_box->LocalToAbsoluteQuad(FloatQuad(data.rect)); + gfx::QuadF area_quad = + layout_box->LocalToAbsoluteQuad(gfx::QuadF(data.rect)); result_area->setValue("path", BuildPathFromQuad(containing_view, area_quad)); @@ -2230,7 +2220,7 @@ continue; auto* area_layout_box = area_node->GetLayoutBox(); - FloatQuad area_box_quad = area_layout_box->LocalRectToAbsoluteQuad( + gfx::QuadF area_box_quad = area_layout_box->LocalRectToAbsoluteQuad( area_layout_box->PhysicalBorderBoxRect()); result_area->setValue("borderBox", BuildPathFromQuad(containing_view, area_box_quad)); @@ -2266,15 +2256,15 @@ return scroll_snap_info; } -Vector<FloatQuad> GetContainerQueryingDescendantQuads(Element* container) { - Vector<FloatQuad> descendant_quads; +Vector<gfx::QuadF> GetContainerQueryingDescendantQuads(Element* container) { + Vector<gfx::QuadF> descendant_quads; for (Element* descendant : InspectorDOMAgent::GetContainerQueryingDescendants(container)) { LayoutBox* layout_box = descendant->GetLayoutBox(); if (!layout_box) continue; auto content_box = layout_box->PhysicalContentBoxRect(); - FloatQuad content_quad = layout_box->LocalRectToAbsoluteQuad(content_box); + gfx::QuadF content_quad = layout_box->LocalRectToAbsoluteQuad(content_box); descendant_quads.push_back(content_quad); } @@ -2302,7 +2292,7 @@ PathBuilder container_builder; auto content_box = layout_box->PhysicalContentBoxRect(); - FloatQuad content_quad = layout_box->LocalRectToAbsoluteQuad(content_box); + gfx::QuadF content_quad = layout_box->LocalRectToAbsoluteQuad(content_box); FrameQuadToViewport(containing_view, content_quad); container_builder.AppendPath(QuadToPath(content_quad), scale); container_query_container_info->setValue("containerBorder", @@ -2351,7 +2341,8 @@ auto isolated_element_info = protocol::DictionaryValue::create(); auto element_box = layout_box->PhysicalContentBoxRect(); - FloatQuad element_box_quad = layout_box->LocalRectToAbsoluteQuad(element_box); + gfx::QuadF element_box_quad = + layout_box->LocalRectToAbsoluteQuad(element_box); FrameQuadToViewport(containing_view, element_box_quad); isolated_element_info->setDouble("currentX", element_box_quad.p1().x()); isolated_element_info->setDouble("currentY", element_box_quad.p1().y());
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h index 53884fd7..0fed0dd6 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.h +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -9,10 +9,10 @@ #include "third_party/blink/renderer/core/dom/pseudo_element.h" #include "third_party/blink/renderer/core/inspector/node_content_visibility_state.h" #include "third_party/blink/renderer/core/inspector/protocol/dom.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -196,7 +196,7 @@ const Color& fill_color, const Color& outline_color, const String& name = String()); - void AppendQuad(const FloatQuad&, + void AppendQuad(const gfx::QuadF&, const Color& fill_color, const Color& outline_color = Color::kTransparent, const String& name = String()); @@ -205,10 +205,10 @@ protected: static bool BuildNodeQuads(Node*, - FloatQuad* content, - FloatQuad* padding, - FloatQuad* border, - FloatQuad* margin); + gfx::QuadF* content, + gfx::QuadF* padding, + gfx::QuadF* border, + gfx::QuadF* margin); std::unique_ptr<protocol::ListValue> highlight_paths_; float scale_; }; @@ -254,7 +254,7 @@ std::unique_ptr<protocol::DictionaryValue> AsProtocolValue() const override; private: - static bool BuildSVGQuads(Node*, Vector<FloatQuad>& quads); + static bool BuildSVGQuads(Node*, Vector<gfx::QuadF>& quads); void AppendNodeHighlight(Node*, const InspectorHighlightConfig&); void AppendPathsForShapeOutside(Node*, const InspectorHighlightConfig&);
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index 6ec2d9f..04e49b8 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -101,7 +101,7 @@ namespace { bool ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array, - FloatQuad* quad) { + gfx::QuadF* quad) { const size_t kCoordinatesInQuad = 8; if (!quad_array || quad_array->size() != kCoordinatesInQuad) return false; @@ -227,7 +227,7 @@ // Hinge ----------------------------------------------------------------------- -Hinge::Hinge(FloatQuad quad, +Hinge::Hinge(gfx::QuadF quad, Color content_color, Color outline_color, InspectorOverlayAgent* overlay) @@ -607,8 +607,8 @@ int height, Maybe<protocol::DOM::RGBA> color, Maybe<protocol::DOM::RGBA> outline_color) { - std::unique_ptr<FloatQuad> quad = - std::make_unique<FloatQuad>(gfx::RectF(x, y, width, height)); + std::unique_ptr<gfx::QuadF> quad = + std::make_unique<gfx::QuadF>(gfx::RectF(x, y, width, height)); return SetInspectTool(MakeGarbageCollected<QuadHighlightTool>( this, GetFrontend(), std::move(quad), InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)), @@ -619,7 +619,7 @@ std::unique_ptr<protocol::Array<double>> quad_array, Maybe<protocol::DOM::RGBA> color, Maybe<protocol::DOM::RGBA> outline_color) { - std::unique_ptr<FloatQuad> quad = std::make_unique<FloatQuad>(); + std::unique_ptr<gfx::QuadF> quad = std::make_unique<gfx::QuadF>(); if (!ParseQuad(std::move(quad_array), quad.get())) return Response::ServerError("Invalid Quad format"); return SetInspectTool(MakeGarbageCollected<QuadHighlightTool>( @@ -660,7 +660,7 @@ DCHECK(frame_impl_->GetFrameView() && GetFrame()); - FloatQuad quad(gfx::RectF(x, y, width, height)); + gfx::QuadF quad(gfx::RectF(x, y, width, height)); hinge_ = MakeGarbageCollected<Hinge>(quad, content_color, outline_color, this);
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h index ec4259a..13e2cc7 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -44,12 +44,12 @@ #include "third_party/blink/renderer/core/inspector/inspector_highlight.h" #include "third_party/blink/renderer/core/inspector/inspector_overlay_host.h" #include "third_party/blink/renderer/core/inspector/protocol/overlay.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/geometry/quad_f.h" namespace cc { class Layer; @@ -124,7 +124,7 @@ class CORE_EXPORT Hinge final : public GarbageCollected<Hinge> { public: - Hinge(FloatQuad quad, + Hinge(gfx::QuadF quad, Color color, Color outline_color, InspectorOverlayAgent* overlay); @@ -136,7 +136,7 @@ void Trace(Visitor* visitor) const; private: - FloatQuad quad_; + gfx::QuadF quad_; Color content_color_; Color outline_color_; Member<InspectorOverlayAgent> overlay_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index 96cbd46..44d0aba 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -661,7 +661,7 @@ SetCallStack(dict); } -static void CreateQuad(perfetto::TracedValue context, const FloatQuad& quad) { +static void CreateQuad(perfetto::TracedValue context, const gfx::QuadF& quad) { auto array = std::move(context).WriteArray(); array.Append(quad.p1().x()); array.Append(quad.p1().y()); @@ -692,7 +692,7 @@ auto dict = std::move(context).WriteDictionary(); SetGeneratingNodeInfo(dict, layout_root.object, "nodeId"); dict.Add("depth", static_cast<int>(layout_root.depth)); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; layout_root.object->AbsoluteQuads(quads); if (quads.size() > kMaxQuads) quads.Shrink(kMaxQuads); @@ -1111,7 +1111,7 @@ void inspector_paint_event::Data(perfetto::TracedValue context, Frame* frame, const LayoutObject* layout_object, - const FloatQuad& quad, + const gfx::QuadF& quad, int layer_id) { auto dict = std::move(context).WriteDictionary(); dict.Add("frame", IdentifiersFactory::FrameId(frame)); @@ -1348,9 +1348,11 @@ } void inspector_invalidate_layout_event::Data(perfetto::TracedValue context, - LocalFrame* frame) { + LocalFrame* frame, + DOMNodeId nodeId) { auto dict = std::move(context).WriteDictionary(); dict.Add("frame", IdentifiersFactory::FrameId(frame)); + dict.Add("nodeId", nodeId); SetCallStack(dict); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/third_party/blink/renderer/core/inspector/inspector_trace_events.h index 2bcac832..4c49f105 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.h +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -29,6 +29,7 @@ namespace gfx { class RectF; +class QuadF; } namespace v8 { @@ -51,7 +52,6 @@ class EncodedFormData; class Event; class ExecutionContext; -class FloatQuad; class Frame; class HitTestLocation; class HitTestRequest; @@ -435,7 +435,7 @@ void Data(perfetto::TracedValue context, Frame*, const LayoutObject*, - const FloatQuad& quad, + const gfx::QuadF& quad, int layer_id); } @@ -527,7 +527,7 @@ } namespace inspector_invalidate_layout_event { -void Data(perfetto::TracedValue context, LocalFrame*); +void Data(perfetto::TracedValue context, LocalFrame*, DOMNodeId); } namespace inspector_recalculate_styles_event {
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc index 41d5173..d977e59 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -382,11 +382,11 @@ implicit_root_to_target_document_transform.AccumulatedTransform() .Inverse(); intersection_rect_ = PhysicalRect::EnclosingRect( - matrix.ProjectQuad(FloatQuad(gfx::RectF(intersection_rect_))) + matrix.ProjectQuad(gfx::QuadF(gfx::RectF(intersection_rect_))) .BoundingBox()); unclipped_intersection_rect_ = PhysicalRect::EnclosingRect( matrix - .ProjectQuad(FloatQuad(gfx::RectF(unclipped_intersection_rect_))) + .ProjectQuad(gfx::QuadF(gfx::RectF(unclipped_intersection_rect_))) .BoundingBox()); // intersection_rect_ is in the coordinate system of the implicit root; // map it down the to absolute coordinates for the target's document. @@ -396,11 +396,11 @@ // same as root's document). intersection_rect_ = PhysicalRect::EnclosingRect( root_geometry.root_to_document_transform - .MapQuad(FloatQuad(gfx::RectF(intersection_rect_))) + .MapQuad(gfx::QuadF(gfx::RectF(intersection_rect_))) .BoundingBox()); unclipped_intersection_rect_ = PhysicalRect::EnclosingRect( root_geometry.root_to_document_transform - .MapQuad(FloatQuad(gfx::RectF(unclipped_intersection_rect_))) + .MapQuad(gfx::QuadF(gfx::RectF(unclipped_intersection_rect_))) .BoundingBox()); } } else { @@ -409,7 +409,7 @@ // Map root_rect_ from root's coordinate system to absolute coordinates. root_rect_ = PhysicalRect::EnclosingRect( root_geometry.root_to_document_transform - .MapQuad(FloatQuad(gfx::RectF(root_rect_))) + .MapQuad(gfx::QuadF(gfx::RectF(root_rect_))) .BoundingBox()); // Some corner cases for threshold index:
diff --git a/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h b/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h index 5a30ca4..73f4e092 100644 --- a/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h +++ b/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h
@@ -86,8 +86,8 @@ AdjustLayoutUnit(size.height, style)); } - inline static void AdjustFloatQuad(FloatQuad& quad, - const LayoutObject& layout_object) { + inline static void AdjustQuad(gfx::QuadF& quad, + const LayoutObject& layout_object) { float zoom = layout_object.StyleRef().EffectiveZoom(); if (zoom != 1) quad.Scale(1 / zoom, 1 / zoom);
diff --git a/third_party/blink/renderer/core/layout/geometry/transform_state.cc b/third_party/blink/renderer/core/layout/geometry/transform_state.cc index faa9dbf5..013497e8 100644 --- a/third_party/blink/renderer/core/layout/geometry/transform_state.cc +++ b/third_party/blink/renderer/core/layout/geometry/transform_state.cc
@@ -64,7 +64,7 @@ if (map_point_) last_planar_point_ += adjusted_offset; if (map_quad_) - last_planar_quad_.Move(adjusted_offset); + last_planar_quad_ += adjusted_offset; } void TransformState::Move(const PhysicalOffset& offset, @@ -171,11 +171,11 @@ return PhysicalOffset::FromPointFRound(point); } -FloatQuad TransformState::MappedQuad() const { - FloatQuad quad = last_planar_quad_; - quad.Move(gfx::Vector2dF((direction_ == kApplyTransformDirection) - ? accumulated_offset_ - : -accumulated_offset_)); +gfx::QuadF TransformState::MappedQuad() const { + gfx::QuadF quad = last_planar_quad_; + quad += gfx::Vector2dF((direction_ == kApplyTransformDirection) + ? accumulated_offset_ + : -accumulated_offset_); if (!accumulated_transform_) return quad;
diff --git a/third_party/blink/renderer/core/layout/geometry/transform_state.h b/third_party/blink/renderer/core/layout/geometry/transform_state.h index 555e256..ecd912c 100644 --- a/third_party/blink/renderer/core/layout/geometry/transform_state.h +++ b/third_party/blink/renderer/core/layout/geometry/transform_state.h
@@ -29,13 +29,13 @@ #include <memory> #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_point.h" #include "third_party/blink/renderer/platform/geometry/layout_size.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -58,7 +58,7 @@ TransformState(TransformDirection mapping_direction, const gfx::PointF& p, - const FloatQuad& quad) + const gfx::QuadF& quad) : last_planar_point_(p), last_planar_quad_(quad), force_accumulating_transform_(false), @@ -73,7 +73,7 @@ map_quad_(false), direction_(mapping_direction) {} - TransformState(TransformDirection mapping_direction, const FloatQuad& quad) + TransformState(TransformDirection mapping_direction, const gfx::QuadF& quad) : last_planar_quad_(quad), force_accumulating_transform_(false), map_point_(false), @@ -94,7 +94,7 @@ // Note: this overrides the quad and ignores any accumulatedOffset. // If it's desired to include the offset, call flatten() first. - void SetQuad(const FloatQuad& quad) { + void SetQuad(const gfx::QuadF& quad) { DCHECK(!accumulated_transform_ || accumulated_transform_->IsIdentity()); // FIXME: this assumes that the quad being added is in the coordinate system // of the current state. This breaks if we're simultaneously mapping a @@ -114,11 +114,11 @@ // Return the coords of the point or quad in the last flattened layer gfx::PointF LastPlanarPoint() const { return last_planar_point_; } - FloatQuad LastPlanarQuad() const { return last_planar_quad_; } + gfx::QuadF LastPlanarQuad() const { return last_planar_quad_; } // Return the point or quad mapped through the current transform PhysicalOffset MappedPoint() const; - FloatQuad MappedQuad() const; + gfx::QuadF MappedQuad() const; // Return the accumulated transform. const TransformationMatrix& AccumulatedTransform() const; @@ -130,7 +130,7 @@ void ApplyAccumulatedOffset(); gfx::PointF last_planar_point_; - FloatQuad last_planar_quad_; + gfx::QuadF last_planar_quad_; // We only allocate the transform if we need to std::unique_ptr<TransformationMatrix> accumulated_transform_;
diff --git a/third_party/blink/renderer/core/layout/hit_test_location.cc b/third_party/blink/renderer/core/layout/hit_test_location.cc index 522ec06..d80bf50 100644 --- a/third_party/blink/renderer/core/layout/hit_test_location.cc +++ b/third_party/blink/renderer/core/layout/hit_test_location.cc
@@ -60,7 +60,7 @@ : HitTestLocation(gfx::PointF(point)) {} HitTestLocation::HitTestLocation(const gfx::PointF& point, - const FloatQuad& quad) + const gfx::QuadF& quad) : transformed_point_(point), transformed_rect_(quad), is_rect_based_(true) { point_ = PhysicalOffset::FromPointFFloor(point); bounding_box_ = PhysicalRect::EnclosingRect(quad.BoundingBox()); @@ -73,7 +73,7 @@ transformed_point_(point_), is_rect_based_(true), is_rectilinear_(true) { - transformed_rect_ = FloatQuad(gfx::RectF(bounding_box_)); + transformed_rect_ = gfx::QuadF(gfx::RectF(bounding_box_)); } HitTestLocation::HitTestLocation(const HitTestLocation& other, @@ -106,7 +106,7 @@ point_ += offset; bounding_box_.Move(offset); transformed_point_ += gfx::Vector2dF(offset); - transformed_rect_.Move(gfx::Vector2dF(offset)); + transformed_rect_ += gfx::Vector2dF(offset); } bool HitTestLocation::Intersects(const PhysicalRect& rect) const { @@ -142,16 +142,16 @@ return rect.IntersectsQuad(transformed_rect_); } -bool HitTestLocation::Intersects(const FloatQuad& quad) const { +bool HitTestLocation::Intersects(const gfx::QuadF& quad) const { // TODO(chrishtr): if the quads are not rectilinear, calling Intersects // has false positives. if (is_rect_based_) return Intersects(quad.BoundingBox()); - return quad.ContainsPoint(gfx::PointF(point_)); + return quad.Contains(gfx::PointF(point_)); } bool HitTestLocation::ContainsPoint(const gfx::PointF& point) const { - return transformed_rect_.ContainsPoint(point); + return transformed_rect_.Contains(point); } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/hit_test_location.h b/third_party/blink/renderer/core/layout/hit_test_location.h index ecb19cd..8e8c217 100644 --- a/third_party/blink/renderer/core/layout/hit_test_location.h +++ b/third_party/blink/renderer/core/layout/hit_test_location.h
@@ -25,9 +25,9 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -50,7 +50,7 @@ explicit HitTestLocation(const gfx::Point&); explicit HitTestLocation(const gfx::PointF&); explicit HitTestLocation(const DoublePoint&); - explicit HitTestLocation(const gfx::PointF&, const FloatQuad&); + explicit HitTestLocation(const gfx::PointF&, const gfx::QuadF&); explicit HitTestLocation(const PhysicalRect&); // The bounding box isn't always a 1x1 rect even when the hit test is not @@ -89,11 +89,11 @@ // (see LayoutRect::InclusiveIntersect for a definition) bool Intersects(const gfx::RectF&) const; bool Intersects(const FloatRoundedRect&) const; - bool Intersects(const FloatQuad&) const; + bool Intersects(const gfx::QuadF&) const; bool ContainsPoint(const gfx::PointF&) const; const gfx::PointF& TransformedPoint() const { return transformed_point_; } - const FloatQuad& TransformedRect() const { return transformed_rect_; } + const gfx::QuadF& TransformedRect() const { return transformed_rect_; } private: void Move(const PhysicalOffset& offset); @@ -104,7 +104,7 @@ PhysicalRect bounding_box_; gfx::PointF transformed_point_; - FloatQuad transformed_rect_; + gfx::QuadF transformed_rect_; // Index of fragment (FragmentData) to hit-test. If it's -1, all fragments // will be hit-tested. This is used to hit test items inside one NG block
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.cc b/third_party/blink/renderer/core/layout/hit_test_result.cc index 35ec70a0..3e7e87c 100644 --- a/third_party/blink/renderer/core/layout/hit_test_result.cc +++ b/third_party/blink/renderer/core/layout/hit_test_result.cc
@@ -52,6 +52,7 @@ #include "third_party/blink/renderer/core/svg/svg_element.h" #include "third_party/blink/renderer/platform/geometry/region.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace blink { @@ -391,10 +392,10 @@ gfx::Rect HitTestResult::ImageRect() const { if (!GetImage()) return gfx::Rect(); - return InnerNodeOrImageMapImage() - ->GetLayoutBox() - ->AbsoluteContentQuad() - .EnclosingBoundingBox(); + return gfx::ToEnclosingRect(InnerNodeOrImageMapImage() + ->GetLayoutBox() + ->AbsoluteContentQuad() + .BoundingBox()); } KURL HitTestResult::AbsoluteImageURL(const Node* node) { @@ -524,14 +525,14 @@ ListBasedHitTestBehavior HitTestResult::AddNodeToListBasedTestResult( Node* node, const HitTestLocation& location, - const FloatQuad& quad) { + const gfx::QuadF& quad) { bool should_check_containment; ListBasedHitTestBehavior behavior; std::tie(should_check_containment, behavior) = AddNodeToListBasedTestResultInternal(node, location); if (!should_check_containment) return behavior; - return quad.ContainsQuad(FloatQuad(gfx::RectF(location.BoundingBox()))) + return quad.ContainsQuad(gfx::QuadF(gfx::RectF(location.BoundingBox()))) ? kStopHitTesting : kContinueHitTesting; }
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.h b/third_party/blink/renderer/core/layout/hit_test_result.h index 1fa85b5..a81a558 100644 --- a/third_party/blink/renderer/core/layout/hit_test_result.h +++ b/third_party/blink/renderer/core/layout/hit_test_result.h
@@ -29,7 +29,6 @@ #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" #include "third_party/blink/renderer/core/layout/hit_test_location.h" #include "third_party/blink/renderer/core/layout/hit_test_request.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -37,6 +36,7 @@ #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector_traits.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -181,7 +181,7 @@ const PhysicalRect& = PhysicalRect()); ListBasedHitTestBehavior AddNodeToListBasedTestResult(Node*, const HitTestLocation&, - const FloatQuad& quad); + const gfx::QuadF& quad); ListBasedHitTestBehavior AddNodeToListBasedTestResult(Node*, const HitTestLocation&, const Region&);
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index 311a9d3..d3b0bbbe 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -2488,7 +2488,7 @@ AddLayoutOverflowFromFloats(); } -void LayoutBlockFlow::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutBlockFlow::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); if (!IsAnonymousBlockContinuation()) { @@ -2498,16 +2498,16 @@ LayoutBoxModelObject::AbsoluteQuads(quads, mode); } -void LayoutBlockFlow::LocalQuadsForSelf(Vector<FloatQuad>& quads) const { +void LayoutBlockFlow::LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const { return QuadsForSelfInternal(quads, 0, false); } -void LayoutBlockFlow::AbsoluteQuadsForSelf(Vector<FloatQuad>& quads, +void LayoutBlockFlow::AbsoluteQuadsForSelf(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { return QuadsForSelfInternal(quads, mode, true); } -void LayoutBlockFlow::QuadsForSelfInternal(Vector<FloatQuad>& quads, +void LayoutBlockFlow::QuadsForSelfInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const { NOT_DESTROYED(); @@ -2521,7 +2521,7 @@ if (map_to_absolute) quads.push_back(LocalRectToAbsoluteQuad(local_rect, mode)); else - quads.push_back(FloatQuad(gfx::RectF(local_rect))); + quads.push_back(gfx::QuadF(gfx::RectF(local_rect))); } RootInlineBox* LayoutBlockFlow::CreateAndAppendRootInlineBox() {
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h index 0a46751..c433e20 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.h +++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -561,10 +561,10 @@ void UpdateBlockChildDirtyBitsBeforeLayout(bool relayout_children, LayoutBox&); - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const override; - void LocalQuadsForSelf(Vector<FloatQuad>& quads) const override; - void AbsoluteQuadsForSelf(Vector<FloatQuad>& quads, + void LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const override; + void AbsoluteQuadsForSelf(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode = 0) const override; LayoutUnit LogicalRightOffsetForLine( @@ -613,7 +613,7 @@ PhysicalOffset AccumulateRelativePositionOffsets() const override; private: - void QuadsForSelfInternal(Vector<FloatQuad>& quads, + void QuadsForSelfInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const;
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc index 02433a7a..e0d23d7 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -708,7 +708,7 @@ } break; } - FALLTHROUGH; + [[fallthrough]]; case ETextAlign::kStart: if (direction == TextDirection::kLtr) { UpdateLogicalWidthForLeftAlignedBlock(
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index e05fc87..313051cc 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -108,12 +108,12 @@ #include "third_party/blink/renderer/core/style/computed_style_base_constants.h" #include "third_party/blink/renderer/core/style/shadow_list.h" #include "third_party/blink/renderer/platform/geometry/double_rect.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/wtf/size_assertions.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -903,7 +903,9 @@ const ComputedStyle& style_to_use = StyleRef(); SetFloating(style_to_use.IsFloating() && !IsOutOfFlowPositioned() && !style_to_use.IsFlexOrGridItem()); - SetHasTransformRelatedProperty(style_to_use.HasTransformRelatedProperty()); + SetHasTransformRelatedProperty( + IsSVGChild() ? style_to_use.HasTransformRelatedPropertyForSVG() + : style_to_use.HasTransformRelatedProperty()); SetHasReflection(style_to_use.BoxReflect()); // LayoutTable and LayoutTableCell will overwrite this flag if needed. SetHasNonCollapsedBorderDecoration(style_to_use.HasBorderDecoration()); @@ -1211,7 +1213,7 @@ margin_box_outsets_.SetLeft(box.left); } -void LayoutBox::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutBox::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); if (LayoutFlowThread* flow_thread = FlowThreadContainingBlock()) { @@ -1525,7 +1527,7 @@ } } -FloatQuad LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const { +gfx::QuadF LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const { NOT_DESTROYED(); PhysicalRect rect = PhysicalContentBoxRect(); return LocalRectToAbsoluteQuad(rect, flags); @@ -2054,8 +2056,8 @@ // using TransformState::kAccumulateTransform?) if (!StyleRef().Preserves3D()) { transform_state.Flatten(); - transform_state.SetQuad( - FloatQuad(transform_state.LastPlanarQuad().EnclosingBoundingBox())); + transform_state.SetQuad(gfx::QuadF(gfx::RectF( + gfx::ToEnclosingRect(transform_state.LastPlanarQuad().BoundingBox())))); } // 2. Generate transformation matrix. @@ -2155,7 +2157,8 @@ PhysicalRect clip_rect = ClippingRect(PhysicalOffset()); transform_state.Flatten(); - PhysicalRect rect(transform_state.LastPlanarQuad().EnclosingBoundingBox()); + PhysicalRect rect( + gfx::ToEnclosingRect(transform_state.LastPlanarQuad().BoundingBox())); bool does_intersect; if (visual_rect_flags & kEdgeInclusive) { does_intersect = rect.InclusiveIntersect(clip_rect); @@ -2163,7 +2166,7 @@ rect.Intersect(clip_rect); does_intersect = !rect.IsEmpty(); } - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return does_intersect; } @@ -4147,7 +4150,7 @@ PhysicalRect rect = PhysicalRect::EnclosingRect( transform_state.LastPlanarQuad().BoundingBox()); transform_state.SetQuad( - FloatQuad(gfx::RectF(Layer()->MapRectForFilter(rect)))); + gfx::QuadF(gfx::RectF(Layer()->MapRectForFilter(rect)))); } static bool ShouldRecalculateMinMaxWidthsAffectedByAncestor( @@ -6938,7 +6941,7 @@ // Otherwise find the closest fragment. const LayoutUnit square_distance = distance.width * distance.width + distance.height * distance.height; - if (square_distance < shortest_square_distance) { + if (square_distance < shortest_square_distance || !closest_fragment) { shortest_square_distance = square_distance; closest_fragment = &fragment; closest_fragment_offset = fragment_offset;
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index fdc36f4b..ab50898f 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -515,7 +515,7 @@ } // The content box converted to absolute coords (taking transforms into // account). - FloatQuad AbsoluteContentQuad(MapCoordinatesFlags = 0) const; + gfx::QuadF AbsoluteContentQuad(MapCoordinatesFlags = 0) const; // The enclosing rectangle of the background with given opacity requirement. // TODO(crbug.com/877518): Some callers of this method may actually want @@ -981,7 +981,7 @@ CollapsedMarginAfter(), LayoutUnit()); } - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const override; gfx::RectF LocalBoundingBoxRectForAccessibility() const override;
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index 25781a0..6d97be7 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -533,27 +533,27 @@ } void LayoutBoxModelObject::AbsoluteQuadsForSelf( - Vector<FloatQuad>& quads, + Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); NOTREACHED(); } -void LayoutBoxModelObject::LocalQuadsForSelf(Vector<FloatQuad>& quads) const { +void LayoutBoxModelObject::LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const { NOT_DESTROYED(); NOTREACHED(); } -void LayoutBoxModelObject::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutBoxModelObject::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { QuadsInternal(quads, mode, true); } -void LayoutBoxModelObject::LocalQuads(Vector<FloatQuad>& quads) const { +void LayoutBoxModelObject::LocalQuads(Vector<gfx::QuadF>& quads) const { QuadsInternal(quads, 0, false); } -void LayoutBoxModelObject::QuadsInternal(Vector<FloatQuad>& quads, +void LayoutBoxModelObject::QuadsInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const { NOT_DESTROYED(); @@ -581,7 +581,7 @@ gfx::RectF LayoutBoxModelObject::LocalBoundingBoxRectF() const { NOT_DESTROYED(); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; LocalQuads(quads); wtf_size_t n = quads.size();
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index 247e67b..43711e8 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -537,9 +537,9 @@ // Same as AbsoluteQuads, but in the local border box coordinates of this // object. - void LocalQuads(Vector<FloatQuad>& quads) const; + void LocalQuads(Vector<gfx::QuadF>& quads) const; - void AbsoluteQuads(Vector<FloatQuad>& quads, + void AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode = 0) const override; // Returns the bounodiong box of all quads returned by LocalQuads. @@ -581,10 +581,10 @@ // Compute absolute quads for |this|, but not any continuations. May only be // called for objects which can be or have continuations, i.e. LayoutInline or // LayoutBlockFlow. - virtual void AbsoluteQuadsForSelf(Vector<FloatQuad>& quads, + virtual void AbsoluteQuadsForSelf(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode = 0) const; // Same as AbsoluteQuadsForSelf, but in the local border box coordinates. - virtual void LocalQuadsForSelf(Vector<FloatQuad>& quads) const; + virtual void LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const; void WillBeDestroyed() override; @@ -673,7 +673,7 @@ bool full_remove_insert = false); private: - void QuadsInternal(Vector<FloatQuad>& quads, + void QuadsInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const;
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc index d1408ff..92e3ce4 100644 --- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc +++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -341,7 +341,7 @@ PhysicalRect replaced_rect = ReplacedContentRect(); TransformState transform_state(TransformState::kApplyTransformDirection, gfx::PointF(), - FloatQuad(gfx::RectF(replaced_rect))); + gfx::QuadF(gfx::RectF(replaced_rect))); MapLocalToAncestor(nullptr, transform_state, 0); transform_state.Flatten(); PhysicalOffset absolute_location =
diff --git a/third_party/blink/renderer/core/layout/layout_flow_thread.cc b/third_party/blink/renderer/core/layout/layout_flow_thread.cc index 6b403a6..35ddac2 100644 --- a/third_party/blink/renderer/core/layout/layout_flow_thread.cc +++ b/third_party/blink/renderer/core/layout/layout_flow_thread.cc
@@ -132,7 +132,7 @@ transform_state.Flatten(); LayoutRect rect(transform_state.LastPlanarQuad().BoundingBox()); rect = FragmentsBoundingBox(rect); - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return LayoutBlockFlow::MapToVisualRectInAncestorSpaceInternal( ancestor, transform_state, visual_rect_flags); } @@ -171,7 +171,7 @@ } void LayoutFlowThread::AbsoluteQuadsForDescendant(const LayoutBox& descendant, - Vector<FloatQuad>& quads, + Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) { NOT_DESTROYED(); LayoutPoint offset_from_flow_thread;
diff --git a/third_party/blink/renderer/core/layout/layout_flow_thread.h b/third_party/blink/renderer/core/layout/layout_flow_thread.h index 097d9cb..a1e168ad 100644 --- a/third_party/blink/renderer/core/layout/layout_flow_thread.h +++ b/third_party/blink/renderer/core/layout/layout_flow_thread.h
@@ -139,7 +139,7 @@ } void AbsoluteQuadsForDescendant(const LayoutBox& descendant, - Vector<FloatQuad>&, + Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0); void AddOutlineRects(Vector<PhysicalRect>&,
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index 16946dc5..51f625f5 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -49,9 +49,9 @@ #include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/outline_painter.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/region.h" #include "third_party/blink/renderer/platform/wtf/size_assertions.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -1004,16 +1004,16 @@ return false; } -void LayoutInline::LocalQuadsForSelf(Vector<FloatQuad>& quads) const { +void LayoutInline::LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const { QuadsForSelfInternal(quads, 0, false); } -void LayoutInline::AbsoluteQuadsForSelf(Vector<FloatQuad>& quads, +void LayoutInline::AbsoluteQuadsForSelf(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { QuadsForSelfInternal(quads, mode, true); } -void LayoutInline::QuadsForSelfInternal(Vector<FloatQuad>& quads, +void LayoutInline::QuadsForSelfInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const { NOT_DESTROYED(); @@ -1033,10 +1033,10 @@ mapping_to_absolute.emplace(LocalToAbsoluteTransform(mode)); } if (transform_depends_on_point) { - quads.push_back(LocalToAbsoluteQuad(FloatQuad(gfx::RectF(rect)), mode)); + quads.push_back(LocalToAbsoluteQuad(gfx::QuadF(gfx::RectF(rect)), mode)); } else { quads.push_back( - mapping_to_absolute->MapQuad(FloatQuad(gfx::RectF(rect)))); + mapping_to_absolute->MapQuad(gfx::QuadF(gfx::RectF(rect)))); } }; @@ -1045,13 +1045,13 @@ if (map_to_absolute) PushAbsoluteQuad(rect); else - quads.push_back(FloatQuad(gfx::RectF(rect))); + quads.push_back(gfx::QuadF(gfx::RectF(rect))); }); if (quads.IsEmpty()) { if (map_to_absolute) PushAbsoluteQuad(PhysicalRect()); else - quads.push_back(FloatQuad()); + quads.push_back(gfx::QuadF()); } }
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h index d84aa142..09af0af 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.h +++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -286,8 +286,8 @@ void InvalidateDisplayItemClients(PaintInvalidationReason) const override; - void LocalQuadsForSelf(Vector<FloatQuad>& quads) const override; - void AbsoluteQuadsForSelf(Vector<FloatQuad>& quads, + void LocalQuadsForSelf(Vector<gfx::QuadF>& quads) const override; + void AbsoluteQuadsForSelf(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode = 0) const override; PhysicalOffset OffsetFromContainerInternal( @@ -296,7 +296,7 @@ private: bool AbsoluteTransformDependsOnPoint(const LayoutObject& object) const; - void QuadsForSelfInternal(Vector<FloatQuad>& quads, + void QuadsForSelfInternal(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode, bool map_to_absolute) const;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index b5c597be..97c0f8e 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1627,7 +1627,7 @@ MapCoordinatesFlags flags) const { NOT_DESTROYED(); DCHECK(!(flags & kIgnoreTransforms)); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; AbsoluteQuads(quads, flags); wtf_size_t n = quads.size(); @@ -1644,17 +1644,17 @@ MapCoordinatesFlags flags) const { NOT_DESTROYED(); DCHECK(!(flags & kIgnoreTransforms)); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; AbsoluteQuads(quads, flags); wtf_size_t n = quads.size(); if (!n) return gfx::Rect(); - gfx::Rect result = quads[0].EnclosingBoundingBox(); - for (wtf_size_t i = 1; i < n; ++i) - result.Union(quads[i].EnclosingBoundingBox()); - return result; + gfx::RectF result; + for (auto& quad : quads) + result.Union(quad.BoundingBox()); + return gfx::ToEnclosingRect(result); } PhysicalRect LayoutObject::AbsoluteBoundingBoxRectHandlingEmptyInline( @@ -1942,7 +1942,7 @@ return intersects; TransformState transform_state(TransformState::kApplyTransformDirection, - FloatQuad(gfx::RectF(rect))); + gfx::QuadF(gfx::RectF(rect))); intersects = MapToVisualRectInAncestorSpaceInternal(ancestor, transform_state, visual_rect_flags); transform_state.Flatten(); @@ -3193,9 +3193,9 @@ return transform_state.LastPlanarPoint(); } -FloatQuad LayoutObject::AncestorToLocalQuad( +gfx::QuadF LayoutObject::AncestorToLocalQuad( const LayoutBoxModelObject* ancestor, - const FloatQuad& quad, + const gfx::QuadF& quad, MapCoordinatesFlags mode) const { NOT_DESTROYED(); TransformState transform_state( @@ -3481,12 +3481,12 @@ return result; return PhysicalRect::EnclosingRect( - LocalToAncestorQuad(FloatQuad(gfx::RectF(rect)), ancestor, mode) + LocalToAncestorQuad(gfx::QuadF(gfx::RectF(rect)), ancestor, mode) .BoundingBox()); } -FloatQuad LayoutObject::LocalToAncestorQuad( - const FloatQuad& local_quad, +gfx::QuadF LayoutObject::LocalToAncestorQuad( + const gfx::QuadF& local_quad, const LayoutBoxModelObject* ancestor, MapCoordinatesFlags mode) const { NOT_DESTROYED(); @@ -3512,8 +3512,8 @@ for (wtf_size_t i = 0; i < rects.size(); ++i) { PhysicalRect& rect = rects[i]; rect.Move(pre_offset); - FloatQuad container_quad = - LocalToAncestorQuad(FloatQuad(gfx::RectF(rect)), ancestor); + gfx::QuadF container_quad = + LocalToAncestorQuad(gfx::QuadF(gfx::RectF(rect)), ancestor); PhysicalRect container_rect = PhysicalRect::EnclosingRect(container_quad.BoundingBox()); if (container_rect.IsEmpty()) {
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index f60cef5..f22d872 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -56,7 +56,6 @@ #include "third_party/blink/renderer/core/paint/paint_phase.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/style_difference.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/compositing_reasons.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" @@ -65,6 +64,7 @@ #include "third_party/blink/renderer/platform/graphics/subtree_paint_property_update_reason.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "ui/gfx/geometry/quad_f.h" namespace ui { class Cursor; @@ -1712,10 +1712,23 @@ NOT_DESTROYED(); return bitfields_.HasTransformRelatedProperty(); } + // Compared to StyleRef().HasTransform(), this excludes objects that ignore + // transform-related styles (e.g. LayoutInline). + bool HasTransform() const { + NOT_DESTROYED(); + return HasTransformRelatedProperty() && StyleRef().HasTransform(); + } + // Similar to the above. + bool Preserves3D() const { + NOT_DESTROYED(); + return HasTransformRelatedProperty() && StyleRef().Preserves3D() && + !IsSVGChild(); + } bool IsTransformApplicable() const { NOT_DESTROYED(); return IsBox() || IsSVG(); } + bool HasMask() const { NOT_DESTROYED(); return StyleRef().HasMask(); @@ -2378,12 +2391,12 @@ MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); return PhysicalRect::EnclosingRect( - AncestorToLocalQuad(ancestor, FloatQuad(gfx::RectF(rect)), mode) + AncestorToLocalQuad(ancestor, gfx::QuadF(gfx::RectF(rect)), mode) .BoundingBox()); } - FloatQuad AncestorToLocalQuad(const LayoutBoxModelObject*, - const FloatQuad&, - MapCoordinatesFlags mode = 0) const; + gfx::QuadF AncestorToLocalQuad(const LayoutBoxModelObject*, + const gfx::QuadF&, + MapCoordinatesFlags mode = 0) const; PhysicalOffset AncestorToLocalPoint(const LayoutBoxModelObject* ancestor, const PhysicalOffset& p, MapCoordinatesFlags mode = 0) const { @@ -2410,15 +2423,15 @@ PhysicalRect LocalToAncestorRect(const PhysicalRect& rect, const LayoutBoxModelObject* ancestor, MapCoordinatesFlags mode = 0) const; - FloatQuad LocalRectToAncestorQuad(const PhysicalRect& rect, - const LayoutBoxModelObject* ancestor, - MapCoordinatesFlags mode = 0) const { + gfx::QuadF LocalRectToAncestorQuad(const PhysicalRect& rect, + const LayoutBoxModelObject* ancestor, + MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); - return LocalToAncestorQuad(FloatQuad(gfx::RectF(rect)), ancestor, mode); + return LocalToAncestorQuad(gfx::QuadF(gfx::RectF(rect)), ancestor, mode); } - FloatQuad LocalToAncestorQuad(const FloatQuad&, - const LayoutBoxModelObject* ancestor, - MapCoordinatesFlags = 0) const; + gfx::QuadF LocalToAncestorQuad(const gfx::QuadF&, + const LayoutBoxModelObject* ancestor, + MapCoordinatesFlags = 0) const; PhysicalOffset LocalToAncestorPoint(const PhysicalOffset& p, const LayoutBoxModelObject* ancestor, MapCoordinatesFlags mode = 0) const { @@ -2456,13 +2469,13 @@ NOT_DESTROYED(); return LocalToAncestorRect(rect, nullptr, mode); } - FloatQuad LocalRectToAbsoluteQuad(const PhysicalRect& rect, - MapCoordinatesFlags mode = 0) const { + gfx::QuadF LocalRectToAbsoluteQuad(const PhysicalRect& rect, + MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); return LocalRectToAncestorQuad(rect, nullptr, mode); } - FloatQuad LocalToAbsoluteQuad(const FloatQuad& quad, - MapCoordinatesFlags mode = 0) const { + gfx::QuadF LocalToAbsoluteQuad(const gfx::QuadF& quad, + MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); return LocalToAncestorQuad(quad, nullptr, mode); } @@ -2481,8 +2494,8 @@ NOT_DESTROYED(); return AncestorToLocalRect(nullptr, rect, mode); } - FloatQuad AbsoluteToLocalQuad(const FloatQuad& quad, - MapCoordinatesFlags mode = 0) const { + gfx::QuadF AbsoluteToLocalQuad(const gfx::QuadF& quad, + MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); return AncestorToLocalQuad(nullptr, quad, mode); } @@ -2526,7 +2539,7 @@ PhysicalRect AbsoluteBoundingBoxRectForScrollIntoView() const; // Build an array of quads in absolute coords for line boxes - virtual void AbsoluteQuads(Vector<FloatQuad>&, + virtual void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const { NOT_DESTROYED(); } @@ -3723,9 +3736,9 @@ MapCoordinatesFlags mode, PhysicalRect& result) const; - FloatQuad LocalToAncestorQuadInternal(const FloatQuad&, - const LayoutBoxModelObject* ancestor, - MapCoordinatesFlags = 0) const; + gfx::QuadF LocalToAncestorQuadInternal(const gfx::QuadF&, + const LayoutBoxModelObject* ancestor, + MapCoordinatesFlags = 0) const; void ClearLayoutRootIfNeeded() const; @@ -4086,7 +4099,7 @@ // The cached value from ComputedStyle::HasTransformRelatedProperty for // objects that do not ignore transform-related styles (e.g. not - // LayoutInline, LayoutSVGBlock). + // LayoutInline). ADD_BOOLEAN_BITFIELD(has_transform_related_property_, HasTransformRelatedProperty); ADD_BOOLEAN_BITFIELD(has_reflection_, HasReflection); @@ -4574,12 +4587,6 @@ bitfields_.SetHasBoxDecorationBackground(b); } -inline void MakeMatrixRenderable(TransformationMatrix& matrix, - bool has3d_rendering) { - if (!has3d_rendering) - matrix.MakeAffine(); -} - enum class LayoutObjectSide { kRemainingTextIfOnBoundary, kFirstLetterIfOnBoundary
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index 5f744e1..5432d92 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -1691,4 +1691,50 @@ WebFeature::kDifferentPerspectiveCBOrParent); } +TEST_F(LayoutObjectTest, HasTransformRelatedProperty) { + SetBodyInnerHTML(R"HTML( + <style> + .transform { transform: translateX(10px); } + .will-change { will-change: transform; } + .preserve-3d { transform-style: preserve-3d; } + </style> + <span id="span" class="transform will-change preserve-3d"></span> + <div id="div-transform" class="transform"></div> + <div id="div-will-change" class="will-change"></div> + <div id="div-preserve-3d" class="preserve-3d"></div> + <div id="div-none"></div> + <!-- overflow: visible to override the default overflow:hidden for and + enable preserve-3d --> + <svg id="svg" class="transform will-change preserve-3d" + style="overflow:visible"> + <rect id="svg-rect" class="transform preserve-3d"/> + <rect id="svg-rect-will-change" class="will-change"/> + <rect id="svg-rect-preserve-3d" class="preserve-3d"/> + <text id="svg-text" class="transform preserve-3d"/> + <foreignObject id="foreign" class="transform preserve-3d"/> + </svg> + )HTML"); + + auto test = [&](const char* element_id, bool has_transform_related_property, + bool has_transform, bool preserves_3d) { + SCOPED_TRACE(element_id); + const auto* object = GetLayoutObjectByElementId(element_id); + EXPECT_EQ(has_transform_related_property, + object->HasTransformRelatedProperty()); + EXPECT_EQ(has_transform, object->HasTransform()); + EXPECT_EQ(preserves_3d, object->Preserves3D()); + }; + test("span", false, false, false); + test("div-transform", true, true, false); + test("div-will-change", true, false, false); + test("div-preserve-3d", true, false, true); + test("div-none", false, false, false); + test("svg", true, true, true); + test("svg-rect", true, true, false); + test("svg-rect-will-change", true, false, false); + test("svg-rect-preserve-3d", false, false, false); + test("svg-text", true, true, false); + test("foreign", true, true, false); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc index cdf3493..cd90d3c 100644 --- a/third_party/blink/renderer/core/layout/layout_replaced.cc +++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -657,7 +657,7 @@ if (auto* image = DynamicTo<LayoutImage>(this)) { scaled_intrinsic_size.Scale(1.0 / image->ImageDevicePixelRatio()); } - FALLTHROUGH; + [[fallthrough]]; case EObjectFit::kContain: case EObjectFit::kCover: final_rect.size = final_rect.size.FitToAspectRatio( @@ -667,7 +667,7 @@ if (object_fit != EObjectFit::kScaleDown || final_rect.Width() <= scaled_intrinsic_size.width) break; - FALLTHROUGH; + [[fallthrough]]; case EObjectFit::kNone: final_rect.size = scaled_intrinsic_size; break;
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc index b86f22d8..06ae0f57 100644 --- a/third_party/blink/renderer/core/layout/layout_table.cc +++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -187,7 +187,7 @@ wrap_in_anonymous_section = false; break; } - FALLTHROUGH; + [[fallthrough]]; case EDisplay::kTableRowGroup: ResetSectionPointerIfNotBefore(first_body_, before_child); if (!first_body_)
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc index 621cc241..13735af 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -38,8 +38,8 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/table_cell_painter.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/wtf/size_assertions.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink {
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.cc b/third_party/blink/renderer/core/layout/layout_table_section.cc index b43e028b..193d3848 100644 --- a/third_party/blink/renderer/core/layout/layout_table_section.cc +++ b/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -2174,7 +2174,7 @@ transform_state.Flatten(); gfx::RectF rect = transform_state.LastPlanarQuad().BoundingBox(); rect.set_height(Table()->LogicalHeight()); - transform_state.SetQuad(FloatQuad(rect)); + transform_state.SetQuad(gfx::QuadF(rect)); return Table()->MapToVisualRectInAncestorSpaceInternal( ancestor, transform_state, flags); }
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 0594d70..2f021a5 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -70,7 +70,6 @@ #include "third_party/blink/renderer/core/layout/text_autosizer.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/platform/fonts/character_range.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" @@ -82,6 +81,7 @@ #include "third_party/blink/renderer/platform/wtf/size_assertions.h" #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -606,7 +606,7 @@ } } -void LayoutText::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutText::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); CollectLineBoxRects([this, &quads, mode](const PhysicalRect& r) { @@ -657,7 +657,7 @@ return true; } -void LayoutText::AbsoluteQuadsForRange(Vector<FloatQuad>& quads, +void LayoutText::AbsoluteQuadsForRange(Vector<gfx::QuadF>& quads, unsigned start, unsigned end) const { NOT_DESTROYED(); @@ -689,7 +689,7 @@ // TODO(layout-dev): This heuristic doesn't cover all cases, as we return // 2 collapsed quads (instead of 1) for range [3, 3] in the above example. bool found_non_collapsed_quad = false; - Vector<FloatQuad, 1> collapsed_quads_candidates; + Vector<gfx::QuadF, 1> collapsed_quads_candidates; // Find fragments that have text for the specified range. DCHECK_LE(start, end); @@ -721,12 +721,12 @@ } if (UNLIKELY(text_combine)) rect = text_combine->AdjustRectForBoundingBox(rect); - FloatQuad quad; + gfx::QuadF quad; if (item.Type() == NGFragmentItem::kSvgText) { gfx::RectF float_rect(rect); float_rect.Offset(item.SvgFragmentData()->rect.OffsetFromOrigin()); quad = item.BuildSvgTransformForBoundingBox().MapQuad( - FloatQuad(float_rect)); + gfx::QuadF(float_rect)); const float scaling_factor = item.SvgScalingFactor(); quad.Scale(1 / scaling_factor, 1 / scaling_factor); quad = LocalToAbsoluteQuad(quad);
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index 3879e79..da3b43b 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -136,15 +136,15 @@ void DirtyOrDeleteLineBoxesIfNeeded(bool full_layout); void DirtyLineBoxes(); - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const final; - void AbsoluteQuadsForRange(Vector<FloatQuad>&, + void AbsoluteQuadsForRange(Vector<gfx::QuadF>&, unsigned start_offset = 0, unsigned end_offset = INT_MAX) const; gfx::RectF LocalBoundingBoxRectForAccessibility() const final; enum ClippingOption { kNoClipping, kClipToEllipsis }; - void LocalQuadsInFlippedBlocksDirection(Vector<FloatQuad>&, + void LocalQuadsInFlippedBlocksDirection(Vector<gfx::QuadF>&, ClippingOption = kNoClipping) const; PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc index aed345e..73152089e 100644 --- a/third_party/blink/renderer/core/layout/layout_text_test.cc +++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -1049,11 +1049,11 @@ <div>012<span id=target>345 67</span></div> )HTML"); LayoutText* layout_text = GetLayoutTextById("target"); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; layout_text->AbsoluteQuads(quads); EXPECT_THAT(quads, - testing::ElementsAre(FloatQuad(gfx::RectF(30, 0, 30, 10)), - FloatQuad(gfx::RectF(0, 10, 20, 10)))); + testing::ElementsAre(gfx::QuadF(gfx::RectF(30, 0, 30, 10)), + gfx::QuadF(gfx::RectF(0, 10, 20, 10)))); } TEST_P(ParameterizedLayoutTextTest, AbsoluteQuadsVRL) { @@ -1071,11 +1071,11 @@ <div>012<span id=target>345 67</span></div> )HTML"); LayoutText* layout_text = GetLayoutTextById("target"); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; layout_text->AbsoluteQuads(quads); EXPECT_THAT(quads, - testing::ElementsAre(FloatQuad(gfx::RectF(90, 30, 10, 30)), - FloatQuad(gfx::RectF(80, 0, 10, 20)))); + testing::ElementsAre(gfx::QuadF(gfx::RectF(90, 30, 10, 30)), + gfx::QuadF(gfx::RectF(80, 0, 10, 20)))); } TEST_P(ParameterizedLayoutTextTest, PhysicalLinesBoundingBox) {
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 278482a2..bf0841833 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -55,13 +55,13 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/view_painter.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "ui/display/screen_info.h" +#include "ui/gfx/geometry/quad_f.h" #if defined(OS_LINUX) || defined(OS_CHROMEOS) #include "third_party/blink/renderer/platform/fonts/font_cache.h" @@ -491,7 +491,7 @@ return intersects; TransformState transform_state(TransformState::kApplyTransformDirection, - FloatQuad(gfx::RectF(rect))); + gfx::QuadF(gfx::RectF(rect))); intersects = MapToVisualRectInAncestorSpaceInternal(ancestor, transform_state, mode, visual_rect_flags); transform_state.Flatten(); @@ -535,7 +535,7 @@ transform_state.LastPlanarQuad().BoundingBox()); bool retval = GetFrameView()->MapToVisualRectInRemoteRootFrame( rect, !(visual_rect_flags & kDontApplyMainFrameOverflowClip)); - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return retval; } @@ -545,7 +545,7 @@ PhysicalRect view_rectangle = ViewRect(); if (visual_rect_flags & kEdgeInclusive) { if (!rect.InclusiveIntersect(view_rectangle)) { - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return false; } } else { @@ -560,14 +560,14 @@ // Adjust for frame border. rect.Move(obj->PhysicalContentBoxOffset()); - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return obj->MapToVisualRectInAncestorSpaceInternal( ancestor, transform_state, visual_rect_flags); } // This can happen, e.g., if the iframe element has display:none. - transform_state.SetQuad(FloatQuad(gfx::RectF())); + transform_state.SetQuad(gfx::QuadF(gfx::RectF())); return false; } @@ -581,7 +581,7 @@ return PhysicalOffset(ToFlooredPoint(OffsetForFixedPosition())); } -void LayoutView::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutView::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); quads.push_back(LocalRectToAbsoluteQuad(
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h index b6101303..be383f8 100644 --- a/third_party/blink/renderer/core/layout/layout_view.h +++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -168,7 +168,7 @@ void CommitPendingSelection(); - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const override; PhysicalRect ViewRect() const override;
diff --git a/third_party/blink/renderer/core/layout/map_coordinates_test.cc b/third_party/blink/renderer/core/layout/map_coordinates_test.cc index 8028c2ed..335af97 100644 --- a/third_party/blink/renderer/core/layout/map_coordinates_test.cc +++ b/third_party/blink/renderer/core/layout/map_coordinates_test.cc
@@ -27,18 +27,18 @@ const LayoutBoxModelObject* ancestor, PhysicalOffset, MapCoordinatesFlags = 0) const; - FloatQuad MapLocalToAncestor(const LayoutObject*, - const LayoutBoxModelObject* ancestor, - FloatQuad, - MapCoordinatesFlags = 0) const; + gfx::QuadF MapLocalToAncestor(const LayoutObject*, + const LayoutBoxModelObject* ancestor, + gfx::QuadF, + MapCoordinatesFlags = 0) const; PhysicalOffset MapAncestorToLocal(const LayoutObject*, const LayoutBoxModelObject* ancestor, PhysicalOffset, MapCoordinatesFlags = 0) const; - FloatQuad MapAncestorToLocal(const LayoutObject*, - const LayoutBoxModelObject* ancestor, - FloatQuad, - MapCoordinatesFlags = 0) const; + gfx::QuadF MapAncestorToLocal(const LayoutObject*, + const LayoutBoxModelObject* ancestor, + gfx::QuadF, + MapCoordinatesFlags = 0) const; // Adjust point by the scroll offset of the LayoutView. This only has an // effect if root layer scrolling is enabled. The only reason for doing @@ -75,10 +75,10 @@ return object->LocalToAncestorPoint(point, ancestor, mode); } -FloatQuad MapCoordinatesTest::MapLocalToAncestor( +gfx::QuadF MapCoordinatesTest::MapLocalToAncestor( const LayoutObject* object, const LayoutBoxModelObject* ancestor, - FloatQuad quad, + gfx::QuadF quad, MapCoordinatesFlags mode) const { return object->LocalToAncestorQuad(quad, ancestor, mode); } @@ -91,10 +91,10 @@ return object->AncestorToLocalPoint(ancestor, point, mode); } -FloatQuad MapCoordinatesTest::MapAncestorToLocal( +gfx::QuadF MapCoordinatesTest::MapAncestorToLocal( const LayoutObject* object, const LayoutBoxModelObject* ancestor, - FloatQuad quad, + gfx::QuadF quad, MapCoordinatesFlags mode) const { return object->AncestorToLocalQuad(ancestor, quad, mode); } @@ -1394,8 +1394,8 @@ return fabs(expected - actual) < 0.01; } -static bool FloatQuadsAlmostEqual(const FloatQuad& expected, - const FloatQuad& actual) { +static bool QuadsAlmostEqual(const gfx::QuadF& expected, + const gfx::QuadF& actual) { return FloatValuesAlmostEqual(expected.p1().x(), actual.p1().x()) && FloatValuesAlmostEqual(expected.p1().y(), actual.p1().y()) && FloatValuesAlmostEqual(expected.p2().x(), actual.p2().x()) && @@ -1407,11 +1407,11 @@ } // If comparison fails, pretty-print the error using EXPECT_EQ() -#define EXPECT_FLOAT_QUAD_EQ(expected, actual) \ - do { \ - if (!FloatQuadsAlmostEqual(expected, actual)) { \ - EXPECT_EQ(expected, actual); \ - } \ +#define EXPECT_QUADF_EQ(expected, actual) \ + do { \ + if (!QuadsAlmostEqual(expected, actual)) { \ + EXPECT_EQ(expected, actual); \ + } \ } while (false) TEST_F(MapCoordinatesTest, Transforms) { @@ -1430,48 +1430,48 @@ auto* target = GetLayoutBoxByElementId("target"); auto* container = GetLayoutBoxByElementId("container"); - FloatQuad initial_quad(gfx::PointF(0, 0), gfx::PointF(200, 0), - gfx::PointF(200, 200), gfx::PointF(0, 200)); - FloatQuad mapped_quad = MapLocalToAncestor(target, container, initial_quad); - EXPECT_FLOAT_QUAD_EQ(FloatQuad(gfx::PointF(200, 0), gfx::PointF(200, 200), - gfx::PointF(0, 200), gfx::PointF(0, 0)), - mapped_quad); + gfx::QuadF initial_quad(gfx::PointF(0, 0), gfx::PointF(200, 0), + gfx::PointF(200, 200), gfx::PointF(0, 200)); + gfx::QuadF mapped_quad = MapLocalToAncestor(target, container, initial_quad); + EXPECT_QUADF_EQ(gfx::QuadF(gfx::PointF(200, 0), gfx::PointF(200, 200), + gfx::PointF(0, 200), gfx::PointF(0, 0)), + mapped_quad); mapped_quad = MapAncestorToLocal(target, container, mapped_quad); - EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad); + EXPECT_QUADF_EQ(initial_quad, mapped_quad); // Walk each ancestor in the chain separately, to verify each step on the way. auto* inner_transform = GetLayoutBoxByElementId("innerTransform"); auto* outer_transform = GetLayoutBoxByElementId("outerTransform"); mapped_quad = MapLocalToAncestor(target, inner_transform, initial_quad); - EXPECT_FLOAT_QUAD_EQ(FloatQuad(gfx::PointF(0, 0), gfx::PointF(200, 0), - gfx::PointF(200, 200), gfx::PointF(0, 200)), - mapped_quad); + EXPECT_QUADF_EQ(gfx::QuadF(gfx::PointF(0, 0), gfx::PointF(200, 0), + gfx::PointF(200, 200), gfx::PointF(0, 200)), + mapped_quad); mapped_quad = MapAncestorToLocal(target, inner_transform, mapped_quad); - EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad); + EXPECT_QUADF_EQ(initial_quad, mapped_quad); - initial_quad = FloatQuad(gfx::PointF(0, 0), gfx::PointF(200, 0), - gfx::PointF(200, 200), gfx::PointF(0, 200)); + initial_quad = gfx::QuadF(gfx::PointF(0, 0), gfx::PointF(200, 0), + gfx::PointF(200, 200), gfx::PointF(0, 200)); mapped_quad = MapLocalToAncestor(inner_transform, outer_transform, initial_quad); // Clockwise rotation by 45 degrees. - EXPECT_FLOAT_QUAD_EQ( - FloatQuad(gfx::PointF(100, -41.42), gfx::PointF(241.42, 100), - gfx::PointF(100, 241.42), gfx::PointF(-41.42, 100)), + EXPECT_QUADF_EQ( + gfx::QuadF(gfx::PointF(100, -41.42), gfx::PointF(241.42, 100), + gfx::PointF(100, 241.42), gfx::PointF(-41.42, 100)), mapped_quad); mapped_quad = MapAncestorToLocal(inner_transform, outer_transform, mapped_quad); - EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad); + EXPECT_QUADF_EQ(initial_quad, mapped_quad); - initial_quad = FloatQuad(gfx::PointF(100, -41.42), gfx::PointF(241.42, 100), - gfx::PointF(100, 241.42), gfx::PointF(-41.42, 100)); + initial_quad = gfx::QuadF(gfx::PointF(100, -41.42), gfx::PointF(241.42, 100), + gfx::PointF(100, 241.42), gfx::PointF(-41.42, 100)); mapped_quad = MapLocalToAncestor(outer_transform, container, initial_quad); // Another clockwise rotation by 45 degrees. So now 90 degrees in total. - EXPECT_FLOAT_QUAD_EQ(FloatQuad(gfx::PointF(200, 0), gfx::PointF(200, 200), - gfx::PointF(0, 200), gfx::PointF(0, 0)), - mapped_quad); + EXPECT_QUADF_EQ(gfx::QuadF(gfx::PointF(200, 0), gfx::PointF(200, 200), + gfx::PointF(0, 200), gfx::PointF(0, 0)), + mapped_quad); mapped_quad = MapAncestorToLocal(outer_transform, container, mapped_quad); - EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad); + EXPECT_QUADF_EQ(initial_quad, mapped_quad); } TEST_F(MapCoordinatesTest, SVGShape) { @@ -1759,9 +1759,9 @@ )HTML"); auto* target = GetLayoutObjectByElementId("target"); - EXPECT_EQ(FloatQuad(gfx::RectF(0, 100, 100, 100)), + EXPECT_EQ(gfx::QuadF(gfx::RectF(0, 100, 100, 100)), MapLocalToAncestor(target, nullptr, - FloatQuad(gfx::RectF(0, 0, 100, 100)))); + gfx::QuadF(gfx::RectF(0, 0, 100, 100)))); } TEST_F(MapCoordinatesTest, Transform3DWithOffset2) { @@ -1782,9 +1782,9 @@ )HTML"); auto* target = GetLayoutObjectByElementId("target"); - EXPECT_EQ(FloatQuad(gfx::RectF(0, 200, 200, 200)), + EXPECT_EQ(gfx::QuadF(gfx::RectF(0, 200, 200, 200)), MapLocalToAncestor(target, nullptr, - FloatQuad(gfx::RectF(0, 0, 100, 100)))); + gfx::QuadF(gfx::RectF(0, 0, 100, 100)))); } // This test verifies that the mapped location of a div within a scroller
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h index a770f76..b9a66f9 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -95,7 +95,7 @@ switch (type) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case EFloat::kLeft: has_break_before_left_float_ = true; break; @@ -109,7 +109,7 @@ switch (type) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case EFloat::kLeft: has_break_inside_left_float_ = true; break; @@ -124,7 +124,7 @@ switch (type) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case EClear::kNone: return false; case EClear::kLeft: @@ -133,7 +133,7 @@ has_break_inside_left_float_ || has_break_before_left_float_; if (type == EClear::kLeft) break; - FALLTHROUGH; + [[fallthrough]]; case EClear::kRight: needs_clearance |= has_break_inside_right_float_ || has_break_before_right_float_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc index 469b360..0f7c7df 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -379,10 +379,10 @@ return ink_bounds; } -FloatQuad NGFragmentItem::SvgUnscaledQuad() const { +gfx::QuadF NGFragmentItem::SvgUnscaledQuad() const { DCHECK_EQ(Type(), kSvgText); - FloatQuad quad = BuildSvgTransformForBoundingBox().MapQuad( - FloatQuad(SvgFragmentData()->rect)); + gfx::QuadF quad = BuildSvgTransformForBoundingBox().MapQuad( + gfx::QuadF(SvgFragmentData()->rect)); const float scaling_factor = SvgScalingFactor(); quad.Scale(1 / scaling_factor, 1 / scaling_factor); return quad;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h index bc26f8a..3e2a97f5 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -458,7 +458,7 @@ // Returns a transformed text cell in the unscaled coordination system. // This works only with kSvgText type. - FloatQuad SvgUnscaledQuad() const; + gfx::QuadF SvgUnscaledQuad() const; // Returns a font scaling factor for SVG <text>. // This returns 1 for an NGFragmentItem not for LayoutSVGInlineText.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index a75649a2e..6a7292b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -124,7 +124,7 @@ switch (clear) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case EClear::kNone: return kAdjoiningNone; case EClear::kLeft:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h index 452905a3..a462ea88 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -198,7 +198,7 @@ bitfields_.percentage_inline_storage)) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case kSameAsAvailable: return available_size_.inline_size; case kZero: @@ -216,7 +216,7 @@ static_cast<NGPercentageStorage>(bitfields_.percentage_block_storage)) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case kSameAsAvailable: return available_size_.block_size; case kZero:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc index e08a748..c8988e4 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
@@ -376,14 +376,14 @@ new_inline_container); } - const NGFragmentedOutOfFlowData* oof_data = - fragment.FragmentedOutOfFlowData(); + NGFragmentedOutOfFlowData* oof_data = fragment.FragmentedOutOfFlowData(); if (!oof_data) return; DCHECK(!oof_data->multicols_with_pending_oofs.IsEmpty() || !oof_data->oof_positioned_fragmentainer_descendants.IsEmpty()); const NGPhysicalBoxFragment* box_fragment = DynamicTo<NGPhysicalBoxFragment>(&fragment); + bool is_column_spanner = box_fragment && box_fragment->IsColumnSpanAll(); if (!oof_data->multicols_with_pending_oofs.IsEmpty()) { const auto& multicols_with_pending_oofs = @@ -407,6 +407,8 @@ // |fragment|. LogicalOffset fixedpos_containing_block_offset; LogicalOffset fixedpos_containing_block_rel_offset; + bool is_inside_column_spanner = + multicol_info.fixedpos_containing_block.is_inside_column_spanner; if (fixedpos_containing_block_fragment) { fixedpos_containing_block_offset = converter.ToLogical(multicol_info.fixedpos_containing_block.offset, @@ -425,6 +427,9 @@ fixedpos_containing_block_offset += offset; fixedpos_containing_block_offset.block_offset += containing_block_adjustment; + + if (is_column_spanner) + is_inside_column_spanner = true; } else { multicol_offset += adjusted_offset; } @@ -434,30 +439,56 @@ multicol_offset, NGContainingBlock<LogicalOffset>( fixedpos_containing_block_offset, fixedpos_containing_block_rel_offset, - fixedpos_containing_block_fragment))); + fixedpos_containing_block_fragment, + is_inside_column_spanner))); } } if (oof_data->oof_positioned_fragmentainer_descendants.IsEmpty()) return; - const auto& out_of_flow_fragmentainer_descendants = + auto& out_of_flow_fragmentainer_descendants = oof_data->oof_positioned_fragmentainer_descendants; - for (const auto& descendant : out_of_flow_fragmentainer_descendants) { + wtf_size_t next_idx; + for (wtf_size_t idx = 0; idx < out_of_flow_fragmentainer_descendants.size(); + idx = next_idx) { + next_idx = idx + 1; + const auto& descendant = out_of_flow_fragmentainer_descendants[idx]; const NGPhysicalFragment* containing_block_fragment = descendant.containing_block.fragment.get(); + bool container_inside_column_spanner = + descendant.containing_block.is_inside_column_spanner; + bool fixedpos_container_inside_column_spanner = + descendant.fixedpos_containing_block.is_inside_column_spanner; + bool remove_descendant = false; + if (!containing_block_fragment) { DCHECK(box_fragment); containing_block_fragment = box_fragment; } else if (box_fragment && box_fragment->IsFragmentationContextRoot()) { // If we find a multicol with OOF positioned fragmentainer descendants, // then that multicol is an inner multicol with pending OOFs. Those OOFs - // will be laid out inside the inner multicol when we reach the outermost - // fragmentation context, so we should not propagate those OOFs up the - // tree any further. - continue; + // will be laid out inside the inner multicol when we reach the + // outermost fragmentation context, so we should not propagate those + // OOFs up the tree any further. However, if the containing block is + // inside a column spanner contained by the current fragmentation root, we + // should continue to propagate that OOF up the tree so it can be laid out + // in the next fragmentation context. + if (container_inside_column_spanner) { + // Reset the OOF node's column spanner tags so that we don't propagate + // the OOF past the next fragmentation context root ancestor. + container_inside_column_spanner = false; + fixedpos_container_inside_column_spanner = false; + remove_descendant = true; + } else { + DCHECK(!fixedpos_container_inside_column_spanner); + continue; + } } + if (is_column_spanner) + container_inside_column_spanner = true; + LogicalOffset containing_block_offset = converter.ToLogical( descendant.containing_block.offset, containing_block_fragment->Size()); LogicalOffset containing_block_rel_offset = @@ -490,6 +521,9 @@ fixedpos_containing_block_offset += offset; fixedpos_containing_block_offset.block_offset += containing_block_adjustment; + + if (is_column_spanner) + fixedpos_container_inside_column_spanner = true; } if (!fixedpos_containing_block_fragment && fixedpos_containing_block) { @@ -523,12 +557,21 @@ AddOutOfFlowFragmentainerDescendant( {descendant.Node(), static_position, new_inline_container, /* needs_block_offset_adjustment */ false, - NGContainingBlock<LogicalOffset>(containing_block_offset, - containing_block_rel_offset, - containing_block_fragment), - NGContainingBlock<LogicalOffset>(fixedpos_containing_block_offset, - fixedpos_containing_block_rel_offset, - fixedpos_containing_block_fragment)}); + NGContainingBlock<LogicalOffset>( + containing_block_offset, containing_block_rel_offset, + containing_block_fragment, container_inside_column_spanner), + NGContainingBlock<LogicalOffset>( + fixedpos_containing_block_offset, + fixedpos_containing_block_rel_offset, + fixedpos_containing_block_fragment, + fixedpos_container_inside_column_spanner)}); + + // Remove any descendants that were propagated to the next fragmentation + // context root (as a result of a column spanner). + if (remove_descendant) { + out_of_flow_fragmentainer_descendants.EraseAt(idx); + next_idx = idx; + } } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc index 1d1e1ee..907786d9 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -376,7 +376,13 @@ if (max_content_block_size != LayoutUnit::Max() && (!result || result->Status() == NGLayoutResult::kSuccess)) { DCHECK_EQ(adjusted_padding_box_size.block_size, kIndefiniteSize); - max_content_block_size -= borders_.BlockSum(); + if (max_content_block_size > padding_.BlockSum()) { + // intrinsic_block_size_ is + // max(borders_.block_start, legend margin box block size). + max_content_block_size = std::max( + max_content_block_size - (intrinsic_block_size_ + borders_.block_end), + padding_.BlockSum()); + } if (result) { const auto& fragment = result->PhysicalFragment();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc index 0d75da8..01c9f812 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -362,6 +362,10 @@ )HTML"); String dump = DumpFragmentTree(GetElementById("container")); + // The fieldset height should be the legend height + padding-top + + // padding-bottom + border-bottom == 53px. + // The anonymous content block height should be 20px due to the padding + // delegation. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x53 offset:0,0 size:126x53
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc index 7e43410f..6a20f96 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -36,7 +36,7 @@ switch (break_value) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case EBreakBetween::kAuto: return 0; case EBreakBetween::kAvoidColumn:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc index 1a34b1f..96877ef 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
@@ -143,7 +143,7 @@ #if DCHECK_IS_ON() if (!read_unset_as_none_) NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; #endif case kNone: case kSmallContents: @@ -171,7 +171,7 @@ #if DCHECK_IS_ON() && !BUILDFLAG(IS_CHROMEOS_ASH) if (!read_unset_as_none_) NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; #endif case kNone: case kSmallSelf: @@ -199,7 +199,7 @@ #if DCHECK_IS_ON() if (!read_unset_as_none_) NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; #endif case kNone: return {PhysicalOffset(), size}; @@ -269,7 +269,7 @@ switch (type) { case kSelfAndContents: Reset(type); - FALLTHROUGH; + [[fallthrough]]; case kNotSet: case kInvalidated: case kNone: @@ -322,7 +322,7 @@ case kSelf: case kContents: Reset(type); - FALLTHROUGH; + [[fallthrough]]; case kNotSet: case kInvalidated: case kNone:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc index abfb889..61408ce2 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc
@@ -136,6 +136,9 @@ converter.ToLogical(padding_rect_.size).inline_size) return normal_overflow; + if (!inflow_bounds->IsEmpty()) + return normal_overflow; + // We'd like everything to be |normal_overflow|, lets see what the impact // would be. if (node_.Style().OverflowInlineDirection() == EOverflow::kAuto ||
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator_test.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator_test.cc index 901a4c9..8cf0bc6 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator_test.cc
@@ -24,7 +24,8 @@ WebFeature::kNewLayoutOverflowDifferentAndAlreadyScrollsBlock)); } -TEST_F(NGLayoutOverflowCalculatorTest, NewLayoutOverflowDifferentBlock) { +TEST_F(NGLayoutOverflowCalculatorTest, + DISABLED_NewLayoutOverflowDifferentBlock) { if (!RuntimeEnabledFeatures::LayoutNGEnabled()) return; SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index eebe80b..c3bb1a5 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -159,7 +159,7 @@ case Length::kDeviceHeight: case Length::kExtendToZoom: NOTREACHED() << "These should only be used for viewport definitions"; - FALLTHROUGH; + [[fallthrough]]; case Length::kAuto: case Length::kNone: default: @@ -224,7 +224,7 @@ case Length::kDeviceHeight: case Length::kExtendToZoom: NOTREACHED() << "These should only be used for viewport definitions"; - FALLTHROUGH; + [[fallthrough]]; case Length::kAuto: case Length::kNone: default:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 1b595083..12062de 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -932,17 +932,27 @@ static_position, inline_container, /* needs_block_offset_adjustment */ false, - NGContainingBlock<LogicalOffset>(containing_block_offset, - containing_block_rel_offset, - containing_block_fragment), - NGContainingBlock<LogicalOffset>(fixedpos_containing_block_offset, - fixedpos_containing_block_rel_offset, - fixedpos_containing_block_fragment)}; + NGContainingBlock<LogicalOffset>( + containing_block_offset, containing_block_rel_offset, + containing_block_fragment, + descendant.containing_block.is_inside_column_spanner), + NGContainingBlock<LogicalOffset>( + fixedpos_containing_block_offset, + fixedpos_containing_block_rel_offset, + fixedpos_containing_block_fragment, + descendant.fixedpos_containing_block.is_inside_column_spanner)}; oof_nodes_to_layout.push_back(node); } previous_multicol_break_token = break_token; } - DCHECK(!oof_nodes_to_layout.IsEmpty()); + // When an OOF's CB is a spanner (or a descendant of a spanner), we will lay + // out the OOF at the next fragmentation context root ancestor. As such, we + // remove any such OOF nodes from the nearest multicol's list of OOF + // descendants during OOF node propagation, which may cause + // |oof_nodes_to_layout| to be empty. Return early if this is the case. + if (oof_nodes_to_layout.IsEmpty()) + return; + DCHECK(!limited_multicol_container_builder .HasOutOfFlowFragmentainerDescendants()); @@ -1268,11 +1278,26 @@ PaintLayerScrollableArea::FreezeScrollbarsRootScope freezer( *node_info.node.GetLayoutBox(), freeze_horizontal, freeze_vertical); - // The offset itself does not need to be recalculated. However, the - // |node_dimensions| and |initial_layout_result| may need to be updated, - // so recompute the OffsetInfo. - offset_info = CalculateOffset(node_info, only_layout, - /* is_first_run */ false); + if (!IsResumingLayout(oof_node_to_layout.break_token)) { + // The offset itself does not need to be recalculated. However, the + // |node_dimensions| and |initial_layout_result| may need to be updated, + // so recompute the OffsetInfo. + // + // Only do this if we're currently building the first fragment of the + // OOF. If we're resuming after a fragmentainer break, we can't update + // our intrinsic inline-size. First of all, the intrinsic inline-size + // should be the same across all fragments [1], and besides, this + // operation would lead to performing a non-fragmented layout pass (to + // measure intrinsic block-size; see IntrinsicBlockSizeFunc in + // ComputeOutOfFlowBlockDimensions()), which in turn would overwrite the + // result of the first fragment entry in LayoutBox without a break + // token, causing major confusion everywhere. + // + // [1] https://drafts.csswg.org/css-break/#varying-size-boxes + offset_info = CalculateOffset(node_info, only_layout, + /* is_first_run */ false); + } + layout_result = Layout(oof_node_to_layout, fragmentainer_constraint_space);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h index 02d9db6..e7dab5c 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h
@@ -32,15 +32,20 @@ // fragmentation: https://www.w3.org/TR/css-break-3/#transforms. OffsetType relative_offset; scoped_refptr<const NGPhysicalFragment> fragment; + // True if there is a column spanner between the containing block and the + // multicol container (or if the containing block is a column spanner). + bool is_inside_column_spanner = false; NGContainingBlock() : fragment(nullptr) {} NGContainingBlock(OffsetType offset, OffsetType relative_offset, - scoped_refptr<const NGPhysicalFragment> fragment) + scoped_refptr<const NGPhysicalFragment> fragment, + bool is_inside_column_spanner) : offset(offset), relative_offset(relative_offset), - fragment(std::move(fragment)) {} + fragment(std::move(fragment)), + is_inside_column_spanner(is_inside_column_spanner) {} }; // This holds the containing block for an out-of-flow positioned element
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index 4d6f909d..be0c350 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -100,7 +100,7 @@ builder->Style().GetWritingDirection(), outer_size, inner_size), containing_block.relative_offset.ConvertToPhysical( builder->Style().GetWritingDirection(), outer_size, inner_size), - containing_block.fragment); + containing_block.fragment, containing_block.is_inside_column_spanner); } NGContainingBlock<PhysicalOffset> PhysicalContainingBlock(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 1c92ec74..dd2e77f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -486,12 +486,11 @@ return container->IsLayoutNGObject(); } -const NGFragmentedOutOfFlowData* NGPhysicalFragment::FragmentedOutOfFlowData() - const { +NGFragmentedOutOfFlowData* NGPhysicalFragment::FragmentedOutOfFlowData() const { if (!has_fragmented_out_of_flow_data_) return nullptr; - const auto* oof_data = - reinterpret_cast<const NGFragmentedOutOfFlowData*>(oof_data_.get()); + auto* oof_data = + reinterpret_cast<NGFragmentedOutOfFlowData*>(oof_data_.get()); DCHECK(!oof_data->multicols_with_pending_oofs.IsEmpty() || !oof_data->oof_positioned_fragmentainer_descendants.IsEmpty()); return oof_data;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index 8f5f005..a1bc46c3 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -621,7 +621,7 @@ oof_data_->oof_positioned_descendants.size()}; } - const NGFragmentedOutOfFlowData* FragmentedOutOfFlowData() const; + NGFragmentedOutOfFlowData* FragmentedOutOfFlowData() const; // Figure out if the child has any out-of-flow positioned descendants, in // which case we'll need to propagate this to the fragment builder.
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc index ea44396..4b6c67f1b 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -274,10 +274,10 @@ return SVGLayoutSupport::ComputeVisualRectForText(*this, box); } -void LayoutNGSVGText::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutNGSVGText::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); - quads.push_back(LocalToAbsoluteQuad(FloatQuad(StrokeBoundingBox()), mode)); + quads.push_back(LocalToAbsoluteQuad(gfx::QuadF(StrokeBoundingBox()), mode)); } gfx::RectF LayoutNGSVGText::LocalBoundingBoxRectForAccessibility() const {
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h index b913ce56..47919d2 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h
@@ -39,7 +39,7 @@ gfx::RectF ObjectBoundingBox() const override; gfx::RectF StrokeBoundingBox() const override; gfx::RectF VisualRectInLocalSVGCoordinates() const override; - void AbsoluteQuads(Vector<FloatQuad>& quads, + void AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const override; gfx::RectF LocalBoundingBoxRectForAccessibility() const override; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc index abf8136..6edbae8 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc
@@ -25,7 +25,7 @@ </svg>)HTML"); UpdateAllLifecyclePhasesForTest(); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; auto* object = GetLayoutObjectByElementId("t"); object->AbsoluteQuads(quads, 0); EXPECT_EQ(1u, quads.size());
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc index ea76046..8424d33 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
@@ -519,7 +519,7 @@ switch (style.TextAnchor()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ETextAnchor::kStart: shift = is_ltr ? shift - min_position : shift - max_position; break;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_constraint_space_data.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_constraint_space_data.h index 02bdb4f..a456c55 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_constraint_space_data.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_constraint_space_data.h
@@ -13,10 +13,10 @@ namespace blink { -// Same NGTableConstraintSpaceData object gets passed on ConstraintSpace to -// all rows and sections in a single table. It contains all the geometry -// information needed to layout sections/rows/cells. This is different from most -// other algorithms, where constraint space data is not shared. +// The same NGTableConstraintSpaceData object gets passed on the constraint +// space to all rows and sections within a single table. It contains all the +// geometry information needed to layout sections/rows/cells. This is different +// from most other algorithms, where the constraint space data is not shared. class NGTableConstraintSpaceData : public RefCounted<NGTableConstraintSpaceData> { public: @@ -26,28 +26,30 @@ : offset(offset), inline_size(inline_size), is_collapsed(is_collapsed) {} - const LayoutUnit offset; - const LayoutUnit inline_size; - const bool is_collapsed; + bool operator==(const ColumnLocation& other) const { return offset == other.offset && inline_size == other.inline_size && is_collapsed == other.is_collapsed; } + + const LayoutUnit offset; + const LayoutUnit inline_size; + const bool is_collapsed; }; // Section hold row index information used to map between table and // section row indexes. struct Section { - Section(wtf_size_t start_row_index, wtf_size_t rowspan) - : start_row_index(start_row_index), rowspan(rowspan) {} + Section(wtf_size_t start_row_index, wtf_size_t row_count) + : start_row_index(start_row_index), row_count(row_count) {} bool MaySkipLayout(const Section& other) const { // We don't compare |start_row_index| as this is allowed to change. - return rowspan == other.rowspan; + return row_count == other.row_count; } - wtf_size_t start_row_index; // First section row in table grid. - wtf_size_t rowspan; + const wtf_size_t start_row_index; // First section row in table grid. + const wtf_size_t row_count; }; // Data needed by row layout algorithm. @@ -75,12 +77,12 @@ is_collapsed == other.is_collapsed; } - LayoutUnit baseline; - LayoutUnit block_size; - wtf_size_t start_cell_index; - wtf_size_t cell_count; - bool has_baseline_aligned_percentage_block_size_descendants; - bool is_collapsed; + const LayoutUnit baseline; + const LayoutUnit block_size; + const wtf_size_t start_cell_index; + const wtf_size_t cell_count; + const bool has_baseline_aligned_percentage_block_size_descendants; + const bool is_collapsed; }; // Data needed to layout a single cell. @@ -95,6 +97,7 @@ start_column(start_column), has_grown(has_grown), is_constrained(is_constrained) {} + bool operator==(const Cell& other) const { return border_box_borders == other.border_box_borders && block_size == other.block_size && @@ -103,23 +106,23 @@ is_constrained == other.is_constrained; } bool operator!=(const Cell& other) const { return !(*this == other); } + // Size of borders drawn on the inside of the border box. - NGBoxStrut border_box_borders; + const NGBoxStrut border_box_borders; // Size of the cell. Need this for cells that span multiple rows. - LayoutUnit block_size; - wtf_size_t start_column; - bool has_grown; - bool is_constrained; + const LayoutUnit block_size; + const wtf_size_t start_column; + const bool has_grown; + const bool is_constrained; }; bool IsTableSpecificDataEqual(const NGTableConstraintSpaceData& other) const { - return table_inline_size == other.table_inline_size && + return column_locations == other.column_locations && table_writing_direction == other.table_writing_direction && table_border_spacing == other.table_border_spacing && is_table_block_size_specified == other.is_table_block_size_specified && - hide_table_cell_if_empty == other.hide_table_cell_if_empty && - column_locations == other.column_locations; + has_collapsed_borders == other.has_collapsed_borders; } bool MaySkipRowLayout(const NGTableConstraintSpaceData& other, @@ -166,15 +169,15 @@ if (!new_section.MaySkipLayout(old_section)) return false; - DCHECK_EQ(new_section.rowspan, old_section.rowspan); + DCHECK_EQ(new_section.row_count, old_section.row_count); const wtf_size_t new_start_row_index = new_section.start_row_index; const wtf_size_t old_start_row_index = old_section.start_row_index; const wtf_size_t new_end_row_index = - new_start_row_index + new_section.rowspan; + new_start_row_index + new_section.row_count; const wtf_size_t old_end_row_index = - old_start_row_index + old_section.rowspan; + old_start_row_index + old_section.row_count; for (wtf_size_t new_row_index = new_start_row_index, old_row_index = old_start_row_index; @@ -191,14 +194,12 @@ Vector<Section> sections; Vector<Row> rows; Vector<Cell> cells; - LayoutUnit table_inline_size; WritingDirectionMode table_writing_direction = WritingDirectionMode(WritingMode::kHorizontalTb, TextDirection::kLtr); LogicalSize table_border_spacing; // If the block-size of the table is specified (not 'auto'). bool is_table_block_size_specified; - bool hide_table_cell_if_empty; // currently on regular constraint space. bool has_collapsed_borders; };
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc index 5dc6f06..f930a60 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -233,17 +233,12 @@ const NGTableTypes::Sections& sections, const NGTableTypes::Rows& rows, const NGTableTypes::CellBlockConstraints& cell_block_constraints, - const LayoutUnit table_inline_size, const LogicalSize& border_spacing) { scoped_refptr<NGTableConstraintSpaceData> data = base::MakeRefCounted<NGTableConstraintSpaceData>(); - data->table_inline_size = table_inline_size; data->table_writing_direction = style.GetWritingDirection(); data->table_border_spacing = border_spacing; data->is_table_block_size_specified = !style.LogicalHeight().IsAuto(); - data->hide_table_cell_if_empty = - style.EmptyCells() == EEmptyCells::kHide && - style.BorderCollapse() == EBorderCollapse::kSeparate; data->has_collapsed_borders = style.BorderCollapse() == EBorderCollapse::kCollapse; @@ -254,7 +249,7 @@ } data->sections.ReserveCapacity(sections.size()); for (const auto& section : sections) - data->sections.emplace_back(section.start_row, section.rowspan); + data->sections.emplace_back(section.start_row, section.row_count); data->rows.ReserveCapacity(rows.size()); for (const auto& row : rows) { data->rows.emplace_back( @@ -267,13 +262,12 @@ // section. The cell does not know what section it is in. for (const auto& section : sections) { for (wtf_size_t row_index = section.start_row; - row_index < section.start_row + section.rowspan; ++row_index) { - for (wtf_size_t cell_index = rows[row_index].start_cell_index; - cell_index < - rows[row_index].start_cell_index + rows[row_index].cell_count; - ++cell_index) { + row_index < section.start_row + section.row_count; ++row_index) { + const auto& row = rows[row_index]; + for (wtf_size_t cell_index = row.start_cell_index; + cell_index < row.start_cell_index + row.cell_count; ++cell_index) { wtf_size_t max_rowspan = - section.start_row + section.rowspan - row_index; + section.start_row + section.row_count - row_index; wtf_size_t rowspan = std::min(cell_block_constraints[cell_index].rowspan, max_rowspan); // Compute cell's size. @@ -771,8 +765,7 @@ const auto table_writing_direction = Style().GetWritingDirection(); scoped_refptr<const NGTableConstraintSpaceData> constraint_space_data = CreateConstraintSpaceData(Style(), column_locations, sections, rows, - cell_block_constraints, table_inline_size, - border_spacing); + cell_block_constraints, border_spacing); const NGBoxStrut border_padding = container_builder_.BorderPadding(); LayoutUnit block_offset; @@ -818,7 +811,7 @@ kIndefiniteSize}; // Sections without rows can receive redistributed height from the table. - if (constraint_space_data->sections[section_index].rowspan == 0) { + if (constraint_space_data->sections[section_index].row_count == 0) { section_space_builder.SetIsFixedBlockSize(true); available_size.block_size = sections[section_index].block_size; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc index 499b764..cbadd82 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -1304,7 +1304,7 @@ if (!section.needs_redistribution) continue; DistributeExcessBlockSizeToRows( - section.start_row, section.rowspan, section.block_size, + section.start_row, section.row_count, section.block_size, /* desired_block_size_is_rowspan */ false, border_block_spacing, section.block_size, rows); }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc index 1765ea4..bb46edd 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
@@ -215,7 +215,7 @@ NGTableTypes::Section NGTableTypes::CreateSection( const NGLayoutInputNode& section, wtf_size_t start_row, - wtf_size_t rows, + wtf_size_t row_count, LayoutUnit block_size, bool treat_as_tbody) { const Length& section_css_block_size = section.Style().LogicalHeight(); @@ -226,7 +226,7 @@ if (section_css_block_size.IsPercent()) percent = section_css_block_size.Percent(); return Section{start_row, - rows, + row_count, block_size, percent, is_constrained,
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h index 38f583c..9a0e843f 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
@@ -199,7 +199,7 @@ struct Section { wtf_size_t start_row; - wtf_size_t rowspan; + wtf_size_t row_count; LayoutUnit block_size; absl::optional<float> percent; bool is_constrained; @@ -220,7 +220,7 @@ static Section CreateSection(const NGLayoutInputNode&, wtf_size_t start_row, - wtf_size_t rowspan, + wtf_size_t row_count, LayoutUnit block_size, bool treat_as_tbody);
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc index 55dc9d64..45cc0d2 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
@@ -41,7 +41,7 @@ for (NGBlockNode row = To<NGBlockNode>(Node().FirstChild()); row; row = To<NGBlockNode>(row.NextSibling())) { DCHECK_LT(row_index, table_data.sections[section_index].start_row_index + - table_data.sections[section_index].rowspan); + table_data.sections[section_index].row_count); NGConstraintSpaceBuilder row_space_builder( table_data.table_writing_direction.GetWritingMode(), table_data.table_writing_direction, @@ -67,7 +67,7 @@ } if (ConstraintSpace().IsFixedBlockSize()) { // A fixed block-size should only occur for a section without children. - DCHECK_EQ(table_data.sections[section_index].rowspan, 0u); + DCHECK_EQ(table_data.sections[section_index].row_count, 0u); container_builder_.SetFragmentBlockSize( ConstraintSpace().AvailableSize().block_size); } else {
diff --git a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc index f9547a6..1bd7171b 100644 --- a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc +++ b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc
@@ -51,7 +51,7 @@ // SVG content require_fill = true; require_stroke = true; - FALLTHROUGH; + [[fallthrough]]; case EPointerEvents::kVisible: require_visible = true; can_hit_fill = true; @@ -68,7 +68,7 @@ case EPointerEvents::kPainted: require_fill = true; require_stroke = true; - FALLTHROUGH; + [[fallthrough]]; case EPointerEvents::kAll: can_hit_fill = true; can_hit_stroke = true;
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.cc b/third_party/blink/renderer/core/layout/scroll_anchor.cc index 1f69a2e..c998729 100644 --- a/third_party/blink/renderer/core/layout/scroll_anchor.cc +++ b/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -133,7 +133,7 @@ LayoutRect relative_bounds = LayoutRect(scroller ->LocalToVisibleContentQuad( - FloatQuad(gfx::RectF(local_bounds)), layout_object) + gfx::QuadF(gfx::RectF(local_bounds)), layout_object) .BoundingBox()); return relative_bounds;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc index 02c049c..1b6c1068 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
@@ -115,7 +115,7 @@ // |HasTransformRelatedProperty| is used for compositing so ensure it was // correctly set by the call to |StyleDidChange|. DCHECK_EQ(HasTransformRelatedProperty(), - StyleRef().HasTransformRelatedProperty()); + StyleRef().HasTransformRelatedPropertyForSVG()); transform_uses_reference_box_ = TransformHelper::DependsOnReferenceBox(StyleRef()); @@ -180,7 +180,7 @@ // Apply other mappings on local SVG coordinates. bool retval = SVGLayoutSupport::MapToVisualRectInAncestorSpace( *this, ancestor, gfx::RectF(rect), rect); - transform_state.SetQuad(FloatQuad(gfx::RectF(rect))); + transform_state.SetQuad(gfx::QuadF(gfx::RectF(rect))); return retval; }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h index 06c9c1b..181d071 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
@@ -57,7 +57,7 @@ NOT_DESTROYED(); return gfx::RectF(); } - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const final { NOT_DESTROYED(); }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc index 0ee8ba4..8fd3ab46 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -138,7 +138,7 @@ SVGLayoutSupport::MapLocalToAncestor(this, ancestor, transform_state, flags); } -void LayoutSVGInline::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutSVGInline::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); if (IsInLayoutNGInlineFormattingContext()) { @@ -148,7 +148,7 @@ const NGFragmentItem& item = *cursor.CurrentItem(); if (item.Type() == NGFragmentItem::kSvgText) { quads.push_back(LocalToAbsoluteQuad( - FloatQuad(SVGLayoutSupport::ExtendTextBBoxWithStroke( + gfx::QuadF(SVGLayoutSupport::ExtendTextBBoxWithStroke( *this, cursor.Current().ObjectBoundingBox(cursor))), mode)); } @@ -158,7 +158,7 @@ for (InlineFlowBox* box : *LineBoxes()) { gfx::RectF box_rect(box->FrameRect()); quads.push_back(LocalToAbsoluteQuad( - FloatQuad(SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, box_rect)), + gfx::QuadF(SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, box_rect)), mode)); } }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h index 741177e..d30b9eb 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -56,7 +56,7 @@ void MapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags) const final; - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const final; void AddOutlineRects(Vector<PhysicalRect>&, const PhysicalOffset& additional_offset,
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc index df4706b..d571790 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
@@ -71,10 +71,10 @@ SVGLayoutSupport::MapAncestorToLocal(*this, ancestor, transform_state, flags); } -void LayoutSVGModelObject::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutSVGModelObject::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); - quads.push_back(LocalToAbsoluteQuad(FloatQuad(StrokeBoundingBox()), mode)); + quads.push_back(LocalToAbsoluteQuad(gfx::QuadF(StrokeBoundingBox()), mode)); } // This method is called from inside PaintOutline(), and since we call @@ -138,7 +138,8 @@ SetNeedsTransformUpdate(); } - SetHasTransformRelatedProperty(StyleRef().HasTransformRelatedProperty()); + SetHasTransformRelatedProperty( + StyleRef().HasTransformRelatedPropertyForSVG()); SVGResources::UpdateClipPathFilterMask(*GetElement(), old_style, StyleRef());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h index c0d1d827..b5984ca 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
@@ -55,7 +55,7 @@ return StrokeBoundingBox(); } - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const override; gfx::RectF LocalBoundingBoxRectForAccessibility() const final;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc index d1ed7d9..06b7f257 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -46,8 +46,8 @@ #include "third_party/blink/renderer/core/paint/svg_text_painter.h" #include "third_party/blink/renderer/core/style/shadow_list.h" #include "third_party/blink/renderer/core/svg/svg_text_element.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -393,10 +393,10 @@ PhysicalOffset(clipped_point_in_contents.left, closest_box->Y())); } -void LayoutSVGText::AbsoluteQuads(Vector<FloatQuad>& quads, +void LayoutSVGText::AbsoluteQuads(Vector<gfx::QuadF>& quads, MapCoordinatesFlags mode) const { NOT_DESTROYED(); - quads.push_back(LocalToAbsoluteQuad(FloatQuad(StrokeBoundingBox()), mode)); + quads.push_back(LocalToAbsoluteQuad(gfx::QuadF(StrokeBoundingBox()), mode)); } void LayoutSVGText::Paint(const PaintInfo& paint_info) const {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h index 1f4dd61..7044d306 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
@@ -96,7 +96,7 @@ void UpdateLayout() override; - void AbsoluteQuads(Vector<FloatQuad>&, + void AbsoluteQuads(Vector<gfx::QuadF>&, MapCoordinatesFlags mode = 0) const override; void AddChild(LayoutObject* child,
diff --git a/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc b/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc index 73d9a1c..0e15735 100644 --- a/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc +++ b/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc
@@ -290,7 +290,7 @@ float baseline = font_data->GetFontMetrics().FloatAscent() / line_layout_item.ScalingFactor(); for (const SVGTextFragment& fragment : text_fragments_) { - FloatQuad fragment_quad = fragment.BoundingQuad(baseline); + gfx::QuadF fragment_quad = fragment.BoundingQuad(baseline); if (hit_test_location.Intersects(fragment_quad)) return true; }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc index 6da25717..1422698fc 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc +++ b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
@@ -32,7 +32,7 @@ switch (style.TextAnchor()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ETextAnchor::kStart: return is_ltr ? 0 : -length; case ETextAnchor::kMiddle: @@ -49,7 +49,7 @@ switch (style.TextAnchor()) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ETextAnchor::kStart: return !is_ltr; case ETextAnchor::kMiddle:
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_fragment.h b/third_party/blink/renderer/core/layout/svg/svg_text_fragment.h index 99bab5a..b764c9b 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_text_fragment.h +++ b/third_party/blink/renderer/core/layout/svg/svg_text_fragment.h
@@ -65,8 +65,8 @@ return BuildNormalFragmentTransform().MapRect(fragment_rect); } - FloatQuad BoundingQuad(float baseline) const { - FloatQuad fragment_quad(gfx::RectF(x, y - baseline, width, height)); + gfx::QuadF BoundingQuad(float baseline) const { + gfx::QuadF fragment_quad(gfx::RectF(x, y - baseline, width, height)); if (!IsTransformed()) return fragment_quad; return BuildNormalFragmentTransform().MapQuad(fragment_quad);
diff --git a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc index 42bea3f..1e1575c 100644 --- a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc +++ b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
@@ -439,10 +439,10 @@ // mozilla doesn't do this so I decided we don't neither. break; } - FALLTHROUGH; + [[fallthrough]]; case Length::kAuto: have_auto = true; - FALLTHROUGH; + [[fallthrough]]; default: // If the column is a percentage width, do not let the spanning cell // overwrite the width value. This caused a mis-layout on amazon.com.
diff --git a/third_party/blink/renderer/core/layout/text_decoration_offset_base.cc b/third_party/blink/renderer/core/layout/text_decoration_offset_base.cc index e07908382..d623771 100644 --- a/third_party/blink/renderer/core/layout/text_decoration_offset_base.cc +++ b/third_party/blink/renderer/core/layout/text_decoration_offset_base.cc
@@ -58,7 +58,7 @@ switch (underline_position) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case ResolvedUnderlinePosition::kNearAlphabeticBaselineFromFont: DCHECK(RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled()); return ComputeUnderlineOffsetFromFont(font_metrics,
diff --git a/third_party/blink/renderer/core/loader/subresource_filter.cc b/third_party/blink/renderer/core/loader/subresource_filter.cc index 8b7cbeed..73e88f8 100644 --- a/third_party/blink/renderer/core/loader/subresource_filter.cc +++ b/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -131,7 +131,7 @@ mojom::ConsoleMessageLevel::kError, GetErrorStringForDisallowedLoad(resource_url))); } - FALLTHROUGH; + [[fallthrough]]; case WebDocumentSubresourceFilter::kWouldDisallow: // TODO(csharrison): Consider posting a task to the main thread from // worker thread, or adding support for DidObserveLoadingBehavior to
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc index cb6b39e..f7df9df 100644 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
@@ -40,6 +40,8 @@ base::Milliseconds(5); static constexpr base::TimeDelta kEvaluationDelay = base::Milliseconds(3000); static constexpr base::TimeDelta kEvaluationInterval = base::Minutes(1); +// Consider a fixed number of tap targets. +static constexpr int kMaxTapTargets = 1000; MobileFriendlinessChecker::MobileFriendlinessChecker(LocalFrameView& frame_view) : frame_view_(&frame_view), @@ -154,69 +156,89 @@ !To<HTMLAnchorElement>(node)->Href().IsEmpty()); } +// Skip the whole subtree if the object is invisible. Some elements in subtree +// may have visibility: visible property which should not be ignored for +// correctness, but it is rare and we prioritize performance. +bool ShouldSkipSubree(const LayoutObject* object) { + const auto& style = object->StyleRef(); + return object->IsElementContinuation() || + style.Visibility() != EVisibility::kVisible || + style.ContentVisibility() != EContentVisibility::kVisible; +} + +void AddElement(const LayoutObject* object, + WTF::HashSet<Member<const LayoutObject>>* tap_targets, + int finger_radius, + Vector<int>& x_positions, + Vector<std::pair<int, EdgeOrCenter>>& vertices) { + Node* node = object->GetNode(); + if (!node || !IsTapTargetCandidate(node)) { + return; + } + if (Element* element = DynamicTo<Element>(object->GetNode())) { + // Expand each corner by the size of fingertips. + const gfx::RectF rect = element->GetBoundingClientRectNoLifecycleUpdate(); + if (!rect.IsEmpty()) { + if (!tap_targets->insert(object).is_new_entry) { + const int top = ClampTo<int>(rect.y() - finger_radius); + const int bottom = ClampTo<int>(rect.bottom() + finger_radius); + const int left = ClampTo<int>(rect.x() - finger_radius); + const int right = ClampTo<int>(rect.right() + finger_radius); + const int center = right / 2 + left / 2; + vertices.emplace_back(top, EdgeOrCenter::StartEdge(left, right)); + vertices.emplace_back(bottom / 2 + top / 2, + EdgeOrCenter::Center(center)); + vertices.emplace_back(bottom, EdgeOrCenter::EndEdge(left, right)); + x_positions.push_back(left); + x_positions.push_back(right); + x_positions.push_back(center); + } + } + } +} + // Scans full DOM tree and register all tap regions. -// root: DOM tree's root. +// frame_view: DOM tree's root. // finger_radius: Extends every tap regions with given pixels. // x_positions: Collects and inserts every x dimension positions. // vertices: Inserts y dimension keyed vertex positions with its attribute. // Returns total count of tap targets. // Returns kTimeBudgetExceeded if time limit exceeded. int ExtractAndCountAllTapTargets( - LayoutObject* const root, + const LocalFrameView& frame_view, int finger_radius, - int scroll_offset, - int max_height, Vector<int>& x_positions, const base::Time& started, Vector<std::pair<int, EdgeOrCenter>>& vertices) { vertices.clear(); - int tap_targets = 0; - for (LayoutObject* object = root; object;) { - if (IsTimeBudgetExpired(started)) - return kTimeBudgetExceeded; + LayoutObject* const root = + frame_view.GetFrame().GetDocument()->GetLayoutView(); + WTF::HashSet<Member<const LayoutObject>> tap_targets; - Node* node = object->GetNode(); - const ComputedStyle* style = object->Style(); - if (!node || !IsTapTargetCandidate(node)) { - object = object->NextInPreOrder(); - continue; + // Simultaneously iterate front-to-back and back-to-front to consider + // both page headers and footers using the same time budget. + for (const LayoutObject *forward = root, *backward = root; + forward && backward && tap_targets.size() < kMaxTapTargets;) { + if (IsTimeBudgetExpired(started)) { + return kTimeBudgetExceeded; } - if (object->IsElementContinuation() || - style->Visibility() != EVisibility::kVisible || - style->ContentVisibility() != EContentVisibility::kVisible) { - // Skip the whole subtree in this case. Some elements in subtree may have - // visibility: visible property which should not be ignored for - // correctness, but it is rare and we priority performance. - object = object->NextInPreOrderAfterChildren(); - continue; + + if (ShouldSkipSubree(forward)) { + forward = forward->NextInPreOrderAfterChildren(); + } else { + AddElement(forward, &tap_targets, finger_radius, x_positions, vertices); + forward = forward->NextInPreOrder(); } - if (Element* element = DynamicTo<Element>(object->GetNode())) { - // Expand each corner by the size of fingertips. - const gfx::RectF rect = element->GetBoundingClientRectNoLifecycleUpdate(); - if (rect.IsEmpty()) { - object = object->NextInPreOrder(); - continue; - } - const int top = ClampTo<int>(rect.y() - finger_radius + scroll_offset); - const int bottom = - ClampTo<int>(rect.bottom() + finger_radius + scroll_offset); - const int left = ClampTo<int>(rect.x() - finger_radius); - const int right = ClampTo<int>(rect.right() + finger_radius); - const int center = right / 2 + left / 2; - if (top > max_height) { - break; - } - vertices.emplace_back(top, EdgeOrCenter::StartEdge(left, right)); - vertices.emplace_back(bottom / 2 + top / 2, EdgeOrCenter::Center(center)); - vertices.emplace_back(bottom, EdgeOrCenter::EndEdge(left, right)); - x_positions.push_back(left); - x_positions.push_back(right); - x_positions.push_back(center); - tap_targets++; + + if (ShouldSkipSubree(backward)) { + backward = backward->PreviousInPostOrderBeforeChildren(nullptr); + } else { + AddElement(backward, &tap_targets, finger_radius, x_positions, vertices); + backward = backward->PreviousInPostOrder(nullptr); } - object = object->NextInPreOrder(); } - return tap_targets; + + return static_cast<int>(tap_targets.size()); } // Compress the x-dimension range and overwrites the value. @@ -309,18 +331,10 @@ Vector<std::pair<int, EdgeOrCenter>> vertices; Vector<int> x_positions; - // This is like DOMWindow::scrollY() but without layout update. - const int scroll_y = AdjustForAbsoluteZoom::AdjustScroll( - frame_view_->LayoutViewport()->GetScrollOffset().y(), - frame_view_->GetFrame().PageZoomFactor()); - const int screen_height = - frame_view_->LayoutViewport()->GetLayoutBox()->Size().Height().ToInt(); - // Scan full DOM tree and extract every corner and center position of tap // targets. const int all_tap_targets = ExtractAndCountAllTapTargets( - frame_view_->GetFrame().GetDocument()->GetLayoutView(), finger_radius, - scroll_y, screen_height, x_positions, started, vertices); + *frame_view_, finger_radius, x_positions, started, vertices); if (all_tap_targets <= 0) return all_tap_targets; // Means there is no tap target or timeout. @@ -347,7 +361,7 @@ if (bad_tap_targets == kTimeBudgetExceeded) return kTimeBudgetExceeded; - return bad_tap_targets * 100.0 / all_tap_targets; + return std::ceil(bad_tap_targets * 100.0 / all_tap_targets); } void MobileFriendlinessChecker::Activate(TimerBase*) {
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc index b5860b0..1f20d468 100644 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc
@@ -763,7 +763,7 @@ TEST_F(ClockFixedMobileFriendlinessCheckerTest, SingleTapTarget) { MobileFriendliness actual_mf = CalculateMainFrameMetricsForHTMLString(R"( -</html> +<html> <head> <meta name="viewport" content="width=480, initial-scale=1"> </head> @@ -906,7 +906,7 @@ </body> </html> )"); - EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 33); + EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 34); } TEST_F(ClockFixedMobileFriendlinessCheckerTest, TooCloseTapTargetsHorizontal) { @@ -958,7 +958,7 @@ </body> </html> )"); - EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 33); + EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 34); } TEST_F(ClockFixedMobileFriendlinessCheckerTest, GridGoodTargets3X3) { @@ -1146,92 +1146,6 @@ EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 100); } -TEST_F(ClockFixedMobileFriendlinessCheckerTest, - BadTapTargetBelowFirstOnePager) { - MobileFriendliness actual_mf = CalculateMainFrameMetricsForHTMLString(R"( -<html> - <head> - <meta name="viewport" content="width=480, initial-scale=1"> - </head> - <body style="font-size: 18px"> - <button style="position:absolute; width:50px; height:50px"> - a - </button> - <button style="position:relative; width:50px; height:50px"> - b - </button> - <!-- below area must be ignored --> - <div style="margin-top: 800px"> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - have - </div> - </a> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - enough - </div> - </a> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - spans - </div> - </a> - </div> - </body> -</html> -)"); - EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 100); -} - -TEST_F(ClockFixedMobileFriendlinessCheckerTest, - BadTapTargetBelowFirstOnePagerWithScroll) { - auto eval_btt_with_scroll = [&](const int scroll_offset) { - return CalculateMainFrameMetricsForHTMLString(R"( -<html> - <head> - <meta name="viewport" content="width=480, initial-scale=1"> - </head> - <body style="font-size: 18px"> - <button style="position:absolute; width:50px; height:50px"> - a - </button> - <button style="position:relative; width:50px; height:50px"> - b - </button> - <!-- below area must be ignored --> - <div style="margin-top: 800px"> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - have - </div> - </a> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - enough - </div> - </a> - <a href="about:blank"> - <div style="width: 50px;height: 50px; margin: 50px; display:inline-block"> - spans - </div> - </a> - </div> - </body> -</html> -)", - 1.0 /*=device_scale*/, - scroll_offset) - .bad_tap_targets_ratio; - }; - - // BadTapTargetResult must not be affected by scrolling offset. - EXPECT_EQ(eval_btt_with_scroll(0), 100); - EXPECT_EQ(eval_btt_with_scroll(400), 100); - EXPECT_EQ(eval_btt_with_scroll(800), 100); - EXPECT_EQ(eval_btt_with_scroll(1200), 100); -} - TEST_F(ClockFixedMobileFriendlinessCheckerTest, TapTargetTimeout) { clock_override_.reset(); clock_override_ = std::make_unique<base::subtle::ScopedTimeClockOverrides>( @@ -1272,6 +1186,21 @@ EXPECT_EQ(actual_mf.bad_tap_targets_ratio, -2); } +TEST_F(ClockFixedMobileFriendlinessCheckerTest, TapTargetPositionFixed) { + MobileFriendliness actual_mf = CalculateMainFrameMetricsForHTMLString(R"( +<html> + <head> + <meta name="viewport" content="width=480, initial-scale=1"> + </head> + <body style="font-size: 18px"> + <button style="position: fixed; bottom: 0; right: 100">fixed</button> + <button style="position: fixed; bottom: 10; right: 100">fixed</button> + </body> +</html> +)"); + EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 100); +} + TEST_F(ClockFixedMobileFriendlinessCheckerTest, IFrameTest) { url_test_helpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(kBaseUrl), blink::test::CoreTestDataPath(),
diff --git a/third_party/blink/renderer/core/page/page_widget_delegate.cc b/third_party/blink/renderer/core/page/page_widget_delegate.cc index ebeba55c..f2941b5 100644 --- a/third_party/blink/renderer/core/page/page_widget_delegate.cc +++ b/third_party/blink/renderer/core/page/page_widget_delegate.cc
@@ -198,7 +198,7 @@ case WebInputEvent::Type::kGesturePinchBegin: // Gesture pinch events are handled entirely on the compositor. DLOG(INFO) << "Gesture pinch ignored by main thread."; - FALLTHROUGH; + [[fallthrough]]; case WebInputEvent::Type::kGesturePinchEnd: case WebInputEvent::Type::kGesturePinchUpdate: return WebInputEventResult::kNotHandled;
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc index 067c491d..da2e8280 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
@@ -24,6 +24,7 @@ #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size_conversions.h" namespace blink { @@ -53,12 +54,12 @@ ? layout_box->PhysicalContentBoxRect() : layout_box->PhysicalPaddingBoxRect(); - FloatQuad quad = layout_box->LocalRectToAbsoluteQuad(rect); + gfx::QuadF quad = layout_box->LocalRectToAbsoluteQuad(rect); if (!quad.IsRectilinear()) return false; - gfx::Rect bounding_box = ToEnclosingRect(quad.BoundingBox()); + gfx::Rect bounding_box = gfx::ToEnclosingRect(quad.BoundingBox()); gfx::Size icb_size = top_document.GetLayoutView()->GetLayoutSize();
diff --git a/third_party/blink/renderer/core/page/spatial_navigation.cc b/third_party/blink/renderer/core/page/spatial_navigation.cc index e071939..d8d19a6c 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -149,10 +149,10 @@ // If it has empty quads, it's most likely not a line broken ("fragmented") // text. <a><div></div></a> has for example one empty rect. - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; layout_object.AbsoluteQuads(quads); - for (const FloatQuad& quad : quads) { - if (quad.IsEmpty()) + for (const gfx::QuadF& quad : quads) { + if (quad.BoundingBox().IsEmpty()) return 1; } @@ -874,7 +874,7 @@ const SpatialNavigationDirection direction) { // For accuracy, use the first visible fragment (not the fragmented element's // entire bounding rect which is a union of all fragments) as search origin. - Vector<FloatQuad> fragments; + Vector<gfx::QuadF> fragments; fragmented.AbsoluteQuads( fragments, kTraverseDocumentBoundaries | kApplyRemoteMainFrameTransform); switch (direction) {
diff --git a/third_party/blink/renderer/core/page/touch_adjustment.cc b/third_party/blink/renderer/core/page/touch_adjustment.cc index 7a57406..0d249aa 100644 --- a/third_party/blink/renderer/core/page/touch_adjustment.cc +++ b/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -36,11 +36,12 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/text/text_break_iterator.h" #include "ui/display/screen_info.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -59,17 +60,19 @@ DISALLOW_NEW(); public: - SubtargetGeometry(Node* node, const FloatQuad& quad) + SubtargetGeometry(Node* node, const gfx::QuadF& quad) : node_(node), quad_(quad) {} void Trace(Visitor* visitor) const { visitor->Trace(node_); } Node* GetNode() const { return node_; } - FloatQuad Quad() const { return quad_; } - gfx::Rect BoundingBox() const { return quad_.EnclosingBoundingBox(); } + gfx::QuadF Quad() const { return quad_; } + gfx::Rect BoundingBox() const { + return gfx::ToEnclosingRect(quad_.BoundingBox()); + } private: Member<Node> node_; - FloatQuad quad_; + gfx::QuadF quad_; }; } // namespace touch_adjustment @@ -156,11 +159,11 @@ } static inline void AppendQuadsToSubtargetList( - Vector<FloatQuad>& quads, + Vector<gfx::QuadF>& quads, Node* node, SubtargetGeometryList& subtargets) { - Vector<FloatQuad>::const_iterator it = quads.begin(); - const Vector<FloatQuad>::const_iterator end = quads.end(); + Vector<gfx::QuadF>::const_iterator it = quads.begin(); + const Vector<gfx::QuadF>::const_iterator end = quads.end(); for (; it != end; ++it) subtargets.push_back(SubtargetGeometry(node, *it)); } @@ -171,7 +174,7 @@ // Node guaranteed to have layoutObject due to check in node filter. DCHECK(node->GetLayoutObject()); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; node->GetLayoutObject()->AbsoluteQuads(quads); AppendQuadsToSubtargetList(quads, node, subtargets); @@ -204,7 +207,7 @@ int offset; while ((offset = word_iterator->next()) != -1) { if (IsWordTextBreak(word_iterator)) { - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; text_layout_object->AbsoluteQuadsForRange(quads, last_offset, offset); AppendQuadsToSubtargetList(quads, text_node, subtargets); } @@ -218,7 +221,7 @@ const LayoutTextSelectionStatus& selection_status = frame_selection.ComputeLayoutSelectionStatus(*text_layout_object); // If selected, make subtargets out of only the selected part of the text. - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; text_layout_object->AbsoluteQuadsForRange(quads, selection_status.start, selection_status.end); AppendQuadsToSubtargetList(quads, text_node, subtargets); @@ -409,7 +412,7 @@ const gfx::Rect& touch_area, gfx::Point& adjusted_point) { LocalFrameView* view = geom.GetNode()->GetDocument().View(); - FloatQuad quad = geom.Quad(); + gfx::QuadF quad = geom.Quad(); if (quad.IsRectilinear()) { gfx::Rect bounds = view->ConvertToRootFrame(geom.BoundingBox()); @@ -436,20 +439,20 @@ gfx::PointF p2 = ConvertToRootFrame(view, quad.p2()); gfx::PointF p3 = ConvertToRootFrame(view, quad.p3()); gfx::PointF p4 = ConvertToRootFrame(view, quad.p4()); - quad = FloatQuad(p1, p2, p3, p4); + quad = gfx::QuadF(p1, p2, p3, p4); - if (quad.ContainsPoint(gfx::PointF(touch_point))) { + if (quad.Contains(gfx::PointF(touch_point))) { adjusted_point = touch_point; return true; } // Pull point towards the center of the element. - gfx::PointF center = quad.Center(); + gfx::PointF center = quad.CenterPoint(); AdjustPointToRect(center, touch_area); adjusted_point = gfx::ToRoundedPoint(center); - return quad.ContainsPoint(gfx::PointF(adjusted_point)); + return quad.Contains(gfx::PointF(adjusted_point)); } // A generic function for finding the target node with the lowest distance
diff --git a/third_party/blink/renderer/core/paint/applied_decoration_painter.cc b/third_party/blink/renderer/core/paint/applied_decoration_painter.cc index 37605402..4cac1c2f 100644 --- a/third_party/blink/renderer/core/paint/applied_decoration_painter.cc +++ b/third_party/blink/renderer/core/paint/applied_decoration_painter.cc
@@ -23,7 +23,7 @@ case ETextDecorationStyle::kDotted: case ETextDecorationStyle::kDashed: context_.SetShouldAntialias(decoration_info_.ShouldAntialias()); - FALLTHROUGH; + [[fallthrough]]; default: context_.DrawLineForText(decoration_info_.StartPoint(), decoration_info_.Width(), auto_dark_mode, flags);
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc index f8ef6383..eab1152 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.cc +++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -13,12 +13,14 @@ #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" +#include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" #include "third_party/blink/renderer/core/style/border_edge.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" +#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" namespace blink { @@ -51,25 +53,6 @@ : LayoutUnit(); } -PhysicalOffset AccumulatedScrollOffsetForFixedBackground( - const LayoutBoxModelObject& object, - const LayoutBoxModelObject* container) { - PhysicalOffset result; - if (&object == container) - return result; - - LayoutObject::AncestorSkipInfo skip_info(container); - for (const LayoutBlock* block = object.ContainingBlock(&skip_info); - block && !skip_info.AncestorSkipped(); - block = block->ContainingBlock(&skip_info)) { - if (block->IsScrollContainer()) - result += block->ScrolledContentOffset(); - if (block == container) - break; - } - return result; -} - } // anonymous namespace bool NeedsFullSizeDestination(const FillLayer& fill_layer) { @@ -228,6 +211,7 @@ void BackgroundImageGeometry::UseFixedAttachment( const PhysicalOffset& attachment_point) { + DCHECK(has_background_fixed_to_viewport_); PhysicalOffset fixed_adjustment = attachment_point - unsnapped_dest_rect_.offset; fixed_adjustment.ClampNegativeToZero(); @@ -327,58 +311,33 @@ } bool BackgroundImageGeometry::ShouldUseFixedAttachment( - const FillLayer& fill_layer) { - // Solid color background should use default attachment. - return fill_layer.GetImage() && + const FillLayer& fill_layer) const { + // Only backgrounds fixed to viewport should be treated as fixed attachment. + // See comments in the private constructor. + return has_background_fixed_to_viewport_ && + // Solid color background should use default attachment. + fill_layer.GetImage() && fill_layer.Attachment() == EFillAttachment::kFixed; } namespace { -PhysicalRect FixedAttachmentPositioningArea( - const LayoutBoxModelObject& obj, - const LayoutBoxModelObject* container) { - // TODO(crbug.com/667006): We should consider ancestor with transform as the - // fixed background container, instead of always the viewport. - const LocalFrameView* frame_view = obj.GetFrameView(); - if (!frame_view) - return PhysicalRect(); - - const ScrollableArea* layout_viewport = frame_view->LayoutViewport(); +PhysicalRect FixedAttachmentPositioningArea(const PaintInfo& paint_info, + const LayoutBoxModelObject& obj) { + DCHECK(obj.View()); + gfx::PointF viewport_origin_in_local_space = + GeometryMapper::SourceToDestinationProjection( + obj.View()->FirstFragment().LocalBorderBoxProperties().Transform(), + paint_info.context.GetPaintController() + .CurrentPaintChunkProperties() + .Transform()) + .MapPoint(gfx::PointF()); + DCHECK(obj.GetFrameView()); + const ScrollableArea* layout_viewport = obj.GetFrameView()->LayoutViewport(); DCHECK(layout_viewport); - - PhysicalRect rect(PhysicalOffset(), - PhysicalSize(layout_viewport->VisibleContentRect().size())); - - if (const auto* layout_view = DynamicTo<LayoutView>(obj)) { - if (!(layout_view->GetBackgroundPaintLocation() & - kBackgroundPaintInContentsSpace)) - return rect; - // The LayoutView is the only object that can paint a fixed background into - // its scrolling contents layer, so it gets a special adjustment here. - rect.offset = layout_view->ScrolledContentOffset(); - } - - rect.Move(AccumulatedScrollOffsetForFixedBackground(obj, container)); - - if (!container) - return rect; - - rect.Move( - -container->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms)); - - // By now we have converted the viewport rect to the border box space of - // |container|, however |container| does not necessarily create a paint - // offset translation node, thus its paint offset must be added to convert - // the rect to the space of the transform node. - // TODO(trchen): This function does only one simple thing -- mapping the - // viewport rect from frame space to whatever space the current paint - // context uses. However we can't always invoke geometry mapper because - // there are at least one caller uses this before PrePaint phase. - DCHECK_GE(container->GetDocument().Lifecycle().GetState(), - DocumentLifecycle::kPrePaintClean); - rect.Move(container->FirstFragment().PaintOffset()); - return rect; + return PhysicalRect( + PhysicalOffset::FromPointFRound(viewport_origin_in_local_space), + PhysicalSize(layout_viewport->VisibleContentRect().size())); } } // Anonymous namespace @@ -386,7 +345,10 @@ BackgroundImageGeometry::BackgroundImageGeometry( const LayoutView& view, const PhysicalOffset& element_positioning_area_offset) - : box_(&view), positioning_box_(&view.RootBox()), painting_view_(true) { + : box_(&view), positioning_box_(&view.RootBox()) { + has_background_fixed_to_viewport_ = + view.StyleRef().HasFixedAttachmentBackgroundImage(); + painting_view_ = true; // The background of the box generated by the root element covers the // entire canvas and will be painted by the view object, but the we should // still use the root element box for positioning. @@ -397,19 +359,17 @@ BackgroundImageGeometry::BackgroundImageGeometry( const LayoutBoxModelObject& obj) - : box_(&obj), positioning_box_(&obj) { - // Specialized constructor should be used for LayoutView. - DCHECK(!IsA<LayoutView>(obj)); -} + : BackgroundImageGeometry(&obj, &obj) {} BackgroundImageGeometry::BackgroundImageGeometry( const LayoutTableCell& cell, const LayoutObject* background_object) - : box_(&cell), - positioning_box_(background_object && !background_object->IsTableCell() - ? &To<LayoutBoxModelObject>(*background_object) - : &cell), - painting_table_cell_(true) { + : BackgroundImageGeometry( + &cell, + background_object && !background_object->IsTableCell() + ? &To<LayoutBoxModelObject>(*background_object) + : &cell) { + painting_table_cell_ = true; cell_using_container_background_ = background_object && !background_object->IsTableCell(); if (cell_using_container_background_) { @@ -425,7 +385,8 @@ PhysicalOffset cell_offset, const LayoutBox& table_part, PhysicalSize table_part_size) - : box_(&cell), positioning_box_(&table_part), painting_table_cell_(true) { + : BackgroundImageGeometry(&cell, &table_part) { + painting_table_cell_ = true; cell_using_container_background_ = true; element_positioning_area_offset_ = cell_offset; positioning_size_override_ = table_part_size; @@ -433,12 +394,10 @@ BackgroundImageGeometry::BackgroundImageGeometry( const NGPhysicalBoxFragment& fragment) - : box_(To<LayoutBoxModelObject>(fragment.GetLayoutObject())), - positioning_box_(box_) { - DCHECK(box_); + : BackgroundImageGeometry( + To<LayoutBoxModelObject>(fragment.GetLayoutObject()), + To<LayoutBoxModelObject>(fragment.GetLayoutObject())) { DCHECK(box_->IsBox()); - // Specialized constructor should be used for LayoutView. - DCHECK(!IsA<LayoutView>(box_)); if (!fragment.IsOnlyForNode()) { // The element is block-fragmented. We need to calculate the correct @@ -450,6 +409,35 @@ } } +BackgroundImageGeometry::BackgroundImageGeometry( + const LayoutBoxModelObject* box, + const LayoutBoxModelObject* positioning_box) + : box_(box), positioning_box_(positioning_box) { + // Specialized constructor should be used for LayoutView. + DCHECK(!IsA<LayoutView>(box)); + DCHECK(box); + DCHECK(positioning_box); + if (positioning_box->StyleRef().HasFixedAttachmentBackgroundImage()) { + has_background_fixed_to_viewport_ = true; + // https://www.w3.org/TR/css-transforms-1/#transform-rendering + // Fixed backgrounds on the root element are affected by any transform + // specified for that element. For all other elements that are effected + // by a transform, a value of fixed for the background-attachment property + // is treated as if it had a value of scroll. + for (const LayoutObject* container = box; + container && !IsA<LayoutView>(container); + container = container->Container()) { + // Not using HasTransformRelatedProperty(), to excludes will-change: + // transform, etc. Otherwise at least + // compositing/backgrounds/fixed-backgrounds.html will fail. + if (container->HasTransform()) { + has_background_fixed_to_viewport_ = false; + break; + } + } + } +} + void BackgroundImageGeometry::ComputeDestRectAdjustments( const FillLayer& fill_layer, const PhysicalRect& unsnapped_positioning_area, @@ -468,7 +456,7 @@ snapped_dest_adjust = unsnapped_dest_adjust; return; } - FALLTHROUGH; + [[fallthrough]]; case EFillBox::kPadding: unsnapped_dest_adjust = positioning_box_->BorderBoxOutsets(); if (disallow_border_derived_adjustment) { @@ -567,7 +555,7 @@ snapped_box_outset = unsnapped_box_outset; return; } - FALLTHROUGH; + [[fallthrough]]; case EFillBox::kPadding: unsnapped_box_outset = positioning_box_->BorderBoxOutsets(); if (disallow_border_derived_adjustment) { @@ -603,8 +591,7 @@ } void BackgroundImageGeometry::ComputePositioningArea( - const LayoutBoxModelObject* container, - PaintPhase paint_phase, + const PaintInfo& paint_info, const FillLayer& fill_layer, const PhysicalRect& paint_rect, PhysicalRect& unsnapped_positioning_area, @@ -613,9 +600,8 @@ PhysicalOffset& snapped_box_offset) { if (ShouldUseFixedAttachment(fill_layer)) { // No snapping for fixed attachment. - SetHasNonLocalGeometry(); unsnapped_positioning_area = - FixedAttachmentPositioningArea(*box_, container); + FixedAttachmentPositioningArea(paint_info, *box_); unsnapped_dest_rect_ = snapped_dest_rect_ = snapped_positioning_area = unsnapped_positioning_area; } else { @@ -650,7 +636,7 @@ // * We are painting a block-fragmented box. // * There is a border image, because it may not be opaque or may be outset. bool disallow_border_derived_adjustment = - !ShouldPaintSelfBlockBackground(paint_phase) || + !ShouldPaintSelfBlockBackground(paint_info.phase) || fill_layer.Composite() != CompositeOperator::kCompositeSourceOver || painting_view_ || painting_table_cell_ || box_has_multiple_fragments_ || positioning_box_->StyleRef().BorderImage().GetImage() || @@ -813,10 +799,12 @@ return; } -void BackgroundImageGeometry::Calculate(const LayoutBoxModelObject* container, - PaintPhase paint_phase, +void BackgroundImageGeometry::Calculate(const PaintInfo& paint_info, const FillLayer& fill_layer, const PhysicalRect& paint_rect) { + DCHECK_GE(box_->GetDocument().Lifecycle().GetState(), + DocumentLifecycle::kPrePaintClean); + // Unsnapped positioning area is used to derive quantities // that reference source image maps and define non-integer values, such // as phase and position. @@ -832,7 +820,7 @@ PhysicalOffset snapped_box_offset; // This method also sets the destination rects. - ComputePositioningArea(container, paint_phase, fill_layer, paint_rect, + ComputePositioningArea(paint_info, fill_layer, paint_rect, unsnapped_positioning_area, snapped_positioning_area, unsnapped_box_offset, snapped_box_offset);
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.h b/third_party/blink/renderer/core/paint/background_image_geometry.h index fa25081..f59ab75 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.h +++ b/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -24,6 +24,7 @@ class LayoutTableCell; class LayoutView; class NGPhysicalBoxFragment; +struct PaintInfo; class BackgroundImageGeometry { STACK_ALLOCATED(); @@ -40,7 +41,7 @@ const LayoutObject* background_object); // Generic constructor for all other elements. - BackgroundImageGeometry(const LayoutBoxModelObject&); + explicit BackgroundImageGeometry(const LayoutBoxModelObject&); // Constructor for TablesNG table parts. BackgroundImageGeometry(const LayoutNGTableCell& cell, @@ -50,8 +51,10 @@ explicit BackgroundImageGeometry(const NGPhysicalBoxFragment&); - void Calculate(const LayoutBoxModelObject* container, - PaintPhase, + // Calculates data members. This must be called before any of the following + // getters is called. The document lifecycle phase must be at least + // PrePaintClean. + void Calculate(const PaintInfo& paint_info, const FillLayer&, const PhysicalRect& paint_rect); @@ -87,10 +90,6 @@ // the image if used as a pattern with background-repeat: space. const PhysicalSize& SpaceSize() const { return repeat_spacing_; } - // Has background-attachment: fixed. Implies that we can't always cheaply - // compute the destination rects. - bool HasNonLocalGeometry() const { return has_non_local_geometry_; } - // Whether the background needs to be positioned relative to a container // element. Only used for tables. bool CellUsingContainerBackground() const { @@ -103,7 +102,10 @@ InterpolationQuality ImageInterpolationQuality() const; private: - static bool ShouldUseFixedAttachment(const FillLayer&); + BackgroundImageGeometry(const LayoutBoxModelObject* box, + const LayoutBoxModelObject* positioning_box); + + bool ShouldUseFixedAttachment(const FillLayer&) const; void SetSpaceSize(const PhysicalSize& repeat_spacing) { repeat_spacing_ = repeat_spacing; @@ -127,7 +129,6 @@ void SetSpaceY(LayoutUnit space, LayoutUnit extra_offset); void UseFixedAttachment(const PhysicalOffset& attachment_point); - void SetHasNonLocalGeometry() { has_non_local_geometry_ = true; } PhysicalOffset GetPositioningOffsetForCell(const LayoutTableCell&, const LayoutBox&); PhysicalSize GetBackgroundObjectDimensions(const LayoutTableCell&, @@ -152,8 +153,7 @@ LayoutRectOutsets&, LayoutRectOutsets&) const; - void ComputePositioningArea(const LayoutBoxModelObject*, - PaintPhase, + void ComputePositioningArea(const PaintInfo&, const FillLayer&, const PhysicalRect&, PhysicalRect&, @@ -192,7 +192,7 @@ PhysicalOffset phase_; PhysicalSize tile_size_; PhysicalSize repeat_spacing_; - bool has_non_local_geometry_ = false; + bool has_background_fixed_to_viewport_ = false; bool painting_view_ = false; bool painting_table_cell_ = false; bool cell_using_container_background_ = false;
diff --git a/third_party/blink/renderer/core/paint/box_border_painter.cc b/third_party/blink/renderer/core/paint/box_border_painter.cc index 85cfdbb..668c8f2d 100644 --- a/third_party/blink/renderer/core/paint/box_border_painter.cc +++ b/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -298,7 +298,7 @@ context.FillDRRect(adjusted_outer, inner, color, auto_dark_mode); break; } - FALLTHROUGH; + [[fallthrough]]; default: context.FillDRRect(outer, inner, color, auto_dark_mode); break; @@ -1857,12 +1857,12 @@ // https://bugs.webkit.org/show_bug.cgi?id=58608 if (side == BoxSide::kTop || side == BoxSide::kLeft) color = color.Dark(); - FALLTHROUGH; + [[fallthrough]]; case EBorderStyle::kOutset: if (style == EBorderStyle::kOutset && (side == BoxSide::kBottom || side == BoxSide::kRight)) color = color.Dark(); - FALLTHROUGH; + [[fallthrough]]; case EBorderStyle::kSolid: DrawSolidBoxSide(context, x1, y1, x2, y2, side, color, adjacent_width1, adjacent_width2, antialias, auto_dark_mode);
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc index c53010ad..e9b6328b 100644 --- a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -277,7 +277,7 @@ // onto an infinite canvas. In cases where it has a transform we can't // apply incremental invalidation, because the visual rect is no longer // axis-aligned to the LayoutView. - if (root_object->StyleRef().HasTransform()) + if (root_object->HasTransform()) return BackgroundInvalidationType::kFull; } }
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index b5ba48e..ceb3c4b 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -957,8 +957,7 @@ SkBlendMode composite_op = SkBlendMode::kSrcOver; absl::optional<ScopedInterpolationQuality> interpolation_quality_context; if (fill_layer_info.should_paint_image) { - geometry.Calculate(paint_info.PaintContainer(), paint_info.phase, bg_layer, - scrolled_paint_rect); + geometry.Calculate(paint_info, bg_layer, scrolled_paint_rect); image = fill_layer_info.image->GetImage( geometry.ImageClient(), geometry.ImageDocument(), geometry.ImageStyle(style_), gfx::SizeF(geometry.TileSize()));
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc index 701d69c..d37067e 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -2052,6 +2052,7 @@ padding: 5px; background: lightblue; } + } </style> <div id="target"> <div id="textContainer"> @@ -2084,39 +2085,6 @@ EXPECT_FALSE(CcLayerByDOMElementId("target")->contents_opaque_for_text()); } -TEST_P(CompositingSimTest, ChangingDrawsContentRequiresFullUpdate) { - InitializeWithHTML(R"HTML( - <!DOCTYPE html> - <style> - #target { - width: 100px; - height: 100px; - will-change: transform; - } - </style> - <div id="target"></div> - )HTML"); - - Compositor().BeginFrame(); - - // Initially, no update is needed. - EXPECT_FALSE(paint_artifact_compositor()->NeedsUpdate()); - EXPECT_FALSE(CcLayerByDOMElementId("target")->DrawsContent()); - - // Clear the previous update to ensure we record a new one in the next update. - paint_artifact_compositor()->ClearPreviousUpdateForTesting(); - - // A simple repaint change that causes Layer::DrawsContent to change still - // needs to cause a full update because it can affect whether mask layers are - // created. - auto* target = GetElementById("target"); - target->setAttribute(html_names::kStyleAttr, "background: rgba(0,0,0,0.5)"); - Compositor().BeginFrame(); - EXPECT_EQ(paint_artifact_compositor()->PreviousUpdateForTesting(), - PaintArtifactCompositor::PreviousUpdateType::kFull); - EXPECT_TRUE(CcLayerByDOMElementId("target")->DrawsContent()); -} - TEST_P(CompositingSimTest, ContentsOpaqueForTextWithSubpixelSizeSimpleBg) { InitializeWithHTML(R"HTML( <!DOCTYPE html>
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc index fb76348..d91905e4 100644 --- a/third_party/blink/renderer/core/paint/frame_painter.cc +++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -21,11 +21,11 @@ namespace { -FloatQuad GetQuadForTraceEvent(const LocalFrameView& frame_view, - const CullRect& cull_rect) { - FloatQuad quad(gfx::RectF(cull_rect.Rect())); +gfx::QuadF GetQuadForTraceEvent(const LocalFrameView& frame_view, + const CullRect& cull_rect) { + gfx::QuadF quad(gfx::RectF(cull_rect.Rect())); if (auto* owner = frame_view.GetFrame().OwnerLayoutObject()) { - quad.Move(gfx::Vector2dF(owner->PhysicalContentBoxOffset())); + quad += gfx::Vector2dF(owner->PhysicalContentBoxOffset()); owner->LocalToAbsoluteQuad( quad, kTraverseDocumentBoundaries | kUseGeometryMapperMode); }
diff --git a/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc b/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc index 3dd78d05..64e882e 100644 --- a/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc +++ b/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc
@@ -56,7 +56,7 @@ return accumulated_transform_.Inverse().ProjectPoint(last_planar_point_); } -FloatQuad HitTestingTransformState::MappedQuad() const { +gfx::QuadF HitTestingTransformState::MappedQuad() const { return accumulated_transform_.Inverse().ProjectQuad(last_planar_quad_); }
diff --git a/third_party/blink/renderer/core/paint/hit_testing_transform_state.h b/third_party/blink/renderer/core/paint/hit_testing_transform_state.h index e975630f..444d42b 100644 --- a/third_party/blink/renderer/core/paint/hit_testing_transform_state.h +++ b/third_party/blink/renderer/core/paint/hit_testing_transform_state.h
@@ -27,11 +27,11 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_HIT_TESTING_TRANSFORM_STATE_H_ #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -42,8 +42,8 @@ public: HitTestingTransformState(const gfx::PointF& p, - const FloatQuad& quad, - const FloatQuad& area) + const gfx::QuadF& quad, + const gfx::QuadF& area) : last_planar_point_(p), last_planar_quad_(quad), last_planar_area_(area) {} @@ -56,7 +56,7 @@ void ApplyTransform(const TransformPaintPropertyNode&); gfx::PointF MappedPoint() const; - FloatQuad MappedQuad() const; + gfx::QuadF MappedQuad() const; PhysicalRect BoundsOfMappedQuad() const; PhysicalRect BoundsOfMappedArea() const; void Flatten(); @@ -66,8 +66,8 @@ private: gfx::PointF last_planar_point_; - FloatQuad last_planar_quad_; - FloatQuad last_planar_area_; + gfx::QuadF last_planar_quad_; + gfx::QuadF last_planar_area_; TransformationMatrix accumulated_transform_; };
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index e723f05..0bbe0f8 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -2047,7 +2047,7 @@ if (text_item.Type() == NGFragmentItem::kSvgText && text_item.HasSvgTransformForBoundingBox()) { - const FloatQuad quad = text_item.SvgUnscaledQuad(); + const gfx::QuadF quad = text_item.SvgUnscaledQuad(); if (!hit_test.location.Intersects(quad)) return false; return hit_test.AddNodeToResultWithContentOffset(
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h index e6d9087..ae6b922 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -206,7 +206,7 @@ // Add |node| to |HitTestResult|. Returns true if the hit-testing should // stop. - // T is PhysicalRect or FloatQuad. + // T is PhysicalRect or gfx::QuadF. template <typename T> bool AddNodeToResult(Node* node, const NGPhysicalBoxFragment* box_fragment, @@ -215,7 +215,7 @@ // Same as |AddNodeToResult|, except that |offset| is in the content // coordinate system rather than the container coordinate system. They // differ when |container| is a scroll container. - // T is PhysicalRect or FloatQuad. + // T is PhysicalRect or gfx::QuadF. template <typename T> bool AddNodeToResultWithContentOffset( Node* node,
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index c4dfcee..c53fc1b 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -369,29 +369,24 @@ *transform, box->Size(), ComputedStyle::kIncludeTransformOrigin, ComputedStyle::kIncludeMotionPath, ComputedStyle::kIncludeIndependentTransformProperties); - MakeMatrixRenderable( - *transform, - box->GetDocument().GetSettings()->GetAcceleratedCompositingEnabled()); + if (!box->GetDocument().GetSettings()->GetAcceleratedCompositingEnabled()) + transform->MakeAffine(); } } void PaintLayer::UpdateTransform(const ComputedStyle* old_style, const ComputedStyle& new_style) { // It's possible for the old and new style transform data to be equivalent - // while hasTransform() differs, as it checks a number of conditions aside + // while HasTransform() differs, as it checks a number of conditions aside // from just the matrix, including but not limited to animation state. - if (old_style && old_style->HasTransform() == new_style.HasTransform() && + bool had_transform = Transform(); + bool has_transform = GetLayoutObject().HasTransform(); + if (had_transform == has_transform && old_style && new_style.TransformDataEquivalent(*old_style)) { return; } + bool had_3d_transform = Has3DTransform(); - // LayoutObject::HasTransformRelatedProperty is also true when there is - // transform-style: preserve-3d or perspective set, so check style too. - bool has_transform = GetLayoutObject().HasTransformRelatedProperty() && - new_style.HasTransform(); - bool had3d_transform = Has3DTransform(); - - bool had_transform = Transform(); if (has_transform != had_transform) { if (has_transform) EnsureRareData().transform = std::make_unique<TransformationMatrix>(); @@ -401,7 +396,7 @@ UpdateTransformationMatrix(); - if (had3d_transform != Has3DTransform()) + if (had_3d_transform != Has3DTransform()) MarkAncestorChainForFlagsUpdate(); if (LocalFrameView* frame_view = GetLayoutObject().GetDocument().View()) @@ -414,21 +409,6 @@ return TransformationMatrix(); } -TransformationMatrix PaintLayer::RenderableTransform( - GlobalPaintFlags global_paint_flags) const { - TransformationMatrix* transform = Transform(); - if (!transform) - return TransformationMatrix(); - - if (global_paint_flags & kGlobalPaintFlattenCompositingLayers) { - TransformationMatrix matrix = *transform; - MakeMatrixRenderable(matrix, false /* flatten 3d */); - return matrix; - } - - return *transform; -} - void PaintLayer::ConvertFromFlowThreadToVisualBoundingBoxInAncestor( const PaintLayer* ancestor_layer, PhysicalRect& rect) const { @@ -1465,7 +1445,7 @@ : HitTestingTransformState( recursion_data.location.TransformedPoint(), recursion_data.location.TransformedRect(), - FloatQuad(gfx::RectF(recursion_data.rect))); + gfx::QuadF(gfx::RectF(recursion_data.rect))); if (container_transform_state && (!transform_container.Preserves3D() || @@ -2357,11 +2337,6 @@ return result; } -bool PaintLayer::PaintsWithTransform( - GlobalPaintFlags global_paint_flags) const { - return Transform(); -} - bool PaintLayer::SupportsSubsequenceCaching() const { if (EnclosingPaginationLayer()) return false;
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h index 085c5d5..17672e9 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.h +++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -410,16 +410,10 @@ return rare_data_ ? rare_data_->transform.get() : nullptr; } - // currentTransform computes a transform which takes accelerated animations - // into account. The resulting transform has transform-origin baked in. If the - // layer does not have a transform, returns the identity matrix. + // Returns *Transform(), or identity matrix if Transform() is nullptr. TransformationMatrix CurrentTransform() const; - TransformationMatrix RenderableTransform(GlobalPaintFlags) const; - bool Preserves3D() const { - return GetLayoutObject().IsBox() && - GetLayoutObject().StyleRef().Preserves3D(); - } + bool Preserves3D() const { return GetLayoutObject().Preserves3D(); } bool Has3DTransform() const { return rare_data_ && rare_data_->transform && !rare_data_->transform->IsAffine(); @@ -431,8 +425,6 @@ return GetLayoutObject().HasFilterInducingProperty(); } - bool PaintsWithTransform(GlobalPaintFlags) const; - bool SupportsSubsequenceCaching() const; // If the input CompositorFilterOperation is not empty, it will be populated
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 3ee97e8..5bbedabb 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -111,10 +111,8 @@ properties->Transform()->HasActiveTransformAnimation()) { paint_non_invertible_transforms = true; } - if (!paint_non_invertible_transforms && - paint_layer_.PaintsWithTransform(painting_info.GetGlobalPaintFlags()) && - !paint_layer_.RenderableTransform(painting_info.GetGlobalPaintFlags()) - .IsInvertible()) { + if (!paint_non_invertible_transforms && paint_layer_.Transform() && + !paint_layer_.Transform()->IsInvertible()) { return kFullyPainted; } @@ -229,7 +227,7 @@ // change. // For these reasons, we use an infinite dirty rect here. // The reasons don't apply for CullRectUpdater. - if (!for_cull_rect_update && paint_layer_.PaintsWithTransform(global_flags) && + if (!for_cull_rect_update && paint_layer_.Transform() && // The reasons don't apply for printing though, because when we enter and // leaving printing mode, full invalidations occur. !is_printing)
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 6e902b1b..66fba60 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1173,8 +1173,8 @@ scroll_anchor_.RestoreAnchor(serialized_anchor); } -FloatQuad PaintLayerScrollableArea::LocalToVisibleContentQuad( - const FloatQuad& quad, +gfx::QuadF PaintLayerScrollableArea::LocalToVisibleContentQuad( + const gfx::QuadF& quad, const LayoutObject* local_object, MapCoordinatesFlags flags) const { LayoutBox* box = GetLayoutBox();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index b00decec..754df1b 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -484,9 +484,9 @@ LayoutBox* GetLayoutBox() const override; - FloatQuad LocalToVisibleContentQuad(const FloatQuad&, - const LayoutObject*, - unsigned = 0) const final; + gfx::QuadF LocalToVisibleContentQuad(const gfx::QuadF&, + const LayoutObject*, + unsigned = 0) const final; scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 4227337..c649bca 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -1866,7 +1866,7 @@ const ComputedStyle* old_style = target_object->Style(); scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(*old_style); new_style->SetHasCurrentTransformAnimation(true); - target_paint_layer->UpdateTransform(old_style, *new_style); + target_object->SetStyle(std::move(new_style)); EXPECT_NE(nullptr, target_paint_layer->Transform()); }
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 9757d048..75c25697 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -433,14 +433,13 @@ if (!object.IsBoxModelObject()) return false; - // <foreignObject> inherits no paint offset, because there is no such - // concept within SVG. However, the foreign object can have its own paint - // offset due to the x and y parameters of the element. This affects the - // offset of painting of the <foreignObject> element and its children. - // However, <foreignObject> otherwise behaves like other SVG elements, in - // that the x and y offset is applied *after* any transform, instead of - // before. Therefore there is no paint offset translation needed. - if (object.IsSVGForeignObject()) + // An SVG children inherits no paint offset, because there is no such concept + // within SVG. Though <foreignObject> can have its own paint offset due to the + // x and y parameters of the element, which affects the offset of painting of + // the <foreignObject> element and its children, it still behaves like other + // SVG elements, in that the x and y offset is applied *after* any transform, + // instead of before. + if (object.IsSVGChild()) return false; const auto& box_model = To<LayoutBoxModelObject>(object); @@ -456,10 +455,8 @@ return true; } - if (box_model.HasLayer() && box_model.Layer()->PaintsWithTransform( - kGlobalPaintFlattenCompositingLayers)) { + if (box_model.HasTransform()) return true; - } if (NeedsScrollOrScrollTranslation(object, direct_compositing_reasons)) return true; if (NeedsStickyTranslation(object)) @@ -874,12 +871,12 @@ } } -static gfx::Point3F TransformOrigin(const ComputedStyle& style, - PhysicalSize size) { +static gfx::Point3F TransformOrigin(const LayoutBox& box, PhysicalSize size) { // Transform origin has no effect without a transform or motion path. - if (!style.HasTransform()) + if (!box.HasTransform()) return gfx::Point3F(); gfx::SizeF border_box_size(size); + const auto& style = box.StyleRef(); return gfx::Point3F( FloatValueForLength(style.TransformOriginX(), border_box_size.width()), FloatValueForLength(style.TransformOriginY(), border_box_size.height()), @@ -897,10 +894,7 @@ if (direct_compositing_reasons & CompositingReasonsForTransformProperty()) return true; - if (!object.IsBox()) - return false; - - if (object.StyleRef().HasTransform() || object.StyleRef().Preserves3D()) + if (object.HasTransform() || object.Preserves3D()) return true; return false; @@ -965,8 +959,7 @@ matrix.IsIdentityOr2DTranslation()) { state.transform_and_origin = {matrix.To2DTranslation()}; } else { - state.transform_and_origin = {matrix, - TransformOrigin(box.StyleRef(), size)}; + state.transform_and_origin = {matrix, TransformOrigin(box, size)}; } // We want to track whether (a) this element is in a preserve-3d scene @@ -1812,6 +1805,18 @@ // LayoutObjects under custom scrollbars don't support paint properties. } +static void AdjustRoundedClipForOverflowClipMargin( + const LayoutBox& box, + gfx::RectF& layout_clip_rect, + FloatRoundedRect& paint_clip_rect) { + const auto& style = box.StyleRef(); + LayoutUnit overflow_clip_margin = style.OverflowClipMargin(); + if (!overflow_clip_margin || !box.ShouldApplyOverflowClipMargin()) + return; + layout_clip_rect.Outset(overflow_clip_margin.ToFloat()); + paint_clip_rect.InflateAndReshape(overflow_clip_margin.ToFloat()); +} + void FragmentPaintPropertyTreeBuilder::UpdateInnerBorderRadiusClip() { DCHECK(properties_); @@ -1819,12 +1824,16 @@ if (NeedsInnerBorderRadiusClip(object_)) { const auto& box = To<LayoutBox>(object_); PhysicalRect box_rect(context_.current.paint_offset, box.Size()); - ClipPaintPropertyNode::State state( - context_.current.transform, + gfx::RectF layout_clip_rect = RoundedBorderGeometry::RoundedInnerBorder(box.StyleRef(), box_rect) - .Rect(), + .Rect(); + FloatRoundedRect paint_clip_rect = RoundedBorderGeometry::PixelSnappedRoundedInnerBorder(box.StyleRef(), - box_rect)); + box_rect); + AdjustRoundedClipForOverflowClipMargin(box, layout_clip_rect, + paint_clip_rect); + ClipPaintPropertyNode::State state(context_.current.transform, + layout_clip_rect, paint_clip_rect); OnUpdateClip(properties_->UpdateInnerBorderRadiusClip( *context_.current.clip, std::move(state))); } else { @@ -2162,10 +2171,10 @@ // If scroll and transform are both present, we should use the // transform property tree node to determine visibility of the // scrolling contents. - if (object_.StyleRef().HasTransform() && - object_.StyleRef().BackfaceVisibility() == - EBackfaceVisibility::kHidden) + if (object_.HasTransform() && object_.StyleRef().BackfaceVisibility() == + EBackfaceVisibility::kHidden) { state.flags.delegates_to_parent_for_backface = true; + } auto effective_change_type = properties_->UpdateScrollTranslation( *context_.current.transform, std::move(state)); // Even if effective_change_type is kUnchanged, we might still need to @@ -2655,7 +2664,7 @@ // transform-origin, and perspective-origin can depend on the size of the // frame rect, so force a property update if it changes. TODO(pdr): We // only need to update properties if there are relative lengths. - box.StyleRef().HasTransform() || NeedsPerspective(box) || + box.HasTransform() || NeedsPerspective(box) || box_generates_property_nodes_for_mask_and_clip_path) { box.GetMutableForPainting().SetNeedsPaintPropertyUpdate(); }
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index a73ce26..d1fc2b6 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -5700,9 +5700,20 @@ TEST_P(PaintPropertyTreeBuilderTest, UpdateUnderChangedEffectUnderCompositedLayer) { SetBodyInnerHTML(R"HTML( - <div id="opacity" style="isolation: isolate; width: 100px: height: 100px"> - <div id="target" - style="will-change: transform; width: 100px: height: 100px"> + <style> + #opacity { + isolation: isolate; + width: 100px; + height: 100px; + } + #target { + will-change: transform; + width: 100px; + height: 100px; + } + </style> + <div id="opacity"> + <div id="target"> </div> </div> )HTML");
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index 6f6bf96..e622249 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -393,9 +393,7 @@ fragment_id = 0; if (pre_paint_info.is_first_for_node) { - if (allow_update) - fragment_data->ClearNextFragment(); - else + if (!allow_update) DCHECK_EQ(fragment_data->FragmentID(), fragment_id); } else { FragmentData* last_fragment = nullptr; @@ -406,14 +404,7 @@ fragment_data = fragment_data->NextFragment(); } while (fragment_data); if (fragment_data) { - if (pre_paint_info.is_last_for_node) { - // We have reached the end. There may be more data entries that were - // needed in the previous layout, but not any more. Clear them. - if (allow_update) - fragment_data->ClearNextFragment(); - else - DCHECK(!fragment_data->NextFragment()); - } else if (fragment_data->FragmentID() != fragment_id) { + if (fragment_data->FragmentID() != fragment_id) { // There are entries for fragmentainers after this one, but none for // this one. Remove the fragment tail. DCHECK(allow_update); @@ -433,6 +424,15 @@ } } + if (pre_paint_info.is_last_for_node) { + // We have reached the end. There may be more data entries that were + // needed in the previous layout, but not any more. Clear them. + if (allow_update) + fragment_data->ClearNextFragment(); + else + DCHECK(!fragment_data->NextFragment()); + } + if (allow_update) { fragment_data->SetFragmentID(fragment_id); @@ -637,6 +637,16 @@ absl::optional<wtf_size_t> inner_fragmentainer_idx; context.current_fragmentainer.fragmentation_nesting_level++; + PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext* + containing_block_context = nullptr; + PhysicalOffset previous_oof_offset; + if (LIKELY(context.tree_builder_context)) { + containing_block_context = + &context.tree_builder_context->fragments[0].current; + + previous_oof_offset = + containing_block_context->paint_offset_for_oof_in_fragmentainer; + } for (NGLink child : fragment.Children()) { const auto* box_fragment = To<NGPhysicalBoxFragment>(child.fragment); @@ -656,8 +666,17 @@ // spanner. This is fixable, but it would require non-trivial amounts of // special-code for such a special case. If anyone complains, we can // revisit this decision. - if (box_fragment->IsColumnSpanAll()) + if (box_fragment->IsColumnSpanAll()) { context.current_fragmentainer = outer_fragmentainer; + // When an OOF has a spanner CB (or a CB inside a spanner) it will get + // laid out in the next outer fragmentainer (if there is one). Thus, + // any such OOF descendants should be adjusted by offset of the outer + // fragmentainer rather than the innermost fragmentainer. + if (containing_block_context) { + containing_block_context->paint_offset_for_oof_in_fragmentainer = + previous_oof_offset; + } + } NGPrePaintInfo pre_paint_info = CreatePrePaintInfo(child, context); Walk(*box_fragment->GetLayoutObject(), context, &pre_paint_info); @@ -682,11 +701,7 @@ inner_fragmentainer_idx = PreviousInnerFragmentainerIndex(fragment); context.current_fragmentainer.fragmentainer_idx = *inner_fragmentainer_idx; - PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext* - containing_block_context = nullptr; - if (LIKELY(context.tree_builder_context)) { - containing_block_context = - &context.tree_builder_context->fragments[0].current; + if (containing_block_context) { containing_block_context->paint_offset += child.offset; const PhysicalOffset paint_offset = @@ -1118,7 +1133,7 @@ PrePaintTreeWalkContext context(parent_context, needs_tree_builder_context_update); - if (object.StyleRef().HasTransform()) { + if (object.HasTransform()) { // Ignore clip changes from ancestor across transform boundaries. context.clip_changed = false; if (context.tree_builder_context)
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index a0da795a..d5c26700 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" +#include "ui/gfx/geometry/skia_conversions.h" using testing::ElementsAre; @@ -65,20 +66,21 @@ // This is the dest_rect_ calculated by BackgroundImageGeometry. For a fixed // background in scrolling contents layer, its location is the scroll offset. - SkRect rect = static_cast<const cc::DrawRectOp*>(*it)->rect; + auto rect = gfx::SkRectToRectF(static_cast<const cc::DrawRectOp*>(*it)->rect); if (prefer_compositing_to_lcd_text) { - EXPECT_EQ(SkRect::MakeXYWH(0, 0, 800, 600), rect); + EXPECT_EQ(gfx::RectF(0, 0, 800, 600), rect); } else { - EXPECT_EQ(SkRect::MakeXYWH(scroll_offset.x(), scroll_offset.y(), 800, 600), - rect); + EXPECT_EQ(gfx::RectF(scroll_offset.x(), scroll_offset.y(), 800, 600), rect); } } -TEST_P(ViewPainterFixedBackgroundTest, DocumentFixedBackgroundLowDPI) { +TEST_P(ViewPainterFixedBackgroundTest, + DocumentFixedBackgroundNotPreferCompositing) { RunFixedBackgroundTest(false); } -TEST_P(ViewPainterFixedBackgroundTest, DocumentFixedBackgroundHighDPI) { +TEST_P(ViewPainterFixedBackgroundTest, + DocumentFixedBackgroundPreferCompositing) { RunFixedBackgroundTest(true); }
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc index 73f6068..d9bd9fe 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -895,12 +895,10 @@ return 0; } -FloatQuad ScrollableArea::LocalToVisibleContentQuad(const FloatQuad& quad, - const LayoutObject*, - unsigned) const { - FloatQuad result(quad); - result.Move(-GetScrollOffset()); - return result; +gfx::QuadF ScrollableArea::LocalToVisibleContentQuad(const gfx::QuadF& quad, + const LayoutObject*, + unsigned) const { + return quad - GetScrollOffset(); } gfx::Size ScrollableArea::ExcludeScrollbars(const gfx::Size& size) const {
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h index b48984f..e39c4f94 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.h +++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -35,7 +35,6 @@ #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" #include "third_party/blink/renderer/core/loader/history_item.h" #include "third_party/blink/renderer/core/scroll/scrollbar.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h" #include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h" @@ -45,6 +44,7 @@ #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "ui/gfx/geometry/quad_f.h" namespace base { class SingleThreadTaskRunner; @@ -491,9 +491,9 @@ // ScrollableArea to the coordinate system of the ScrollableArea's visible // content rect. If the LayoutObject* argument is null, the argument quad is // considered to be in the coordinate space of the overflow rect. - virtual FloatQuad LocalToVisibleContentQuad(const FloatQuad&, - const LayoutObject*, - unsigned = 0) const; + virtual gfx::QuadF LocalToVisibleContentQuad(const gfx::QuadF&, + const LayoutObject*, + unsigned = 0) const; virtual bool IsPaintLayerScrollableArea() const { return false; } virtual bool IsRootFrameViewport() const { return false; }
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.cc b/third_party/blink/renderer/core/scroll/scrollbar.cc index fb4c43a..78e92a3e 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -408,7 +408,7 @@ // says we injected GestureScrollBegin, since we no longer need to inject // a GSE ourselves. injected_gesture_scroll_begin_ = false; - FALLTHROUGH; + [[fallthrough]]; case WebInputEvent::Type::kGestureLongPress: case WebInputEvent::Type::kGestureFlingStart: scroll_pos_ = 0;
diff --git a/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc b/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc index c278076..246b074 100644 --- a/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc +++ b/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc
@@ -19,19 +19,20 @@ static const V8PrivateProperty::SymbolKey kByteLengthQueuingStrategySizeFunction; -class ByteLengthQueuingStrategySizeFunction final : public ScriptFunction { +class ByteLengthQueuingStrategySizeFunction final + : public NewScriptFunction::Callable { public: static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - ByteLengthQueuingStrategySizeFunction* self = - MakeGarbageCollected<ByteLengthQueuingStrategySizeFunction>( - script_state); + auto* self = MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<ByteLengthQueuingStrategySizeFunction>()); // https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function // 2. Let F be ! CreateBuiltinFunction(steps, « », globalObject’s relevant // Realm). // 4. Perform ! SetFunctionLength(F, 1). - v8::Local<v8::Function> function = self->BindToV8Function(/*length=*/1); + v8::Local<v8::Function> function = self->V8Function(); // 3. Perform ! SetFunctionName(F, "size"). function->SetName(V8String(script_state->GetIsolate(), "size")); @@ -39,14 +40,13 @@ return function; } - explicit ByteLengthQueuingStrategySizeFunction(ScriptState* script_state) - : ScriptFunction(script_state) {} + ByteLengthQueuingStrategySizeFunction() = default; - private: - void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) override { + void CallRaw(ScriptState* script_state, + const v8::FunctionCallbackInfo<v8::Value>& args) override { auto* isolate = args.GetIsolate(); - DCHECK_EQ(isolate, GetScriptState()->GetIsolate()); - auto context = GetScriptState()->GetContext(); + DCHECK_EQ(isolate, script_state->GetIsolate()); + auto context = script_state->GetContext(); v8::Local<v8::Value> chunk; if (args.Length() < 1) { chunk = v8::Undefined(isolate); @@ -77,6 +77,8 @@ } args.GetReturnValue().Set(byte_length); } + + int Length() const override { return 1; } }; } // namespace
diff --git a/third_party/blink/renderer/core/streams/count_queuing_strategy.cc b/third_party/blink/renderer/core/streams/count_queuing_strategy.cc index 98ca424..247d5be3 100644 --- a/third_party/blink/renderer/core/streams/count_queuing_strategy.cc +++ b/third_party/blink/renderer/core/streams/count_queuing_strategy.cc
@@ -18,17 +18,18 @@ static const V8PrivateProperty::SymbolKey kCountQueuingStrategySizeFunction; -class CountQueuingStrategySizeFunction final : public ScriptFunction { +class CountQueuingStrategySizeFunction final + : public NewScriptFunction::Callable { public: static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - CountQueuingStrategySizeFunction* self = - MakeGarbageCollected<CountQueuingStrategySizeFunction>(script_state); + auto* self = MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<CountQueuingStrategySizeFunction>()); // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function // 2. Let F be ! CreateBuiltinFunction(steps, « », globalObject’s relevant // Realm). // 4. Perform ! SetFunctionLength(F, 0). - v8::Local<v8::Function> function = self->BindToV8Function(/*length=*/0); + v8::Local<v8::Function> function = self->V8Function(); // 3. Perform ! SetFunctionName(F, "size"). function->SetName(V8String(script_state->GetIsolate(), "size")); @@ -36,16 +37,14 @@ return function; } - explicit CountQueuingStrategySizeFunction(ScriptState* script_state) - : ScriptFunction(script_state) {} + CountQueuingStrategySizeFunction() = default; - private: - void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) override { + void CallRaw(ScriptState* script_state, + const v8::FunctionCallbackInfo<v8::Value>& args) override { // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function // 1. Let steps be the following steps: // 1. Return 1. - args.GetReturnValue().Set( - v8::Integer::New(GetScriptState()->GetIsolate(), 1)); + args.GetReturnValue().Set(v8::Integer::New(script_state->GetIsolate(), 1)); } };
diff --git a/third_party/blink/renderer/core/streams/promise_handler.cc b/third_party/blink/renderer/core/streams/promise_handler.cc index f21b6ba..0078ad7 100644 --- a/third_party/blink/renderer/core/streams/promise_handler.cc +++ b/third_party/blink/renderer/core/streams/promise_handler.cc
@@ -35,28 +35,28 @@ } // namespace -PromiseHandler::PromiseHandler(ScriptState* script_state) - : PromiseHandlerBase(script_state) {} +PromiseHandler::PromiseHandler() = default; -void PromiseHandler::CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) { +void PromiseHandler::CallRaw(ScriptState* script_state, + const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK_EQ(args.Length(), 1); - CallWithLocal(args[0]); + CallWithLocal(script_state, args[0]); } -PromiseHandlerWithValue::PromiseHandlerWithValue(ScriptState* script_state) - : PromiseHandlerBase(script_state) {} +PromiseHandlerWithValue::PromiseHandlerWithValue() = default; void PromiseHandlerWithValue::CallRaw( + ScriptState* script_state, const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK_EQ(args.Length(), 1); - auto ret = CallWithLocal(args[0]); + auto ret = CallWithLocal(script_state, args[0]); args.GetReturnValue().Set(ret); } v8::Local<v8::Promise> StreamThenPromise(v8::Local<v8::Context> context, v8::Local<v8::Promise> promise, - PromiseHandlerBase* on_fulfilled, - PromiseHandlerBase* on_rejected) { + NewScriptFunction* on_fulfilled, + NewScriptFunction* on_rejected) { v8::MaybeLocal<v8::Promise> result_maybe; if (!on_fulfilled) { DCHECK(on_rejected); @@ -71,13 +71,12 @@ << "by shutdown and ignoring it"; return AttemptToReturnDummyPromise(context, promise); } - result_maybe = - promise->Then(context, noop, on_rejected->BindToV8Function()); + result_maybe = promise->Then(context, noop, on_rejected->V8Function()); } else if (on_rejected) { - result_maybe = promise->Then(context, on_fulfilled->BindToV8Function(), - on_rejected->BindToV8Function()); + result_maybe = promise->Then(context, on_fulfilled->V8Function(), + on_rejected->V8Function()); } else { - result_maybe = promise->Then(context, on_fulfilled->BindToV8Function()); + result_maybe = promise->Then(context, on_fulfilled->V8Function()); } v8::Local<v8::Promise> result;
diff --git a/third_party/blink/renderer/core/streams/promise_handler.h b/third_party/blink/renderer/core/streams/promise_handler.h index 733f17a..ce8d713 100644 --- a/third_party/blink/renderer/core/streams/promise_handler.h +++ b/third_party/blink/renderer/core/streams/promise_handler.h
@@ -11,39 +11,28 @@ namespace blink { -// Common subclass for PromiseHandlers. -class CORE_EXPORT PromiseHandlerBase : public ScriptFunction { - public: - explicit PromiseHandlerBase(ScriptState* script_state) - : ScriptFunction(script_state) {} - - // Exposed for use by StreamThenPromise. - using ScriptFunction::BindToV8Function; -}; - // A variant of ScriptFunction that avoids the conversion to and from a // ScriptValue. Use this when the reaction doesn't need to return a value other // than undefined. -class CORE_EXPORT PromiseHandler : public PromiseHandlerBase { +class CORE_EXPORT PromiseHandler : public NewScriptFunction::Callable { public: - explicit PromiseHandler(ScriptState* script_state); + PromiseHandler(); - virtual void CallWithLocal(v8::Local<v8::Value>) = 0; + virtual void CallWithLocal(ScriptState*, v8::Local<v8::Value>) = 0; - private: - void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&) final; + void CallRaw(ScriptState*, const v8::FunctionCallbackInfo<v8::Value>&) final; }; // A variant of PromiseHandler for when the reaction does need to return a // value. -class CORE_EXPORT PromiseHandlerWithValue : public PromiseHandlerBase { +class CORE_EXPORT PromiseHandlerWithValue : public NewScriptFunction::Callable { public: - explicit PromiseHandlerWithValue(ScriptState* script_state); + PromiseHandlerWithValue(); - virtual v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value>) = 0; + virtual v8::Local<v8::Value> CallWithLocal(ScriptState*, + v8::Local<v8::Value>) = 0; - private: - void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&) final; + void CallRaw(ScriptState*, const v8::FunctionCallbackInfo<v8::Value>&) final; }; // A convenience wrapper for promise->Then() for when all paths are @@ -53,8 +42,8 @@ v8::Local<v8::Promise> StreamThenPromise( v8::Local<v8::Context>, v8::Local<v8::Promise>, - PromiseHandlerBase* on_fulfilled, - PromiseHandlerBase* on_rejected = nullptr); + NewScriptFunction* on_fulfilled, + NewScriptFunction* on_rejected = nullptr); } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc index 94961a4..e6261af 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
@@ -467,11 +467,11 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, - ReadableByteStreamController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit ResolveFunction(ReadableByteStreamController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 7. Upon fulfillment of pullPromise, // a. Set controller.[[pulling]] to false. controller_->pulling_ = false; @@ -481,7 +481,7 @@ controller_->pull_again_ = false; // ii. Perform ! // ReadableByteStreamControllerCallPullIfNeeded(controller). - CallPullIfNeeded(GetScriptState(), controller_); + CallPullIfNeeded(script_state, controller_); } } @@ -496,14 +496,14 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, - ReadableByteStreamController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit RejectFunction(ReadableByteStreamController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value> e) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> e) override { // 8. Upon rejection of pullPromise with reason e, // a. Perform ! ReadableByteStreamControllerError(controller, e). - Error(GetScriptState(), controller_, e); + Error(script_state, controller_, e); } void Trace(Visitor* visitor) const override { @@ -517,8 +517,10 @@ StreamThenPromise( script_state->GetContext(), pull_promise, - MakeGarbageCollected<ResolveFunction>(script_state, controller), - MakeGarbageCollected<RejectFunction>(script_state, controller)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(controller)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(controller))); } ReadableByteStreamController::PullIntoDescriptor* @@ -738,11 +740,11 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, - ReadableByteStreamController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit ResolveFunction(ReadableByteStreamController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 16. Upon fulfillment of startPromise, // a. Set controller.[[started]] to true. controller_->started_ = true; @@ -752,7 +754,7 @@ DCHECK(!controller_->pull_again_); // d. Perform ! // ReadableByteStreamControllerCallPullIfNeeded(controller). - CallPullIfNeeded(GetScriptState(), controller_); + CallPullIfNeeded(script_state, controller_); } void Trace(Visitor* visitor) const override { @@ -766,14 +768,14 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, - ReadableByteStreamController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit RejectFunction(ReadableByteStreamController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value> r) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // 17. Upon rejection of startPromise with reason r, // a. Perform ! ReadableByteStreamControllerError(controller, r). - Error(GetScriptState(), controller_, r); + Error(script_state, controller_, r); } void Trace(Visitor* visitor) const override { @@ -787,8 +789,10 @@ StreamThenPromise( script_state->GetContext(), start_promise, - MakeGarbageCollected<ResolveFunction>(script_state, controller), - MakeGarbageCollected<RejectFunction>(script_state, controller)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(controller)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(controller))); } void ReadableByteStreamController::SetUpFromUnderlyingSource(
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index 177442f..4f17221 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -241,20 +241,17 @@ class WrappedPromiseReaction final : public PromiseHandlerWithValue { public: - WrappedPromiseReaction(ScriptState* script_state, - PipeToEngine* instance, - PromiseReaction method) - : PromiseHandlerWithValue(script_state), - instance_(instance), - method_(method) {} + WrappedPromiseReaction(PipeToEngine* instance, PromiseReaction method) + : instance_(instance), method_(method) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value> value) override { + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> value) override { return (instance_->*method_)(value); } void Trace(Visitor* visitor) const override { visitor->Trace(instance_); - ScriptFunction::Trace(visitor); + PromiseHandlerWithValue::Trace(visitor); } private: @@ -710,12 +707,16 @@ PromiseReaction on_rejected = nullptr) { return StreamThenPromise( script_state_->GetContext(), promise, - on_fulfilled ? MakeGarbageCollected<WrappedPromiseReaction>( - script_state_, this, on_fulfilled) - : nullptr, - on_rejected ? MakeGarbageCollected<WrappedPromiseReaction>( - script_state_, this, on_rejected) - : nullptr); + on_fulfilled + ? MakeGarbageCollected<NewScriptFunction>( + script_state_, MakeGarbageCollected<WrappedPromiseReaction>( + this, on_fulfilled)) + : nullptr, + on_rejected + ? MakeGarbageCollected<NewScriptFunction>( + script_state_, MakeGarbageCollected<WrappedPromiseReaction>( + this, on_rejected)) + : nullptr); } Member<ScriptState> script_state_; @@ -790,7 +791,8 @@ script_state->GetContext(), ReadableStreamDefaultReader::Read(script_state, engine_->reader_) ->V8Promise(script_state->GetIsolate()), - MakeGarbageCollected<ResolveFunction>(script_state, engine_)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(engine_))); } void Trace(Visitor* visitor) const override { @@ -801,10 +803,10 @@ private: class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, TeeEngine* engine) - : PromiseHandler(script_state), engine_(engine) {} + explicit ResolveFunction(TeeEngine* engine) : engine_(engine) {} - void CallWithLocal(v8::Local<v8::Value> result) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> result) override { // i. If closed is true, return. if (engine_->closed_) { return; @@ -813,7 +815,6 @@ // ii. Assert: Type(result) is Object. DCHECK(result->IsObject()); - auto* script_state = GetScriptState(); auto* isolate = script_state->GetIsolate(); // iii. Let done be ! Get(result, "done"). @@ -1049,25 +1050,25 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, TeeEngine* engine) - : PromiseHandler(script_state), engine_(engine) {} + explicit RejectFunction(TeeEngine* engine) : engine_(engine) {} - void CallWithLocal(v8::Local<v8::Value> r) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // 18. Upon rejection of reader.[[closedPromise]] with reason r, // a. Perform ! ReadableStreamDefaultControllerError(branch1. // [[readableStreamController]], r). - ReadableStreamDefaultController::Error(GetScriptState(), + ReadableStreamDefaultController::Error(script_state, engine_->controller_[0], r); // b. Perform ! ReadableStreamDefaultControllerError(branch2. // [[readableStreamController]], r). - ReadableStreamDefaultController::Error(GetScriptState(), + ReadableStreamDefaultController::Error(script_state, engine_->controller_[1], r); // TODO(ricea): Implement https://github.com/whatwg/streams/pull/1045 so // this step can be numbered correctly. // Resolve |cancelPromise| with undefined. - engine_->cancel_promise_->ResolveWithUndefined(GetScriptState()); + engine_->cancel_promise_->ResolveWithUndefined(script_state); } void Trace(Visitor* visitor) const override { @@ -1083,7 +1084,8 @@ StreamThenPromise( script_state->GetContext(), reader_->closed_promise_->V8Promise(script_state->GetIsolate()), nullptr, - MakeGarbageCollected<RejectFunction>(script_state, this)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(this))); // Step "19. Return « branch1, branch2 »." // is performed by the caller. @@ -1778,19 +1780,20 @@ class ReturnUndefinedFunction final : public PromiseHandler { public: - explicit ReturnUndefinedFunction(ScriptState* script_state) - : PromiseHandler(script_state) {} + ReturnUndefinedFunction() = default; // The method does nothing; the default value of undefined is returned to // JavaScript. - void CallWithLocal(v8::Local<v8::Value>) override {} + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override {} }; // 8. Return the result of transforming sourceCancelPromise with a // fulfillment handler that returns undefined. return StreamThenPromise( script_state->GetContext(), source_cancel_promise, - MakeGarbageCollected<ReturnUndefinedFunction>(script_state)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ReturnUndefinedFunction>())); } void ReadableStream::Close(ScriptState* script_state, ReadableStream* stream) {
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc index 50ac14d..057f1d77 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
@@ -373,11 +373,11 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, - ReadableStreamDefaultController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit ResolveFunction(ReadableStreamDefaultController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 7. Upon fulfillment of pullPromise, // a. Set controller.[[pulling]] to false. controller_->is_pulling_ = false; @@ -389,7 +389,7 @@ // ii. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded( // controller). - CallPullIfNeeded(GetScriptState(), controller_); + CallPullIfNeeded(script_state, controller_); } } @@ -404,14 +404,14 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, - ReadableStreamDefaultController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit RejectFunction(ReadableStreamDefaultController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value> e) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> e) override { // 8. Upon rejection of pullPromise with reason e, // a. Perform ! ReadableStreamDefaultControllerError(controller, e). - Error(GetScriptState(), controller_, e); + Error(script_state, controller_, e); } void Trace(Visitor* visitor) const override { @@ -425,8 +425,11 @@ StreamThenPromise( script_state->GetContext(), pull_promise, - MakeGarbageCollected<ResolveFunction>(script_state, controller), - MakeGarbageCollected<RejectFunction>(script_state, controller)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(controller)), + + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(controller))); } bool ReadableStreamDefaultController::ShouldCallPull( @@ -536,11 +539,11 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, - ReadableStreamDefaultController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit ResolveFunction(ReadableStreamDefaultController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 11. Upon fulfillment of startPromise, // a. Set controller.[[started]] to true. controller_->is_started_ = true; @@ -553,7 +556,7 @@ // d. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded( // controller). - CallPullIfNeeded(GetScriptState(), controller_); + CallPullIfNeeded(script_state, controller_); } void Trace(Visitor* visitor) const override { @@ -567,14 +570,14 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, - ReadableStreamDefaultController* controller) - : PromiseHandler(script_state), controller_(controller) {} + explicit RejectFunction(ReadableStreamDefaultController* controller) + : controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value> r) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // 12. Upon rejection of startPromise with reason r, // a. Perform ! ReadableStreamDefaultControllerError(controller, r). - Error(GetScriptState(), controller_, r); + Error(script_state, controller_, r); } void Trace(Visitor* visitor) const override { @@ -588,8 +591,11 @@ StreamThenPromise( script_state->GetContext(), start_promise, - MakeGarbageCollected<ResolveFunction>(script_state, controller), - MakeGarbageCollected<RejectFunction>(script_state, controller)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(controller)), + + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(controller))); } void ReadableStreamDefaultController::SetUpFromUnderlyingSource(
diff --git a/third_party/blink/renderer/core/streams/readable_stream_test.cc b/third_party/blink/renderer/core/streams/readable_stream_test.cc index 1442ce8a..18e5acd 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_test.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_test.cc
@@ -36,7 +36,7 @@ // Web platform tests test ReadableStream more thoroughly from scripts. class ReadableStreamTest : public testing::Test { public: - ReadableStreamTest() {} + ReadableStreamTest() = default; absl::optional<String> ReadAll(V8TestingScope& scope, ReadableStream* stream) { @@ -552,7 +552,7 @@ TEST_F(ReadableStreamTest, GarbageCollectCPlusPlusUnderlyingSource) { class NoopUnderlyingSource : public UnderlyingSourceBase { public: - NoopUnderlyingSource(ScriptState* script_state) + explicit NoopUnderlyingSource(ScriptState* script_state) : UnderlyingSourceBase(script_state) {} };
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc index 94a4aadf..8dc3abaa 100644 --- a/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc +++ b/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
@@ -94,36 +94,32 @@ // runMicrotasks(); // } // } - class ThenGetter final : public ScriptFunction { + class ThenGetter final : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> Create(ScriptState* script_state, - StreamPromiseResolver* promise) { - return MakeGarbageCollected<ThenGetter>(script_state, promise) - ->BindToV8Function(); - } - - ThenGetter(ScriptState* script_state, StreamPromiseResolver* promise) - : ScriptFunction(script_state), promise_(promise) {} + explicit ThenGetter(StreamPromiseResolver* promise) : promise_(promise) {} void Trace(Visitor* visitor) const override { visitor->Trace(promise_); - ScriptFunction::Trace(visitor); + NewScriptFunction::Callable::Trace(visitor); } - private: - void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&) override { - auto* isolate = GetScriptState()->GetIsolate(); + void CallRaw(ScriptState* script_state, + const v8::FunctionCallbackInfo<v8::Value>&) override { + auto* isolate = script_state->GetIsolate(); EXPECT_TRUE(promise_->IsSettled()); - promise_->Resolve(GetScriptState(), v8::Undefined(isolate)); + promise_->Resolve(script_state, v8::Undefined(isolate)); v8::MicrotasksScope::PerformCheckpoint(isolate); } + private: Member<StreamPromiseResolver> promise_; }; auto value = v8::Object::New(isolate); v8::PropertyDescriptor property_descriptor( - ThenGetter::Create(scope.GetScriptState(), promise), + MakeGarbageCollected<NewScriptFunction>( + scope.GetScriptState(), MakeGarbageCollected<ThenGetter>(promise)) + ->V8Function(), v8::Undefined(isolate)); const auto then = V8String(isolate, "then"); value->DefineProperty(scope.GetContext(), then, property_descriptor).Check();
diff --git a/third_party/blink/renderer/core/streams/transferable_streams.cc b/third_party/blink/renderer/core/streams/transferable_streams.cc index 456b7329..3ea17b8f 100644 --- a/third_party/blink/renderer/core/streams/transferable_streams.cc +++ b/third_party/blink/renderer/core/streams/transferable_streams.cc
@@ -405,7 +405,9 @@ return StreamThenPromise( script_state->GetContext(), writable_->backpressure_promise_->V8Promise(isolate), - MakeGarbageCollected<DoWriteOnResolve>(script_state, chunk, this)); + MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<DoWriteOnResolve>(script_state, chunk, this))); } void Trace(Visitor* visitor) const override { @@ -420,12 +422,10 @@ DoWriteOnResolve(ScriptState* script_state, v8::Local<v8::Value> chunk, WriteAlgorithm* target) - : PromiseHandlerWithValue(script_state), - chunk_(script_state->GetIsolate(), chunk), - target_(target) {} + : chunk_(script_state->GetIsolate(), chunk), target_(target) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value>) override { - ScriptState* script_state = GetScriptState(); + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { return target_->DoWrite(script_state, chunk_.Get(script_state->GetIsolate())); }
diff --git a/third_party/blink/renderer/core/streams/transferable_streams_test.cc b/third_party/blink/renderer/core/streams/transferable_streams_test.cc index 5c5813d..42374f3 100644 --- a/third_party/blink/renderer/core/streams/transferable_streams_test.cc +++ b/third_party/blink/renderer/core/streams/transferable_streams_test.cc
@@ -176,27 +176,18 @@ writer->write(script_state, ScriptValue::CreateNull(scope.GetIsolate()), ASSERT_NO_EXCEPTION); - class ExpectNullResponse : public ScriptFunction { + class ExpectNullResponse : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> Create(ScriptState* script_state, - bool* got_response) { - auto* self = - MakeGarbageCollected<ExpectNullResponse>(script_state, got_response); - return self->BindToV8Function(); - } + explicit ExpectNullResponse(bool* got_response) + : got_response_(got_response) {} - ExpectNullResponse(ScriptState* script_state, bool* got_response) - : ScriptFunction(script_state), got_response_(got_response) {} - - private: - ScriptValue Call(ScriptValue value) override { + ScriptValue Call(ScriptState* script_state, ScriptValue value) override { *got_response_ = true; if (!value.IsObject()) { ADD_FAILURE() << "iterator must be an object"; return ScriptValue(); } bool done = false; - auto* script_state = GetScriptState(); auto chunk_maybe = V8UnpackIteratorResult(script_state, value.V8Value() @@ -218,18 +209,11 @@ // TODO(ricea): This is copy-and-pasted from transform_stream_test.cc. Put it // in a shared location. - class ExpectNotReached : public ScriptFunction { + class ExpectNotReached : public NewScriptFunction::Callable { public: - static v8::Local<v8::Function> Create(ScriptState* script_state) { - auto* self = MakeGarbageCollected<ExpectNotReached>(script_state); - return self->BindToV8Function(); - } + ExpectNotReached() = default; - explicit ExpectNotReached(ScriptState* script_state) - : ScriptFunction(script_state) {} - - private: - ScriptValue Call(ScriptValue) override { + ScriptValue Call(ScriptState*, ScriptValue) override { ADD_FAILURE() << "ExpectNotReached was reached"; return ScriptValue(); } @@ -237,8 +221,13 @@ bool got_response = false; reader->read(script_state, ASSERT_NO_EXCEPTION) - .Then(ExpectNullResponse::Create(script_state, &got_response), - ExpectNotReached::Create(script_state)); + .Then(MakeGarbageCollected<NewScriptFunction>( + script_state, + MakeGarbageCollected<ExpectNullResponse>(&got_response)) + ->V8Function(), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ExpectNotReached>()) + ->V8Function()); // Need to run the event loop to pass messages through the MessagePort. test::RunPendingTasks();
diff --git a/third_party/blink/renderer/core/streams/transform_stream.cc b/third_party/blink/renderer/core/streams/transform_stream.cc index 910fe5c..216484ae 100644 --- a/third_party/blink/renderer/core/streams/transform_stream.cc +++ b/third_party/blink/renderer/core/streams/transform_stream.cc
@@ -338,12 +338,10 @@ ResponseFunction(ScriptState* script_state, TransformStream* stream, v8::Local<v8::Value> chunk) - : PromiseHandlerWithValue(script_state), - stream_(stream), - chunk_(script_state->GetIsolate(), chunk) {} + : stream_(stream), chunk_(script_state->GetIsolate(), chunk) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value>) override { - auto* script_state = GetScriptState(); + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { auto* isolate = script_state->GetIsolate(); // c. Return the result of transforming backpressureChangePromise with @@ -371,7 +369,7 @@ void Trace(Visitor* visitor) const override { visitor->Trace(stream_); visitor->Trace(chunk_); - ScriptFunction::Trace(visitor); + PromiseHandlerWithValue::Trace(visitor); } private: @@ -383,7 +381,9 @@ return StreamThenPromise( script_state->GetContext(), backpressure_change_promise->V8Promise(script_state->GetIsolate()), - MakeGarbageCollected<ResponseFunction>(script_state, stream_, chunk)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResponseFunction>( + script_state, stream_, chunk))); } // 4. Return ! TransformStreamDefaultControllerPerformTransform(controller, @@ -457,19 +457,18 @@ class ResolveFunction final : public PromiseHandlerWithValue { public: - ResolveFunction(ScriptState* script_state, TransformStream* stream) - : PromiseHandlerWithValue(script_state), stream_(stream) {} + explicit ResolveFunction(TransformStream* stream) : stream_(stream) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value>) override { + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 5. Return the result of transforming flushPromise with: // a. A fulfillment handler that performs the following steps: // i. If readable.[[state]] is "errored", throw // readable.[[storedError]]. if (ReadableStream::IsErrored(stream_->readable_)) { // Returning a rejection is equivalent to throwing here. - return PromiseReject(GetScriptState(), - stream_->readable_->GetStoredError( - GetScriptState()->GetIsolate())); + return PromiseReject(script_state, stream_->readable_->GetStoredError( + script_state->GetIsolate())); } // ii. Let readableController be @@ -481,11 +480,11 @@ // ReadableStreamDefaultControllerClose(readableController). if (ReadableStreamDefaultController::CanCloseOrEnqueue( readable_controller)) { - ReadableStreamDefaultController::Close(GetScriptState(), + ReadableStreamDefaultController::Close(script_state, readable_controller); } - return v8::Undefined(GetScriptState()->GetIsolate()); + return v8::Undefined(script_state->GetIsolate()); } void Trace(Visitor* visitor) const override { @@ -499,19 +498,18 @@ class RejectFunction final : public PromiseHandlerWithValue { public: - RejectFunction(ScriptState* script_state, TransformStream* stream) - : PromiseHandlerWithValue(script_state), stream_(stream) {} + explicit RejectFunction(TransformStream* stream) : stream_(stream) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value> r) override { + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // b. A rejection handler that, when called with argument r, performs // the following steps: // i. Perform ! TransformStreamError(stream, r). - Error(GetScriptState(), stream_, r); + Error(script_state, stream_, r); // ii. Throw readable.[[storedError]]. - return PromiseReject( - GetScriptState(), - stream_->readable_->GetStoredError(GetScriptState()->GetIsolate())); + return PromiseReject(script_state, stream_->readable_->GetStoredError( + script_state->GetIsolate())); } void Trace(Visitor* visitor) const override { @@ -526,8 +524,10 @@ // 5. Return the result of transforming flushPromise ... return StreamThenPromise( script_state->GetContext(), flush_promise, - MakeGarbageCollected<ResolveFunction>(script_state, stream_), - MakeGarbageCollected<RejectFunction>(script_state, stream_)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(stream_)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(stream_))); } void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc b/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc index 00f66e9..b0f44ec 100644 --- a/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc +++ b/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
@@ -329,19 +329,19 @@ class RejectFunction final : public PromiseHandlerWithValue { public: - RejectFunction(ScriptState* script_state, TransformStream* stream) - : PromiseHandlerWithValue(script_state), stream_(stream) {} + explicit RejectFunction(TransformStream* stream) : stream_(stream) {} - v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value> r) override { + v8::Local<v8::Value> CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // 2. Return the result of transforming transformPromise with a rejection // handler that, when called with argument r, performs the following // steps: // a. Perform ! TransformStreamError(controller. // [[controlledTransformStream]], r). - TransformStream::Error(GetScriptState(), stream_, r); + TransformStream::Error(script_state, stream_, r); // b. Throw r. - return PromiseReject(GetScriptState(), r); + return PromiseReject(script_state, r); } void Trace(Visitor* visitor) const override { @@ -356,8 +356,9 @@ // 2. Return the result of transforming transformPromise ... return StreamThenPromise( script_state->GetContext(), transform_promise, nullptr, - MakeGarbageCollected<RejectFunction>( - script_state, controller->controlled_transform_stream_)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>( + controller->controlled_transform_stream_))); } void TransformStreamDefaultController::Terminate(
diff --git a/third_party/blink/renderer/core/streams/transform_stream_test.cc b/third_party/blink/renderer/core/streams/transform_stream_test.cc index e9cf394c..0f89efb 100644 --- a/third_party/blink/renderer/core/streams/transform_stream_test.cc +++ b/third_party/blink/renderer/core/streams/transform_stream_test.cc
@@ -40,7 +40,7 @@ class TransformStreamTest : public ::testing::Test { public: - TransformStreamTest() {} + TransformStreamTest() = default; TransformStream* Stream() const { return stream_; }
diff --git a/third_party/blink/renderer/core/streams/writable_stream.cc b/third_party/blink/renderer/core/streams/writable_stream.cc index c5a00cd..5231f7e4 100644 --- a/third_party/blink/renderer/core/streams/writable_stream.cc +++ b/third_party/blink/renderer/core/streams/writable_stream.cc
@@ -588,19 +588,19 @@ class ResolvePromiseFunction final : public PromiseHandler { public: - ResolvePromiseFunction(ScriptState* script_state, - WritableStream* stream, + ResolvePromiseFunction(WritableStream* stream, StreamPromiseResolver* promise) - : PromiseHandler(script_state), stream_(stream), promise_(promise) {} + : stream_(stream), promise_(promise) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 13. Upon fulfillment of promise, // a. Resolve abortRequest.[[promise]] with undefined. - promise_->ResolveWithUndefined(GetScriptState()); + promise_->ResolveWithUndefined(script_state); // b. Perform ! // WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream). - RejectCloseAndClosedPromiseIfNeeded(GetScriptState(), stream_); + RejectCloseAndClosedPromiseIfNeeded(script_state, stream_); } void Trace(Visitor* visitor) const override { @@ -616,19 +616,19 @@ class RejectPromiseFunction final : public PromiseHandler { public: - RejectPromiseFunction(ScriptState* script_state, - WritableStream* stream, + RejectPromiseFunction(WritableStream* stream, StreamPromiseResolver* promise) - : PromiseHandler(script_state), stream_(stream), promise_(promise) {} + : stream_(stream), promise_(promise) {} - void CallWithLocal(v8::Local<v8::Value> reason) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> reason) override { // 14. Upon rejection of promise with reason reason, // a. Reject abortRequest.[[promise]] with reason. - promise_->Reject(GetScriptState(), reason); + promise_->Reject(script_state, reason); // b. Perform ! // WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream). - RejectCloseAndClosedPromiseIfNeeded(GetScriptState(), stream_); + RejectCloseAndClosedPromiseIfNeeded(script_state, stream_); } void Trace(Visitor* visitor) const override { @@ -642,11 +642,14 @@ Member<StreamPromiseResolver> promise_; }; - StreamThenPromise(script_state->GetContext(), promise, - MakeGarbageCollected<ResolvePromiseFunction>( - script_state, stream, abort_request->GetPromise()), - MakeGarbageCollected<RejectPromiseFunction>( - script_state, stream, abort_request->GetPromise())); + StreamThenPromise( + script_state->GetContext(), promise, + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolvePromiseFunction>( + stream, abort_request->GetPromise())), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectPromiseFunction>( + stream, abort_request->GetPromise()))); } void WritableStream::FinishInFlightWrite(ScriptState* script_state,
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc index 8e5ab40..d20fb97 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc +++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
@@ -154,10 +154,10 @@ class ResolvePromiseFunction final : public PromiseHandler { public: - ResolvePromiseFunction(ScriptState* script_state, WritableStream* stream) - : PromiseHandler(script_state), stream_(stream) {} + explicit ResolvePromiseFunction(WritableStream* stream) : stream_(stream) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 17. Upon fulfillment of startPromise // a. Assert: stream.[[state]] is "writable" or "erroring". const auto state = stream_->GetState(); @@ -170,7 +170,7 @@ // c. Perform ! WritableStreamDefaultControllerAdvanceQueueIfNeeded( // controller). - WritableStreamDefaultController::AdvanceQueueIfNeeded(GetScriptState(), + WritableStreamDefaultController::AdvanceQueueIfNeeded(script_state, controller); } @@ -185,10 +185,10 @@ class RejectPromiseFunction final : public PromiseHandler { public: - RejectPromiseFunction(ScriptState* script_state, WritableStream* stream) - : PromiseHandler(script_state), stream_(stream) {} + explicit RejectPromiseFunction(WritableStream* stream) : stream_(stream) {} - void CallWithLocal(v8::Local<v8::Value> r) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> r) override { // 18. Upon rejection of startPromise with reason r, // a. Assert: stream.[[state]] is "writable" or "erroring". const auto state = stream_->GetState(); @@ -200,7 +200,7 @@ controller->started_ = true; // c. Perform ! WritableStreamDealWithRejection(stream, r). - WritableStream::DealWithRejection(GetScriptState(), stream_, r); + WritableStream::DealWithRejection(script_state, stream_, r); } void Trace(Visitor* visitor) const override { @@ -214,8 +214,10 @@ StreamThenPromise( script_state->GetContext(), start_promise, - MakeGarbageCollected<ResolvePromiseFunction>(script_state, stream), - MakeGarbageCollected<RejectPromiseFunction>(script_state, stream)); + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolvePromiseFunction>(stream)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectPromiseFunction>(stream))); } // TODO(ricea): Should this be a constructor? @@ -513,13 +515,13 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, WritableStream* stream) - : PromiseHandler(script_state), stream_(stream) {} + explicit ResolveFunction(WritableStream* stream) : stream_(stream) {} - void CallWithLocal(v8::Local<v8::Value>) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 7. Upon fulfillment of sinkClosePromise, // a. Perform ! WritableStreamFinishInFlightClose(stream). - WritableStream::FinishInFlightClose(GetScriptState(), stream_); + WritableStream::FinishInFlightClose(script_state, stream_); } void Trace(Visitor* visitor) const override { @@ -533,14 +535,14 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, WritableStream* stream) - : PromiseHandler(script_state), stream_(stream) {} + explicit RejectFunction(WritableStream* stream) : stream_(stream) {} - void CallWithLocal(v8::Local<v8::Value> reason) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> reason) override { // 8. Upon rejection of sinkClosePromise with reason reason, // a. Perform ! WritableStreamFinishInFlightCloseWithError(stream, // reason). - WritableStream::FinishInFlightCloseWithError(GetScriptState(), stream_, + WritableStream::FinishInFlightCloseWithError(script_state, stream_, reason); } @@ -553,9 +555,12 @@ Member<WritableStream> stream_; }; - StreamThenPromise(script_state->GetContext(), sinkClosePromise, - MakeGarbageCollected<ResolveFunction>(script_state, stream), - MakeGarbageCollected<RejectFunction>(script_state, stream)); + StreamThenPromise( + script_state->GetContext(), sinkClosePromise, + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>(stream)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>(stream))); } void WritableStreamDefaultController::ProcessWrite( @@ -576,15 +581,12 @@ class ResolveFunction final : public PromiseHandler { public: - ResolveFunction(ScriptState* script_state, - WritableStream* stream, + ResolveFunction(WritableStream* stream, WritableStreamDefaultController* controller) - : PromiseHandler(script_state), - stream_(stream), - controller_(controller) {} + : stream_(stream), controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value>) override { - auto* script_state = GetScriptState(); + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value>) override { // 4. Upon fulfillment of sinkWritePromise, // a. Perform ! WritableStreamFinishInFlightWrite(stream). WritableStream::FinishInFlightWrite(script_state, stream_); @@ -632,14 +634,12 @@ class RejectFunction final : public PromiseHandler { public: - RejectFunction(ScriptState* script_state, - WritableStream* stream, + RejectFunction(WritableStream* stream, WritableStreamDefaultController* controller) - : PromiseHandler(script_state), - stream_(stream), - controller_(controller) {} + : stream_(stream), controller_(controller) {} - void CallWithLocal(v8::Local<v8::Value> reason) override { + void CallWithLocal(ScriptState* script_state, + v8::Local<v8::Value> reason) override { const auto state = stream_->GetState(); // 5. Upon rejection of sinkWritePromise with reason, // a. If stream.[[state]] is "writable", perform ! @@ -650,7 +650,7 @@ // b. Perform ! WritableStreamFinishInFlightWriteWithError(stream, // reason). - WritableStream::FinishInFlightWriteWithError(GetScriptState(), stream_, + WritableStream::FinishInFlightWriteWithError(script_state, stream_, reason); } @@ -665,10 +665,13 @@ Member<WritableStreamDefaultController> controller_; }; - StreamThenPromise( - script_state->GetContext(), sinkWritePromise, - MakeGarbageCollected<ResolveFunction>(script_state, stream, controller), - MakeGarbageCollected<RejectFunction>(script_state, stream, controller)); + StreamThenPromise(script_state->GetContext(), sinkWritePromise, + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<ResolveFunction>( + stream, controller)), + MakeGarbageCollected<NewScriptFunction>( + script_state, MakeGarbageCollected<RejectFunction>( + stream, controller))); } bool WritableStreamDefaultController::GetBackpressure(
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni index 69fc284..32db6cd 100644 --- a/third_party/blink/renderer/core/style/build.gni +++ b/third_party/blink/renderer/core/style/build.gni
@@ -24,7 +24,6 @@ "counter_directives.h", "cursor_data.h", "cursor_list.h", - "data_equivalency.h", "data_ref.h", "fill_layer.cc", "fill_layer.h",
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 084a4c2..dddfb36 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -28,6 +28,7 @@ #include <utility> #include "base/cxx17_backports.h" +#include "base/memory/values_equivalent.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/clamped_math.h" #include "build/build_config.h" @@ -57,7 +58,6 @@ #include "third_party/blink/renderer/core/style/computed_style_initial_values.h" #include "third_party/blink/renderer/core/style/content_data.h" #include "third_party/blink/renderer/core/style/cursor_data.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style/quotes_data.h" #include "third_party/blink/renderer/core/style/shadow_list.h" #include "third_party/blink/renderer/core/style/style_difference.h" @@ -979,12 +979,12 @@ return true; for (const AtomicString& property_name : properties) { - if (!DataEquivalent(GetVariableData(property_name), - other.GetVariableData(property_name))) { + if (!base::ValuesEquivalent(GetVariableData(property_name), + other.GetVariableData(property_name))) { return false; } - if (!DataEquivalent(GetVariableValue(property_name), - other.GetVariableValue(property_name))) { + if (!base::ValuesEquivalent(GetVariableValue(property_name), + other.GetVariableValue(property_name))) { return false; } } @@ -1113,7 +1113,7 @@ } bool ComputedStyle::QuotesDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(Quotes(), other.Quotes()); + return base::ValuesEquivalent(Quotes(), other.Quotes()); } void ComputedStyle::ClearCursorList() { @@ -1428,7 +1428,7 @@ } bool ComputedStyle::TextShadowDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(TextShadow(), other.TextShadow()); + return base::ValuesEquivalent(TextShadow(), other.TextShadow()); } StyleImage* ComputedStyle::ListStyleImage() const { @@ -2633,6 +2633,11 @@ Display() == EDisplay::kTableCaption); } +bool ComputedStyle::IsContainerForContainerQueries( + const Element& element) const { + return IsContainerForContainerQueries() && !element.ShouldForceLegacyLayout(); +} + STATIC_ASSERT_ENUM(cc::OverscrollBehavior::Type::kAuto, EOverscrollBehavior::kAuto); STATIC_ASSERT_ENUM(cc::OverscrollBehavior::Type::kContain,
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index a56450d..91ac3241 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -30,6 +30,7 @@ #include <memory> #include "base/gtest_prod_util.h" +#include "base/memory/values_equivalent.h" #include "base/types/pass_key.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_property_names.h" @@ -517,7 +518,8 @@ MutableBackdropFilterInternal()->operations_ = ops; } bool BackdropFilterDataEquivalent(const ComputedStyle& o) const { - return DataEquivalent(BackdropFilterInternal(), o.BackdropFilterInternal()); + return base::ValuesEquivalent(BackdropFilterInternal(), + o.BackdropFilterInternal()); } // filter (aka -webkit-filter) @@ -541,7 +543,7 @@ MutableFilterInternal()->operations_ = v; } bool FilterDataEquivalent(const ComputedStyle& o) const { - return DataEquivalent(FilterInternal(), o.FilterInternal()); + return base::ValuesEquivalent(FilterInternal(), o.FilterInternal()); } @@ -632,7 +634,7 @@ // box-shadow (aka -webkit-box-shadow) bool BoxShadowDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(BoxShadow(), other.BoxShadow()); + return base::ValuesEquivalent(BoxShadow(), other.BoxShadow()); } // clip-path @@ -921,7 +923,7 @@ // shape-outside (aka -webkit-shape-outside) ShapeValue* ShapeOutside() const { return ShapeOutsideInternal().Get(); } bool ShapeOutsideDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(ShapeOutside(), other.ShapeOutside()); + return base::ValuesEquivalent(ShapeOutside(), other.ShapeOutside()); } // touch-action @@ -961,7 +963,7 @@ // -webkit-clip-path bool ClipPathDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(ClipPath(), other.ClipPath()); + return base::ValuesEquivalent(ClipPath(), other.ClipPath()); } // Mask properties. @@ -1016,7 +1018,7 @@ // list-style-type const AtomicString& ListStyleStringValue() const; bool ListStyleTypeDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(ListStyleType(), other.ListStyleType()); + return base::ValuesEquivalent(ListStyleType(), other.ListStyleType()); } // quotes @@ -1190,8 +1192,8 @@ bool CounterDirectivesEqual(const ComputedStyle& other) const { // If the counter directives change, trigger a relayout to re-calculate // counter values and rebuild the counter node tree. - return DataEquivalent(CounterDirectivesInternal().get(), - other.CounterDirectivesInternal().get()); + return base::ValuesEquivalent(CounterDirectivesInternal().get(), + other.CounterDirectivesInternal().get()); } void ClearIncrementDirectives(); void ClearResetDirectives(); @@ -1292,7 +1294,7 @@ } bool HasBoxReflect() const { return BoxReflect(); } bool ReflectionDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(BoxReflect(), other.BoxReflect()); + return base::ValuesEquivalent(BoxReflect(), other.BoxReflect()); } float ResolvedFlexGrow(const ComputedStyle& box_style) const { if (box_style.IsDeprecatedWebkitBox()) @@ -2079,7 +2081,7 @@ // Content utility functions. bool ContentDataEquivalent(const ComputedStyle& other) const { - return DataEquivalent(GetContentData(), other.GetContentData()); + return base::ValuesEquivalent(GetContentData(), other.GetContentData()); } // Contain utility functions. @@ -2119,6 +2121,11 @@ } CORE_EXPORT bool ShouldApplyAnyContainment(const Element& element) const; + // Utility method which checks if legacy layout is forced for the element in + // addition to checking IsContainerForContainerQueries(). Query containers are + // not established in legacy layout. + bool IsContainerForContainerQueries(const Element& element) const; + bool IsContainerForContainerQueries() const { return IsInlineOrBlockSizeContainer() && StyleType() == kPseudoIdNone && !InsideFragmentationContextWithNondeterministicEngine(); @@ -2496,6 +2503,9 @@ return HasTransform() || Preserves3D() || HasPerspective() || HasWillChangeTransformHint(); } + bool HasTransformRelatedPropertyForSVG() const { + return HasTransform() || HasWillChangeTransformHint(); + } // Return true if this style has properties ('filter', 'clip-path' and 'mask') // that applies an effect to SVG elements.
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index 5e2b15f6d..8807fe2 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" +#include "base/memory/values_equivalent.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_font_selector.h" @@ -316,7 +317,7 @@ auto* other_image_value = MakeGarbageCollected<StyleGeneratedImage>(*gradient); - EXPECT_TRUE(DataEquivalent(image_value, other_image_value)); + EXPECT_TRUE(base::ValuesEquivalent(image_value, other_image_value)); style->AddCursor(image_value, false); other->AddCursor(other_image_value, false);
diff --git a/third_party/blink/renderer/core/style/cursor_data.h b/third_party/blink/renderer/core/style/cursor_data.h index 51df7fd7..35cda9b 100644 --- a/third_party/blink/renderer/core/style/cursor_data.h +++ b/third_party/blink/renderer/core/style/cursor_data.h
@@ -25,7 +25,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CURSOR_DATA_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CURSOR_DATA_H_ -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/style/style_image.h" #include "ui/gfx/geometry/point.h" @@ -43,7 +43,7 @@ hot_spot_(hot_spot) {} bool operator==(const CursorData& o) const { - return hot_spot_ == o.hot_spot_ && DataEquivalent(image_, o.image_); + return hot_spot_ == o.hot_spot_ && base::ValuesEquivalent(image_, o.image_); } bool operator!=(const CursorData& o) const { return !(*this == o); }
diff --git a/third_party/blink/renderer/core/style/data_equivalency.h b/third_party/blink/renderer/core/style/data_equivalency.h deleted file mode 100644 index 7313542..0000000 --- a/third_party/blink/renderer/core/style/data_equivalency.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_DATA_EQUIVALENCY_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_DATA_EQUIVALENCY_H_ - -#include <memory> -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/platform/heap/member.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -template <typename T> -bool DataEquivalent(const T* a, const T* b) { - if (a == b) - return true; - if (!a || !b) - return false; - return *a == *b; -} - -template <typename T> -bool DataEquivalent(const scoped_refptr<T>& a, const scoped_refptr<T>& b) { - return DataEquivalent(a.get(), b.get()); -} - -template <typename T> -bool DataEquivalent(const Persistent<T>& a, const Persistent<T>& b) { - return DataEquivalent(a.Get(), b.Get()); -} - -template <typename T> -bool DataEquivalent(const Member<T>& a, const Member<T>& b) { - return DataEquivalent(a.Get(), b.Get()); -} - -template <typename T> -bool DataEquivalent(const std::unique_ptr<T>& a, const std::unique_ptr<T>& b) { - return DataEquivalent(a.get(), b.get()); -} - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_DATA_EQUIVALENCY_H_
diff --git a/third_party/blink/renderer/core/style/fill_layer.cc b/third_party/blink/renderer/core/style/fill_layer.cc index b3f9df5a..6155b23 100644 --- a/third_party/blink/renderer/core/style/fill_layer.cc +++ b/third_party/blink/renderer/core/style/fill_layer.cc
@@ -21,9 +21,9 @@ #include "third_party/blink/renderer/core/style/fill_layer.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/css/css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style/style_generated_image.h" #include "third_party/blink/renderer/platform/wtf/size_assertions.h" @@ -171,8 +171,8 @@ } bool FillLayer::LayerPropertiesEqual(const FillLayer& o) const { - return DataEquivalent(image_, o.image_) && position_x_ == o.position_x_ && - position_y_ == o.position_y_ && + return base::ValuesEquivalent(image_, o.image_) && + position_x_ == o.position_x_ && position_y_ == o.position_y_ && background_x_origin_ == o.background_x_origin_ && background_y_origin_ == o.background_y_origin_ && attachment_ == o.attachment_ && clip_ == o.clip_ &&
diff --git a/third_party/blink/renderer/core/style/nine_piece_image.cc b/third_party/blink/renderer/core/style/nine_piece_image.cc index 4e5fdbe..0b5f2d6 100644 --- a/third_party/blink/renderer/core/style/nine_piece_image.cc +++ b/third_party/blink/renderer/core/style/nine_piece_image.cc
@@ -24,7 +24,7 @@ #include "third_party/blink/renderer/core/style/nine_piece_image.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" namespace blink { @@ -67,7 +67,7 @@ outset(0, 0, 0, 0) {} bool NinePieceImageData::operator==(const NinePieceImageData& other) const { - return DataEquivalent(image, other.image) && + return base::ValuesEquivalent(image, other.image) && image_slices == other.image_slices && fill == other.fill && border_slices == other.border_slices && outset == other.outset && horizontal_rule == other.horizontal_rule &&
diff --git a/third_party/blink/renderer/core/style/shape_value.h b/third_party/blink/renderer/core/style/shape_value.h index 259978a..c4a0ad3 100644 --- a/third_party/blink/renderer/core/style/shape_value.h +++ b/third_party/blink/renderer/core/style/shape_value.h
@@ -31,10 +31,12 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_SHAPE_VALUE_H_ #include "base/memory/scoped_refptr.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/style/basic_shapes.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style/style_image.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" namespace blink { @@ -83,12 +85,12 @@ switch (GetType()) { case kShape: - return DataEquivalent(Shape(), other.Shape()) && + return base::ValuesEquivalent(Shape(), other.Shape()) && CssBox() == other.CssBox(); case kBox: return CssBox() == other.CssBox(); case kImage: - return DataEquivalent(GetImage(), other.GetImage()); + return base::ValuesEquivalent(GetImage(), other.GetImage()); } NOTREACHED();
diff --git a/third_party/blink/renderer/core/style/style_highlight_data.cc b/third_party/blink/renderer/core/style/style_highlight_data.cc index 218557a34..0fa870a 100644 --- a/third_party/blink/renderer/core/style/style_highlight_data.cc +++ b/third_party/blink/renderer/core/style/style_highlight_data.cc
@@ -4,8 +4,8 @@ #include "third_party/blink/renderer/core/style/style_highlight_data.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" namespace blink { @@ -25,8 +25,8 @@ grammar_error_(other.grammar_error_), custom_highlights_(other.custom_highlights_) {} -// Compares two CustomHighlightsStyleMaps with DataEquivalent as comparison -// function on the values. +// Compares two CustomHighlightsStyleMaps with base::ValuesEquivalent as +// comparison function on the values. bool HighlightStyleMapEquals(const CustomHighlightsStyleMap& a, const CustomHighlightsStyleMap& b) { if (a.size() != b.size()) @@ -37,7 +37,7 @@ for (CustomHighlightsStyleMap::const_iterator it = a.begin(); it != a_end; ++it) { CustomHighlightsStyleMap::const_iterator b_pos = b.find(it->key); - if (b_pos == b_end || !DataEquivalent(it->value, b_pos->value)) + if (b_pos == b_end || !base::ValuesEquivalent(it->value, b_pos->value)) return false; } @@ -45,10 +45,10 @@ } bool StyleHighlightData::operator==(const StyleHighlightData& other) const { - return DataEquivalent(selection_, other.selection_) && - DataEquivalent(target_text_, other.target_text_) && - DataEquivalent(spelling_error_, other.spelling_error_) && - DataEquivalent(grammar_error_, other.grammar_error_) && + return base::ValuesEquivalent(selection_, other.selection_) && + base::ValuesEquivalent(target_text_, other.target_text_) && + base::ValuesEquivalent(spelling_error_, other.spelling_error_) && + base::ValuesEquivalent(grammar_error_, other.grammar_error_) && HighlightStyleMapEquals(custom_highlights_, other.custom_highlights_); }
diff --git a/third_party/blink/renderer/core/style/style_inherited_variables.cc b/third_party/blink/renderer/core/style/style_inherited_variables.cc index 806435e..fab0d22 100644 --- a/third_party/blink/renderer/core/style/style_inherited_variables.cc +++ b/third_party/blink/renderer/core/style/style_inherited_variables.cc
@@ -4,13 +4,14 @@ #include "third_party/blink/renderer/core/style/style_inherited_variables.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" namespace blink { bool StyleInheritedVariables::operator==( const StyleInheritedVariables& other) const { - return DataEquivalent(root_, other.root_) && variables_ == other.variables_; + return base::ValuesEquivalent(root_, other.root_) && + variables_ == other.variables_; } StyleInheritedVariables::StyleInheritedVariables() : root_(nullptr) {}
diff --git a/third_party/blink/renderer/core/style/style_initial_data.cc b/third_party/blink/renderer/core/style/style_initial_data.cc index ee6ece47..85534342 100644 --- a/third_party/blink/renderer/core/style/style_initial_data.cc +++ b/third_party/blink/renderer/core/style/style_initial_data.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/core/style/style_initial_data.h" #include "third_party/blink/renderer/core/css/property_registry.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" namespace blink {
diff --git a/third_party/blink/renderer/core/style/style_variables.cc b/third_party/blink/renderer/core/style/style_variables.cc index 87a6fc7..6a60210 100644 --- a/third_party/blink/renderer/core/style/style_variables.cc +++ b/third_party/blink/renderer/core/style/style_variables.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/style/style_variables.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" namespace blink { @@ -18,7 +18,7 @@ return false; if (!a.has_value()) return true; - return DataEquivalent(a.value(), b.value()); + return base::ValuesEquivalent(a.value(), b.value()); } bool IsEqual(const OptionalValue& a, const OptionalValue& b) { @@ -26,7 +26,7 @@ return false; if (!a.has_value()) return true; - return DataEquivalent(a.value(), b.value()); + return base::ValuesEquivalent(a.value(), b.value()); } } // namespace
diff --git a/third_party/blink/renderer/core/style/svg_paint.cc b/third_party/blink/renderer/core/style/svg_paint.cc index e8326c9..2075a59 100644 --- a/third_party/blink/renderer/core/style/svg_paint.cc +++ b/third_party/blink/renderer/core/style/svg_paint.cc
@@ -27,7 +27,7 @@ #include "third_party/blink/renderer/core/style/svg_paint.h" -#include "third_party/blink/renderer/core/style/data_equivalency.h" +#include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/style/style_svg_resource.h" namespace blink { @@ -42,7 +42,7 @@ bool SVGPaint::operator==(const SVGPaint& other) const { return type == other.type && color == other.color && - DataEquivalent(resource, other.resource); + base::ValuesEquivalent(resource, other.resource); } const AtomicString& SVGPaint::GetUrl() const {
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc index 110c43d..bd3fc31 100644 --- a/third_party/blink/renderer/core/svg/svg_element.cc +++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -306,7 +306,7 @@ bool SVGElement::HasTransform( ApplyMotionTransform apply_motion_transform) const { - return (GetLayoutObject() && GetLayoutObject()->StyleRef().HasTransform()) || + return (GetLayoutObject() && GetLayoutObject()->HasTransform()) || (apply_motion_transform == kIncludeMotionTransform && HasSVGRareData()); } @@ -316,7 +316,7 @@ const LayoutObject* layout_object = GetLayoutObject(); AffineTransform matrix; - if (layout_object && layout_object->StyleRef().HasTransform()) { + if (layout_object && layout_object->HasTransform()) { matrix = TransformHelper::ComputeTransform( *layout_object, ComputedStyle::kIncludeTransformOrigin); }
diff --git a/third_party/blink/renderer/core/svg/svg_path_blender.cc b/third_party/blink/renderer/core/svg/svg_path_blender.cc index cd4a8f9..77c18c0 100644 --- a/third_party/blink/renderer/core/svg/svg_path_blender.cc +++ b/third_party/blink/renderer/core/svg/svg_path_blender.cc
@@ -219,12 +219,12 @@ case kPathSegCurveToCubicAbs: blended_segment.point1 = BlendAnimatedPoint(from_seg.point1, to_seg.point1); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToCubicSmoothRel: case kPathSegCurveToCubicSmoothAbs: blended_segment.point2 = BlendAnimatedPoint(from_seg.point2, to_seg.point2); - FALLTHROUGH; + [[fallthrough]]; case kPathSegMoveToRel: case kPathSegMoveToAbs: case kPathSegLineToRel:
diff --git a/third_party/blink/renderer/core/svg/svg_path_byte_stream_source.cc b/third_party/blink/renderer/core/svg/svg_path_byte_stream_source.cc index acb078dc..94fb674 100644 --- a/third_party/blink/renderer/core/svg/svg_path_byte_stream_source.cc +++ b/third_party/blink/renderer/core/svg/svg_path_byte_stream_source.cc
@@ -32,11 +32,11 @@ case kPathSegCurveToCubicRel: case kPathSegCurveToCubicAbs: segment.point1 = ReadPoint(); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToCubicSmoothRel: case kPathSegCurveToCubicSmoothAbs: segment.point2 = ReadPoint(); - FALLTHROUGH; + [[fallthrough]]; case kPathSegMoveToRel: case kPathSegMoveToAbs: case kPathSegLineToRel:
diff --git a/third_party/blink/renderer/core/svg/svg_path_parser.cc b/third_party/blink/renderer/core/svg/svg_path_parser.cc index 5cc45954..e26f155f 100644 --- a/third_party/blink/renderer/core/svg/svg_path_parser.cc +++ b/third_party/blink/renderer/core/svg/svg_path_parser.cc
@@ -68,10 +68,10 @@ break; case kPathSegCurveToCubicRel: norm_seg.point1 += current_point_.OffsetFromOrigin(); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToCubicSmoothRel: norm_seg.point2 += current_point_.OffsetFromOrigin(); - FALLTHROUGH; + [[fallthrough]]; case kPathSegMoveToRel: case kPathSegLineToRel: case kPathSegLineToHorizontalRel: @@ -119,7 +119,7 @@ norm_seg.point1 = current_point_; else norm_seg.point1 = ReflectedPoint(current_point_, control_point_); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToCubicRel: case kPathSegCurveToCubicAbs: control_point_ = norm_seg.point2; @@ -131,7 +131,7 @@ norm_seg.point1 = current_point_; else norm_seg.point1 = ReflectedPoint(current_point_, control_point_); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToQuadraticRel: case kPathSegCurveToQuadraticAbs: // Save the unmodified control point.
diff --git a/third_party/blink/renderer/core/svg/svg_path_string_source.cc b/third_party/blink/renderer/core/svg/svg_path_string_source.cc index d36fafb..8898427 100644 --- a/third_party/blink/renderer/core/svg/svg_path_string_source.cc +++ b/third_party/blink/renderer/core/svg/svg_path_string_source.cc
@@ -197,12 +197,12 @@ case kPathSegCurveToCubicAbs: segment.point1.set_x(ParseNumberWithError()); segment.point1.set_y(ParseNumberWithError()); - FALLTHROUGH; + [[fallthrough]]; case kPathSegCurveToCubicSmoothRel: case kPathSegCurveToCubicSmoothAbs: segment.point2.set_x(ParseNumberWithError()); segment.point2.set_y(ParseNumberWithError()); - FALLTHROUGH; + [[fallthrough]]; case kPathSegMoveToRel: case kPathSegMoveToAbs: case kPathSegLineToRel:
diff --git a/third_party/blink/renderer/core/svg/svg_transform_distance.cc b/third_party/blink/renderer/core/svg/svg_transform_distance.cc index ddc11a4..4838fe4 100644 --- a/third_party/blink/renderer/core/svg/svg_transform_distance.cc +++ b/third_party/blink/renderer/core/svg/svg_transform_distance.cc
@@ -52,7 +52,7 @@ switch (transform_type_) { case SVGTransformType::kMatrix: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case SVGTransformType::kUnknown: break; case SVGTransformType::kRotate: { @@ -89,7 +89,7 @@ switch (transform_type_) { case SVGTransformType::kMatrix: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case SVGTransformType::kUnknown: return SVGTransformDistance(); case SVGTransformType::kRotate: @@ -127,7 +127,7 @@ switch (first->TransformType()) { case SVGTransformType::kMatrix: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case SVGTransformType::kUnknown: return transform; case SVGTransformType::kRotate: { @@ -174,7 +174,7 @@ switch (transform_type_) { case SVGTransformType::kMatrix: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case SVGTransformType::kUnknown: return MakeGarbageCollected<SVGTransform>(); case SVGTransformType::kTranslate: { @@ -213,7 +213,7 @@ switch (transform_type_) { case SVGTransformType::kMatrix: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case SVGTransformType::kUnknown: return 0; case SVGTransformType::kRotate:
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index b7cd594..6efb677 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2920,10 +2920,10 @@ document->View()->UpdateDocumentAnnotatedRegions(); Vector<AnnotatedRegionValue> regions = document->AnnotatedRegions(); - Vector<FloatQuad> quads; + Vector<gfx::QuadF> quads; for (const AnnotatedRegionValue& region : regions) { if (region.draggable == draggable) - quads.push_back(FloatQuad(gfx::RectF(region.bounds))); + quads.push_back(gfx::QuadF(gfx::RectF(region.bounds))); } return MakeGarbageCollected<DOMRectList>(quads); }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index 4bfb6977..308add69 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -1876,7 +1876,7 @@ case kResponseTypeDefault: if (ResponseIsXML()) return std::make_unique<TextResourceDecoder>(decoder_options_for_xml); - FALLTHROUGH; + [[fallthrough]]; case kResponseTypeText: return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions( TextResourceDecoderOptions::kPlainTextContent, UTF8Encoding()));
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index ee46f7e..1cd48ae 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2650,7 +2650,7 @@ *out_value = (min_value + max_value) / 2.0f; return true; } - FALLTHROUGH; + [[fallthrough]]; } case ax::mojom::blink::Role::kSplitter: { *out_value = 50.0f;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index b2f3455..0e4851a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -43,7 +43,6 @@ #include "third_party/blink/renderer/core/scroll/scroll_alignment.h" #include "third_party/blink/renderer/modules/accessibility/ax_enums.h" #include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -54,6 +53,7 @@ #include "ui/accessibility/ax_common.h" #include "ui/accessibility/ax_enums.mojom-blink.h" #include "ui/accessibility/ax_mode.h" +#include "ui/gfx/geometry/quad_f.h" namespace skia { class Matrix44;
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc index 4b3971bc..9caa50f 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc
@@ -530,7 +530,8 @@ mojom::blink::AuctionAdConfig& output) { if (!input.hasInterestGroupBuyers()) return true; - output.interest_group_buyers = mojom::blink::InterestGroupBuyers::New(); + output.shareable_auction_ad_config->interest_group_buyers = + mojom::blink::InterestGroupBuyers::New(); switch (input.interestGroupBuyers()->GetContentType()) { case V8UnionUSVStringOrUSVStringSequence::ContentType::kUSVString: { const String& maybe_wildcard = @@ -542,7 +543,7 @@ "strings.")); return false; } - output.interest_group_buyers->set_all_buyers( + output.shareable_auction_ad_config->interest_group_buyers->set_all_buyers( mojom::blink::AllBuyers::New()); break; } @@ -559,7 +560,8 @@ } buyers.push_back(buyer); } - output.interest_group_buyers->set_buyers(std::move(buyers)); + output.shareable_auction_ad_config->interest_group_buyers->set_buyers( + std::move(buyers)); break; } } @@ -574,7 +576,7 @@ if (!input.hasAuctionSignals()) return true; if (!Jsonify(script_state, input.auctionSignals().V8Value(), - output.auction_signals)) { + output.shareable_auction_ad_config->auction_signals)) { exception_state.ThrowTypeError( ErrorInvalidAuctionConfigJson(input, "auctionSignals")); return false; @@ -589,7 +591,7 @@ if (!input.hasSellerSignals()) return true; if (!Jsonify(script_state, input.sellerSignals().V8Value(), - output.seller_signals)) { + output.shareable_auction_ad_config->seller_signals)) { exception_state.ThrowTypeError( ErrorInvalidAuctionConfigJson(input, "sellerSignals")); return false; @@ -604,7 +606,7 @@ mojom::blink::AuctionAdConfig& output) { if (!input.hasPerBuyerSignals()) return true; - output.per_buyer_signals.emplace(); + output.shareable_auction_ad_config->per_buyer_signals.emplace(); for (const auto& per_buyer_signal : input.perBuyerSignals()) { scoped_refptr<const SecurityOrigin> buyer = ParseOrigin(per_buyer_signal.first); @@ -621,7 +623,8 @@ ErrorInvalidAuctionConfigJson(input, "perBuyerSignals")); return false; } - output.per_buyer_signals->insert(buyer, std::move(buyer_signals_str)); + output.shareable_auction_ad_config->per_buyer_signals->insert( + buyer, std::move(buyer_signals_str)); } return true; @@ -845,6 +848,8 @@ ExceptionState& exception_state) { const ExecutionContext* context = ExecutionContext::From(script_state); auto mojo_config = mojom::blink::AuctionAdConfig::New(); + mojo_config->shareable_auction_ad_config = + mojom::blink::ShareableAuctionAdConfig::New(); if (!CopySellerFromIdlToMojo(exception_state, *config, *mojo_config) || !CopyDecisionLogicUrlFromIdlToMojo(*context, exception_state, *config, *mojo_config) ||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc index c7126d4f..94d7af5 100644 --- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc +++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
@@ -154,7 +154,7 @@ case mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE: if (IsScreenOrWindowCapture(device.id)) return device.id; - FALLTHROUGH; + [[fallthrough]]; default: return std::string(); } @@ -180,7 +180,7 @@ MediaStreamVideoTrackUnderlyingSource::kMinMonitoredFrameCount, media::kVideoCaptureDefaultMaxBufferPoolSize / 2))); } - FALLTHROUGH; + [[fallthrough]]; default: // There will be no monitoring and no frame pool size. Return 0 to signal // that the returned value will not be used.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index 91ef0823..f3d51c5 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -26,7 +26,6 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" @@ -34,6 +33,7 @@ #include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/skia_conversions.h" namespace blink { @@ -1709,8 +1709,8 @@ bool BaseRenderingContext2D::RectContainsTransformedRect( const gfx::RectF& rect, const SkIRect& transformed_rect) const { - FloatQuad quad(rect); - FloatQuad transformed_quad( + gfx::QuadF quad(rect); + gfx::QuadF transformed_quad( gfx::RectF(transformed_rect.x(), transformed_rect.y(), transformed_rect.width(), transformed_rect.height())); return GetState().GetTransform().MapQuad(quad).ContainsQuad(transformed_quad);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc index d68df06..e90226bd 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -628,6 +628,19 @@ path_.MoveTo(gfx::PointF(x, y)); } +void CanvasPath::roundRect( + double double_x, + double double_y, + double double_width, + double double_height, + const Member<V8UnionDOMPointInitOrUnrestrictedDouble>& radius, + ExceptionState& exception_state) { + const auto radii = + HeapVector<Member<V8UnionDOMPointInitOrUnrestrictedDouble>>(1, radius); + roundRect(double_x, double_y, double_width, double_height, radii, + exception_state); +} + void CanvasPath::Trace(Visitor* visitor) const { visitor->Trace(identifiability_study_helper_); }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h index b95b416..cb889f72 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
@@ -97,6 +97,12 @@ double double_height, const HeapVector<Member<V8UnionDOMPointInitOrUnrestrictedDouble>>& radii, ExceptionState& exception_state); + void roundRect(double double_x, + double double_y, + double double_width, + double double_height, + const Member<V8UnionDOMPointInitOrUnrestrictedDouble>& radius, + ExceptionState& exception_state); bool IsTransformInvertible() const;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl index 96d27a9c..3615be22 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
@@ -14,6 +14,7 @@ [NoAllocDirectCall, RaisesException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); [NoAllocDirectCall] void rect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height); [RuntimeEnabled=NewCanvas2DAPI, RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, sequence<(unrestricted double or DOMPointInit)> radii); + [RuntimeEnabled=NewCanvas2DAPI, RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, (unrestricted double or DOMPointInit) radii); [NoAllocDirectCall, RaisesException] void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); [NoAllocDirectCall, RaisesException] void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index c554518..249847c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -711,7 +711,7 @@ NOTREACHED(); // no break on purpose: flags needs to be assigned to avoid compiler warning // about uninitialized variable. - FALLTHROUGH; + [[fallthrough]]; case kFillPaintType: UpdateFillStyle(); flags = &fill_flags_;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc index b1d58d98..0ae36c30 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc
@@ -116,6 +116,7 @@ } } + list_item->setSameParty(canonical_cookie.IsSameParty()); list_item->setPartitioned(canonical_cookie.IsPartitioned()); return list_item;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_init.idl b/third_party/blink/renderer/modules/cookie_store/cookie_init.idl index c1fa60e..181017c 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_init.idl +++ b/third_party/blink/renderer/modules/cookie_store/cookie_init.idl
@@ -17,5 +17,6 @@ USVString path = "/"; DOMTimeStamp? expires = null; CookieSameSite sameSite = "strict"; + [RuntimeEnabled=FirstPartySets] boolean sameParty = false; [RuntimeEnabled=PartitionedCookies] boolean partitioned = false; };
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl b/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl index 4f574779..c7f9aaa 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl +++ b/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl
@@ -12,6 +12,7 @@ DOMTimeStamp? expires; boolean secure; CookieSameSite sameSite; + [RuntimeEnabled=FirstPartySets] boolean sameParty; [RuntimeEnabled=PartitionedCookies] boolean partitioned; };
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc index a14b8f4e..f897df3 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -158,12 +158,11 @@ cookie_partition_key = net::CookiePartitionKey::FromScript(); } - // TODO(crbug.com/1144187): Add support for SameParty attribute. return net::CanonicalCookie::CreateSanitizedCookie( cookie_url, name.Utf8(), value.Utf8(), domain.Utf8(), path.Utf8(), base::Time() /*creation*/, expires, base::Time() /*last_access*/, true /*secure*/, false /*http_only*/, same_site, - net::CookiePriority::COOKIE_PRIORITY_DEFAULT, false /*same_party*/, + net::CookiePriority::COOKIE_PRIORITY_DEFAULT, options->sameParty(), cookie_partition_key); }
diff --git a/third_party/blink/renderer/modules/direct_sockets/tcp_socket.cc b/third_party/blink/renderer/modules/direct_sockets/tcp_socket.cc index 37bfec9..d620e5d 100644 --- a/third_party/blink/renderer/modules/direct_sockets/tcp_socket.cc +++ b/third_party/blink/renderer/modules/direct_sockets/tcp_socket.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/direct_sockets/tcp_socket.h" +#include "base/metrics/histogram_functions.h" #include "net/base/net_errors.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -12,6 +13,13 @@ namespace blink { +namespace { + +constexpr char kTCPNetworkFailuresHistogramName[] = + "DirectSockets.TCPNetworkFailures"; + +} // namespace + TCPSocket::TCPSocket(ScriptPromiseResolver& resolver) : resolver_(&resolver), feature_handle_for_scheduler_( @@ -68,6 +76,11 @@ std::move(send_stream)); resolver_->Resolve(this); } else { + if (result != net::Error::OK) { + // Error codes are negative. + base::UmaHistogramSparse(kTCPNetworkFailuresHistogramName, -result); + } + // TODO(crbug/1282199): Create specific exception based on error code. resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotAllowedError, "Permission denied")); socket_observer_receiver_.reset();
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_socket.cc b/third_party/blink/renderer/modules/direct_sockets/udp_socket.cc index fdb39d4..2470d98d 100644 --- a/third_party/blink/renderer/modules/direct_sockets/udp_socket.cc +++ b/third_party/blink/renderer/modules/direct_sockets/udp_socket.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/direct_sockets/udp_socket.h" +#include "base/metrics/histogram_functions.h" #include "net/base/net_errors.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -16,6 +17,13 @@ namespace blink { +namespace { + +constexpr char kUDPNetworkFailuresHistogramName[] = + "DirectSockets.UDPNetworkFailures"; + +} + UDPSocket::UDPSocket(ExecutionContext* execution_context, ScriptPromiseResolver& resolver) : ExecutionContextClient(execution_context), @@ -54,6 +62,10 @@ peer_addr_ = peer_addr; init_resolver_->Resolve(this); } else { + if (result != net::Error::OK) { + // Error codes are negative. + base::UmaHistogramSparse(kUDPNetworkFailuresHistogramName, -result); + } // TODO(crbug/1282199): Create specific exception based on error code. init_resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotAllowedError, "Permission denied"));
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc index d45a0c0..4e4654e5a 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -1852,7 +1852,7 @@ // canceled. GetMediaStreamDispatcherHost()->CancelRequest( current_request_info_->request_id()); - FALLTHROUGH; + [[fallthrough]]; case RequestInfo::State::kNotSentForGeneration: LogUserMediaRequestWithNoResult(
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index 023b998..83a16d9 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -1618,14 +1618,14 @@ case HasEnrolledInstrumentQueryResult::WARNING_HAS_ENROLLED_INSTRUMENT: WarnIgnoringQueryQuotaForCanMakePayment(*GetExecutionContext(), kHasEnrolledInstrumentDebugName); - FALLTHROUGH; + [[fallthrough]]; case HasEnrolledInstrumentQueryResult::HAS_ENROLLED_INSTRUMENT: has_enrolled_instrument_resolver_->Resolve(true); break; case HasEnrolledInstrumentQueryResult::WARNING_HAS_NO_ENROLLED_INSTRUMENT: WarnIgnoringQueryQuotaForCanMakePayment(*GetExecutionContext(), kHasEnrolledInstrumentDebugName); - FALLTHROUGH; + [[fallthrough]]; case HasEnrolledInstrumentQueryResult::HAS_NO_ENROLLED_INSTRUMENT: has_enrolled_instrument_resolver_->Resolve(false); break;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc index fdc0a91..12140988 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -556,11 +556,11 @@ switch (state_) { case webrtc::DataChannelInterface::kConnecting: has_valid_listeners |= HasEventListeners(event_type_names::kOpen); - FALLTHROUGH; + [[fallthrough]]; case webrtc::DataChannelInterface::kOpen: has_valid_listeners |= HasEventListeners(event_type_names::kMessage) || HasEventListeners(event_type_names::kClosing); - FALLTHROUGH; + [[fallthrough]]; case webrtc::DataChannelInterface::kClosing: has_valid_listeners |= HasEventListeners(event_type_names::kError) || HasEventListeners(event_type_names::kClose);
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc index 835bca8d..e47aba08 100644 --- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc +++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -210,7 +210,7 @@ pending_operation_ = nullptr; break; } - FALLTHROUGH; + [[fallthrough]]; case MOJO_RESULT_SHOULD_WAIT: watcher_.ArmOrNotify(); break;
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_data.cc b/third_party/blink/renderer/modules/webcodecs/audio_data.cc index f512f19..c87baf0 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_data.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_data.cc
@@ -37,7 +37,7 @@ // to kSampleFormatS32, but we do not update our labelling. It's ok to // treat the kSampleFormatS24 as kSampleFormatS32 until we update the // labelling, since our code already treats S24 as S32. - FALLTHROUGH; + [[fallthrough]]; case media::SampleFormat::kSampleFormatS32: return V8AudioSampleFormat(FormatEnum::kS32);
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index cc09d0a..ff1a8bd 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -292,7 +292,7 @@ } const base::Feature kWebCodecsAv1Encoding{"WebCodecsAv1Encoding", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; bool VerifyCodecSupportStatic(VideoEncoderTraits::ParsedConfig* config, ExceptionState* exception_state) { @@ -307,14 +307,6 @@ return false; } - if (config->options.scalability_mode.has_value()) { - if (exception_state) { - exception_state->ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "SVC encoding is not supported for AV1 yet."); - } - return false; - } if (config->profile != media::VideoCodecProfile::AV1PROFILE_PROFILE_MAIN) { if (exception_state) { @@ -323,7 +315,6 @@ } return false; } - // TODO(crbug.com/1208280): Check for supported AV1 levels break; case media::VideoCodec::kVP8: @@ -561,7 +552,7 @@ &VideoEncoder::CreateSoftwareVideoEncoder, WrapCrossThreadWeakPersistent(this), config.codec))); } - FALLTHROUGH; + [[fallthrough]]; case HardwarePreference::kPreferSoftware: return CreateSoftwareVideoEncoder(this, config.codec); @@ -995,6 +986,9 @@ VideoEncoderTraits::ParsedConfig* config) { std::unique_ptr<media::VideoEncoder> software_encoder; switch (config->codec) { + case media::VideoCodec::kAV1: + software_encoder = CreateAv1VideoEncoder(); + break; case media::VideoCodec::kVP8: case media::VideoCodec::kVP9: software_encoder = CreateVpxVideoEncoder();
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 2108a26..c51494e3 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -922,7 +922,7 @@ "for integer formats, samples > 0"); return; } - FALLTHROUGH; + [[fallthrough]]; case GL_R8: case GL_RG8: case GL_RGB8: @@ -5908,7 +5908,7 @@ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: if (!attachment_object->IsTexture()) break; - FALLTHROUGH; + [[fallthrough]]; case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: @@ -5927,7 +5927,7 @@ "COMPONENT_TYPE can't be queried for DEPTH_STENCIL_ATTACHMENT"); return ScriptValue::CreateNull(script_state->GetIsolate()); } - FALLTHROUGH; + [[fallthrough]]; case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: { GLint value = 0; ContextGL()->GetFramebufferAttachmentParameteriv(target, attachment,
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 d4be2dd..80f4f81 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
@@ -3761,7 +3761,7 @@ "invalid parameter name"); return ScriptValue::CreateNull(script_state->GetIsolate()); } - FALLTHROUGH; + [[fallthrough]]; case GL_ATTACHED_SHADERS: case GL_ACTIVE_ATTRIBUTES: case GL_ACTIVE_UNIFORMS: @@ -3814,7 +3814,7 @@ "invalid parameter name"); return ScriptValue::CreateNull(script_state->GetIsolate()); } - FALLTHROUGH; + [[fallthrough]]; case GL_RENDERBUFFER_WIDTH: case GL_RENDERBUFFER_HEIGHT: case GL_RENDERBUFFER_RED_SIZE: @@ -4330,7 +4330,7 @@ ContextGL()->GetVertexAttribiv(index, pname, &value); return WebGLAny(script_state, static_cast<bool>(value)); } - FALLTHROUGH; + [[fallthrough]]; default: SynthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name"); @@ -6413,7 +6413,7 @@ "invalid parameter name"); return; } - FALLTHROUGH; + [[fallthrough]]; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: if ((is_float && paramf != GL_CLAMP_TO_EDGE && @@ -7938,7 +7938,7 @@ } break; } - FALLTHROUGH; + [[fallthrough]]; case GL_TEXTURE_2D_ARRAY: if (IsWebGL2()) { if (width > (max_texture_size_ >> level) || @@ -7950,7 +7950,7 @@ } break; } - FALLTHROUGH; + [[fallthrough]]; default: SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target"); return false;
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index e6255da3..69bfdc88 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -84,13 +84,13 @@ switch (webgpu_extent_sequence.size()) { default: dawn_extent.depthOrArrayLayers = webgpu_extent_sequence[2]; - FALLTHROUGH; + [[fallthrough]]; case 2: dawn_extent.height = webgpu_extent_sequence[1]; - FALLTHROUGH; + [[fallthrough]]; case 1: dawn_extent.width = webgpu_extent_sequence[0]; - FALLTHROUGH; + [[fallthrough]]; case 0: break; } @@ -124,13 +124,13 @@ switch (webgpu_origin_sequence.size()) { default: dawn_origin.z = webgpu_origin_sequence[2]; - FALLTHROUGH; + [[fallthrough]]; case 2: dawn_origin.y = webgpu_origin_sequence[1]; - FALLTHROUGH; + [[fallthrough]]; case 1: dawn_origin.x = webgpu_origin_sequence[0]; - FALLTHROUGH; + [[fallthrough]]; case 0: break; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index a96e81c..07241f1c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -62,10 +62,10 @@ default: // This is a 2D origin and the depth should be 0 always. dawn_origin.y = webgpu_origin_sequence[1]; - FALLTHROUGH; + [[fallthrough]]; case 1: dawn_origin.x = webgpu_origin_sequence[0]; - FALLTHROUGH; + [[fallthrough]]; case 0: break; }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 7c239642..8bb6ff3 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -805,7 +805,7 @@ switch (message.Type()) { case kMessageTypeText: message_type = network::mojom::blink::WebSocketMessageType::TEXT; - FALLTHROUGH; + [[fallthrough]]; case kMessageTypeArrayBuffer: { base::span<const char>& data_frame = message.MutablePendingPayload(); if (!message.GetDidCallSendMessage()) {
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc index aef7344..139377e 100644 --- a/third_party/blink/renderer/modules/webusb/usb_device.cc +++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -767,7 +767,7 @@ switch (error) { case UsbOpenDeviceError::ALREADY_OPEN: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case UsbOpenDeviceError::OK: OnDeviceOpenedOrClosed(true /* opened */); resolver->Resolve();
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index dd34ed4..72bd14c 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -751,8 +751,6 @@ "geometry/double_size.h", "geometry/float_polygon.cc", "geometry/float_polygon.h", - "geometry/float_quad.cc", - "geometry/float_quad.h", "geometry/float_rect_outsets.cc", "geometry/float_rect_outsets.h", "geometry/float_rounded_rect.cc", @@ -2037,7 +2035,6 @@ "geometry/double_point_test.cc", "geometry/double_rect_test.cc", "geometry/float_polygon_test.cc", - "geometry/float_quad_test.cc", "geometry/float_rounded_rect_test.cc", "geometry/layout_rect_test.cc", "geometry/layout_unit_test.cc",
diff --git a/third_party/blink/renderer/platform/geometry/float_quad.cc b/third_party/blink/renderer/platform/geometry/float_quad.cc deleted file mode 100644 index 51e44c0..0000000 --- a/third_party/blink/renderer/platform/geometry/float_quad.cc +++ /dev/null
@@ -1,260 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2013 Xidorn Quan (quanxunzhen@gmail.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/geometry/float_quad.h" - -#include <algorithm> -#include <cmath> -#include <limits> -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#include "third_party/skia/include/core/SkPoint.h" -#include "ui/gfx/geometry/skia_conversions.h" - -namespace blink { - -static inline float Min4(float a, float b, float c, float d) { - return std::min(std::min(a, b), std::min(c, d)); -} - -static inline float Max4(float a, float b, float c, float d) { - return std::max(std::max(a, b), std::max(c, d)); -} - -inline bool IsPointInTriangle(const gfx::PointF& p, - const gfx::PointF& t1, - const gfx::PointF& t2, - const gfx::PointF& t3) { - // Compute vectors - gfx::Vector2dF v0 = t3 - t1; - gfx::Vector2dF v1 = t2 - t1; - gfx::Vector2dF v2 = p - t1; - - // Compute dot products - double dot00 = gfx::DotProduct(v0, v0); - double dot01 = gfx::DotProduct(v0, v1); - double dot02 = gfx::DotProduct(v0, v2); - double dot11 = gfx::DotProduct(v1, v1); - double dot12 = gfx::DotProduct(v1, v2); - - // Compute barycentric coordinates - double inv_denom = 1.0f / (dot00 * dot11 - dot01 * dot01); - double u = (dot11 * dot02 - dot01 * dot12) * inv_denom; - double v = (dot00 * dot12 - dot01 * dot02) * inv_denom; - - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v <= 1); -} - -static inline float ClampToIntRange(float value) { - if (UNLIKELY(std::isinf(value) || - std::abs(value) > std::numeric_limits<int>::max())) { - return std::signbit(value) ? std::numeric_limits<int>::min() - : std::numeric_limits<int>::max(); - } - return value; -} - -gfx::RectF FloatQuad::BoundingBox() const { - float left = ClampToIntRange(Min4(p1_.x(), p2_.x(), p3_.x(), p4_.x())); - float top = ClampToIntRange(Min4(p1_.y(), p2_.y(), p3_.y(), p4_.y())); - - float right = ClampToIntRange(Max4(p1_.x(), p2_.x(), p3_.x(), p4_.x())); - float bottom = ClampToIntRange(Max4(p1_.y(), p2_.y(), p3_.y(), p4_.y())); - - return gfx::RectF(left, top, right - left, bottom - top); -} - -static inline bool WithinEpsilon(float a, float b) { - return fabs(a - b) < std::numeric_limits<float>::epsilon(); -} - -FloatQuad::FloatQuad(const SkPoint (&quad)[4]) - : FloatQuad(gfx::SkPointToPointF(quad[0]), - gfx::SkPointToPointF(quad[1]), - gfx::SkPointToPointF(quad[2]), - gfx::SkPointToPointF(quad[3])) {} - -bool FloatQuad::IsRectilinear() const { - return (WithinEpsilon(p1_.x(), p2_.x()) && WithinEpsilon(p2_.y(), p3_.y()) && - WithinEpsilon(p3_.x(), p4_.x()) && WithinEpsilon(p4_.y(), p1_.y())) || - (WithinEpsilon(p1_.y(), p2_.y()) && WithinEpsilon(p2_.x(), p3_.x()) && - WithinEpsilon(p3_.y(), p4_.y()) && WithinEpsilon(p4_.x(), p1_.x())); -} - -bool FloatQuad::ContainsPoint(const gfx::PointF& p) const { - return IsPointInTriangle(p, p1_, p2_, p3_) || - IsPointInTriangle(p, p1_, p3_, p4_); -} - -// Note that we only handle convex quads here. -bool FloatQuad::ContainsQuad(const FloatQuad& other) const { - return ContainsPoint(other.p1()) && ContainsPoint(other.p2()) && - ContainsPoint(other.p3()) && ContainsPoint(other.p4()); -} - -static inline gfx::PointF RightMostCornerToVector( - const gfx::RectF& rect, - const gfx::Vector2dF& vector) { - // Return the corner of the rectangle that if it is to the left of the vector - // would mean all of the rectangle is to the left of the vector. - // The vector here represents the side between two points in a clockwise - // convex polygon. - // - // Q XXX - // QQQ XXX If the lower left corner of X is left of the vector that goes - // QQQ from the top corner of Q to the right corner of Q, then all of X - // Q is left of the vector, and intersection impossible. - // - gfx::PointF point; - if (vector.x() >= 0) - point.set_y(rect.bottom()); - else - point.set_y(rect.y()); - if (vector.y() >= 0) - point.set_x(rect.x()); - else - point.set_x(rect.right()); - return point; -} - -bool FloatQuad::IntersectsRect(const gfx::RectF& rect) const { - // IntersectsRect is only valid on convex quads which an empty quad is not. - DCHECK(!IsEmpty()); - - // For each side of the quad clockwise we check if the rectangle is to the - // left of it since only content on the right can onlap with the quad. This - // only works if the quad is convex. - gfx::Vector2dF v1, v2, v3, v4; - - // Ensure we use clockwise vectors. - if (!IsCounterclockwise()) { - v1 = p2_ - p1_; - v2 = p3_ - p2_; - v3 = p4_ - p3_; - v4 = p1_ - p4_; - } else { - v1 = p4_ - p1_; - v2 = p1_ - p2_; - v3 = p2_ - p3_; - v4 = p3_ - p4_; - } - - gfx::PointF p = RightMostCornerToVector(rect, v1); - if (gfx::CrossProduct(v1, p - p1_) < 0) - return false; - - p = RightMostCornerToVector(rect, v2); - if (gfx::CrossProduct(v2, p - p2_) < 0) - return false; - - p = RightMostCornerToVector(rect, v3); - if (gfx::CrossProduct(v3, p - p3_) < 0) - return false; - - p = RightMostCornerToVector(rect, v4); - if (gfx::CrossProduct(v4, p - p4_) < 0) - return false; - - // If not all of the rectangle is outside one of the quad's four sides, then - // that means at least a part of the rectangle is overlapping the quad. - return true; -} - -// Tests whether the line is contained by or intersected with the circle. -static inline bool LineIntersectsCircle(const gfx::PointF& center, - float radius, - const gfx::PointF& p0, - const gfx::PointF& p1) { - float x0 = p0.x() - center.x(), y0 = p0.y() - center.y(); - float x1 = p1.x() - center.x(), y1 = p1.y() - center.y(); - float radius2 = radius * radius; - if ((x0 * x0 + y0 * y0) <= radius2 || (x1 * x1 + y1 * y1) <= radius2) - return true; - if (p0 == p1) - return false; - - float a = y0 - y1; - float b = x1 - x0; - float c = x0 * y1 - x1 * y0; - float distance2 = c * c / (a * a + b * b); - // If distance between the center point and the line > the radius, - // the line doesn't cross (or is contained by) the ellipse. - if (distance2 > radius2) - return false; - - // The nearest point on the line is between p0 and p1? - float x = -a * c / (a * a + b * b); - float y = -b * c / (a * a + b * b); - - return (((x0 <= x && x <= x1) || (x0 >= x && x >= x1)) && - ((y0 <= y && y <= y1) || (y1 <= y && y <= y0))); -} - -bool FloatQuad::IntersectsCircle(const gfx::PointF& center, - float radius) const { - return ContainsPoint( - center) // The circle may be totally contained by the quad. - || LineIntersectsCircle(center, radius, p1_, p2_) || - LineIntersectsCircle(center, radius, p2_, p3_) || - LineIntersectsCircle(center, radius, p3_, p4_) || - LineIntersectsCircle(center, radius, p4_, p1_); -} - -bool FloatQuad::IntersectsEllipse(const gfx::PointF& center, - const gfx::SizeF& radii) const { - // Transform the ellipse to an origin-centered circle whose radius is the - // product of major radius and minor radius. Here we apply the same - // transformation to the quad. - FloatQuad transformed_quad(*this); - transformed_quad.Move(-center.x(), -center.y()); - transformed_quad.Scale(radii.height(), radii.width()); - - gfx::PointF origin_point; - return transformed_quad.IntersectsCircle(origin_point, - radii.height() * radii.width()); -} - -bool FloatQuad::IsCounterclockwise() const { - // Return if the two first vectors are turning clockwise. If the quad is - // convex then all following vectors will turn the same way. - return gfx::CrossProduct(p2_ - p1_, p3_ - p2_) < 0; -} - -std::ostream& operator<<(std::ostream& ostream, const FloatQuad& quad) { - return ostream << quad.ToString(); -} - -String FloatQuad::ToString() const { - return String::Format("%s; %s; %s; %s", p1_.ToString().c_str(), - p2_.ToString().c_str(), p3_.ToString().c_str(), - p4_.ToString().c_str()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/float_quad.h b/third_party/blink/renderer/platform/geometry/float_quad.h deleted file mode 100644 index 649b5a4a..0000000 --- a/third_party/blink/renderer/platform/geometry/float_quad.h +++ /dev/null
@@ -1,203 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_QUAD_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_QUAD_H_ - -#include <iosfwd> -#include "third_party/blink/renderer/platform/geometry/layout_size.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/quad_f.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/rect_conversions.h" -#include "ui/gfx/geometry/rect_f.h" - -struct SkPoint; - -namespace blink { - -// A FloatQuad is a collection of 4 points, often representing the result of -// mapping a rectangle through transforms. When initialized from a rect, the -// points are in clockwise order from top left. -class PLATFORM_EXPORT FloatQuad { - USING_FAST_MALLOC(FloatQuad); - - public: - constexpr FloatQuad() = default; - - constexpr FloatQuad(const gfx::PointF& p1, - const gfx::PointF& p2, - const gfx::PointF& p3, - const gfx::PointF& p4) - : p1_(p1), p2_(p2), p3_(p3), p4_(p4) {} - - explicit constexpr FloatQuad(const gfx::RectF& in_rect) - : p1_(in_rect.origin()), - p2_(in_rect.right(), in_rect.y()), - p3_(in_rect.right(), in_rect.bottom()), - p4_(in_rect.x(), in_rect.bottom()) {} - - explicit constexpr FloatQuad(const gfx::Rect& in_rect) - : p1_(in_rect.origin()), - p2_(in_rect.right(), in_rect.y()), - p3_(in_rect.right(), in_rect.bottom()), - p4_(in_rect.x(), in_rect.bottom()) {} - - // Converts from an array of four SkPoints, as from SkMatrix::mapRectToQuad. - explicit FloatQuad(const SkPoint (&)[4]); - - explicit FloatQuad(const gfx::QuadF& q) - : p1_(q.p1()), p2_(q.p2()), p3_(q.p3()), p4_(q.p4()) {} - - // This is deleted during blink geometry type to gfx migration. - // Use ToGfxQuadF() instead. - operator gfx::QuadF() const = delete; - - constexpr gfx::PointF p1() const { return p1_; } - constexpr gfx::PointF p2() const { return p2_; } - constexpr gfx::PointF p3() const { return p3_; } - constexpr gfx::PointF p4() const { return p4_; } - - void set_p1(const gfx::PointF& p) { p1_ = p; } - void set_p2(const gfx::PointF& p) { p2_ = p; } - void set_p3(const gfx::PointF& p) { p3_ = p; } - void set_p4(const gfx::PointF& p) { p4_ = p; } - - // isEmpty tests that the bounding box is empty. This will not identify - // "slanted" empty quads. - bool IsEmpty() const { return BoundingBox().IsEmpty(); } - - // Tests whether this quad can be losslessly represented by a gfx::RectF, - // that is, if two edges are parallel to the x-axis and the other two - // are parallel to the y-axis. If this method returns true, the - // corresponding gfx::RectF can be retrieved with boundingBox(). - bool IsRectilinear() const; - - // Tests whether the given point is inside, or on an edge or corner of this - // quad. - bool ContainsPoint(const gfx::PointF&) const; - - // Tests whether the four corners of other are inside, or coincident with the - // sides of this quad. Note that this only works for convex quads, but that - // includes all quads that originate - // from transformed rects. - bool ContainsQuad(const FloatQuad&) const; - - // Tests whether any part of the rectangle intersects with this quad. - // This only works for convex quads. - // This intersection is edge-inclusive and will return true even if the - // intersecting area is empty (i.e., the intersection is a line or a point). - bool IntersectsRect(const gfx::RectF&) const; - - // Test whether any part of the circle/ellipse intersects with this quad. - // Note that these two functions only work for convex quads. - // These intersections are edge-inclusive and will return true even if the - // intersecting area is empty (i.e., the intersection is a line or a point). - bool IntersectsCircle(const gfx::PointF& center, float radius) const; - bool IntersectsEllipse(const gfx::PointF& center, - const gfx::SizeF& radii) const; - - // The center of the quad. If the quad is the result of a affine-transformed - // rectangle this is the same as the original center transformed. - gfx::PointF Center() const { - return gfx::PointF((p1_.x() + p2_.x() + p3_.x() + p4_.x()) / 4.0, - (p1_.y() + p2_.y() + p3_.y() + p4_.y()) / 4.0); - } - - gfx::RectF BoundingBox() const; - gfx::Rect EnclosingBoundingBox() const { - return gfx::ToEnclosingRect(BoundingBox()); - } - - void Move(const gfx::Vector2dF& offset) { - p1_ += offset; - p2_ += offset; - p3_ += offset; - p4_ += offset; - } - - void Move(const LayoutSize& offset) { - Move(offset.Width().ToFloat(), offset.Height().ToFloat()); - } - - void Move(float dx, float dy) { - p1_.Offset(dx, dy); - p2_.Offset(dx, dy); - p3_.Offset(dx, dy); - p4_.Offset(dx, dy); - } - - void Scale(float dx, float dy) { - p1_.Scale(dx, dy); - p2_.Scale(dx, dy); - p3_.Scale(dx, dy); - p4_.Scale(dx, dy); - } - - // Tests whether points are in clock-wise, or counter clock-wise order. - // Note that output is undefined when all points are colinear. - bool IsCounterclockwise() const; - - String ToString() const; - - private: - gfx::PointF p1_; - gfx::PointF p2_; - gfx::PointF p3_; - gfx::PointF p4_; -}; - -inline FloatQuad& operator+=(FloatQuad& a, const gfx::Vector2dF& b) { - a.Move(b); - return a; -} - -inline FloatQuad& operator-=(FloatQuad& a, const gfx::Vector2dF& b) { - a.Move(-b); - return a; -} - -constexpr bool operator==(const FloatQuad& a, const FloatQuad& b) { - return a.p1() == b.p1() && a.p2() == b.p2() && a.p3() == b.p3() && - a.p4() == b.p4(); -} - -constexpr bool operator!=(const FloatQuad& a, const FloatQuad& b) { - return !(a == b); -} - -constexpr gfx::QuadF ToGfxQuadF(const FloatQuad& q) { - return gfx::QuadF(q.p1(), q.p2(), q.p3(), q.p4()); -} - -PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatQuad&); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_QUAD_H_
diff --git a/third_party/blink/renderer/platform/geometry/float_quad_test.cc b/third_party/blink/renderer/platform/geometry/float_quad_test.cc deleted file mode 100644 index 0d8ced2..0000000 --- a/third_party/blink/renderer/platform/geometry/float_quad_test.cc +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/geometry/float_quad.h" - -#include <limits> -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -TEST(FloatQuadTest, ToString) { - FloatQuad quad(gfx::PointF(2, 3), gfx::PointF(5, 7), gfx::PointF(11, 13), - gfx::PointF(17, 19)); - EXPECT_EQ("2,3; 5,7; 11,13; 17,19", quad.ToString()); -} - -TEST(FloatQuadTest, BoundingBox) { - FloatQuad quad(gfx::PointF(2, 3), gfx::PointF(5, 7), gfx::PointF(11, 13), - gfx::PointF(17, 19)); - gfx::RectF rect = quad.BoundingBox(); - EXPECT_EQ(rect.x(), 2); - EXPECT_EQ(rect.y(), 3); - EXPECT_EQ(rect.width(), 17 - 2); - EXPECT_EQ(rect.height(), 19 - 3); -} - -TEST(FloatQuadTest, BoundingBoxSaturateInf) { - constexpr double inf = std::numeric_limits<double>::infinity(); - FloatQuad quad(gfx::PointF(-inf, 3), gfx::PointF(5, inf), gfx::PointF(11, 13), - gfx::PointF(17, 19)); - gfx::RectF rect = quad.BoundingBox(); - EXPECT_EQ(rect.x(), std::numeric_limits<int>::min()); - EXPECT_EQ(rect.y(), 3.0f); - EXPECT_EQ(rect.width(), 17.0f - std::numeric_limits<int>::min()); - EXPECT_EQ(rect.height(), - static_cast<float>(std::numeric_limits<int>::max()) - 3.0f); -} - -TEST(FloatQuadTest, BoundingBoxSaturateLarge) { - constexpr double large = std::numeric_limits<float>::max() * 4; - FloatQuad quad(gfx::PointF(-large, 3), gfx::PointF(5, large), - gfx::PointF(11, 13), gfx::PointF(17, 19)); - gfx::RectF rect = quad.BoundingBox(); - EXPECT_EQ(rect.x(), std::numeric_limits<int>::min()); - EXPECT_EQ(rect.y(), 3.0f); - EXPECT_EQ(rect.width(), 17.0f - std::numeric_limits<int>::min()); - EXPECT_EQ(rect.height(), - static_cast<float>(std::numeric_limits<int>::max()) - 3.0f); -} - -TEST(FloatQuadTest, RectIntersectionIsInclusive) { - // A rectilinear quad at (10, 10) with dimensions 10x10. - FloatQuad quad(gfx::RectF(10, 10, 10, 10)); - - // A rect fully contained in the quad should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(11, 11, 8, 8))); - - // A point fully contained in the quad should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(11, 11, 0, 0))); - - // A rect that touches the quad only at the point (10, 10) should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(9, 9, 1, 1))); - - // A rect that touches the quad only on the left edge should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(9, 11, 1, 1))); - - // A rect that touches the quad only on the top edge should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(11, 9, 1, 1))); - - // A rect that touches the quad only on the right edge should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(20, 11, 1, 1))); - - // A rect that touches the quad only on the bottom edge should intersect. - EXPECT_TRUE(quad.IntersectsRect(gfx::RectF(11, 20, 1, 1))); - - // A rect that is fully outside the quad should not intersect. - EXPECT_FALSE(quad.IntersectsRect(gfx::RectF(8, 8, 1, 1))); - - // A point that is fully outside the quad should not intersect. - EXPECT_FALSE(quad.IntersectsRect(gfx::RectF(9, 9, 0, 0))); -} - -TEST(FloatQuadTest, CircleIntersectionIsInclusive) { - // A rectilinear quad at (10, 10) with dimensions 10x10. - FloatQuad quad(gfx::RectF(10, 10, 10, 10)); - - // A circle fully contained in the top-left of the quad should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(12, 12), 1)); - - // A point fully contained in the top-left of the quad should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(12, 12), 0)); - - // A circle that touches the left edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(9, 11), 1)); - - // A circle that touches the top edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(11, 9), 1)); - - // A circle that touches the right edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(21, 11), 1)); - - // A circle that touches the bottom edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(11, 21), 1)); - - // A point that touches the left edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(10, 11), 0)); - - // A point that touches the top edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(11, 10), 0)); - - // A point that touches the right edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(20, 11), 0)); - - // A point that touches the bottom edge should intersect. - EXPECT_TRUE(quad.IntersectsCircle(gfx::PointF(11, 20), 0)); - - // A circle that is fully outside the quad should not intersect. - EXPECT_FALSE(quad.IntersectsCircle(gfx::PointF(9, 9), 1)); - - // A point that is fully outside the quad should not intersect. - EXPECT_FALSE(quad.IntersectsCircle(gfx::PointF(9, 9), 0)); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc b/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc index e395db67..5c71986 100644 --- a/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc +++ b/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc
@@ -30,10 +30,10 @@ #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include <algorithm> -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "ui/gfx/geometry/insets_f.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -142,6 +142,39 @@ } } +// From: https://drafts.csswg.org/css-backgrounds-3/#shadow-shape +// When the border radius is less than the spread distance, the spread distance +// is first multiplied by the proportion 1 + (r-1)^3, where r is the ratio of +// the border radius to the spread distance, in calculating the corner radii of +// the spread shadow shape. For example, if the border radius is 10px and the +// spread distance is 20px (r = .5), the corner radius of the shadow shape will +// be 10px + 20px × (1 + (.5 - 1)^3) = 27.5px rather than 30px. This adjustment +// is applied independently to the radii in each dimension. +static void ReshapeCorner(gfx::SizeF& corner, float inflation) { + if (corner.width() == 0 && corner.height() == 0) + return; + + float width_factor = 1; + if (corner.width() < inflation) + width_factor = 1 + pow(corner.width() / inflation - 1, 3); + + float height_factor = 1; + if (corner.height() == corner.width()) + height_factor = width_factor; + else if (corner.height() < inflation) + height_factor = 1 + pow(corner.height() / inflation - 1, 3); + + corner.set_width(corner.width() + width_factor * inflation); + corner.set_height(corner.height() + height_factor * inflation); +} + +void FloatRoundedRect::Radii::Reshape(float inflation) { + ReshapeCorner(top_left_, inflation); + ReshapeCorner(top_right_, inflation); + ReshapeCorner(bottom_left_, inflation); + ReshapeCorner(bottom_right_, inflation); +} + static inline float CornerRectIntercept(float y, const gfx::RectF& corner_rect) { DCHECK_GT(corner_rect.height(), 0); @@ -209,6 +242,13 @@ return true; } +void FloatRoundedRect::InflateAndReshape(float size) { + if (size == 0.f) + return; + rect_.Outset(size); + radii_.Reshape(size); +} + void FloatRoundedRect::InflateWithRadii(int size) { gfx::RectF old = rect_; @@ -224,7 +264,7 @@ radii_.Scale(factor); } -bool FloatRoundedRect::IntersectsQuad(const FloatQuad& quad) const { +bool FloatRoundedRect::IntersectsQuad(const gfx::QuadF& quad) const { if (!quad.IntersectsRect(rect_)) return false;
diff --git a/third_party/blink/renderer/platform/geometry/float_rounded_rect.h b/third_party/blink/renderer/platform/geometry/float_rounded_rect.h index 028e2c6..b5fdf5fa 100644 --- a/third_party/blink/renderer/platform/geometry/float_rounded_rect.h +++ b/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
@@ -40,9 +40,11 @@ #include "ui/gfx/geometry/size_f.h" #include "ui/gfx/geometry/skia_conversions.h" -namespace blink { +namespace gfx { +class QuadF; +} -class FloatQuad; +namespace blink { // Represents a rect with rounded corners. // We don't use gfx::RRect in blink because gfx::RRect is based on SkRRect @@ -108,6 +110,10 @@ float right_width); void Shrink(float size) { Shrink(size, size, size, size); } + // Reshapes the corners based on the algorithm in + // https://drafts.csswg.org/css-backgrounds-3/#shadow-shape. + void Reshape(float inflation); + String ToString() const; private: @@ -143,6 +149,10 @@ void InflateWithRadii(int size); void Inflate(float size) { rect_.Outset(size); } + // Inflates the rect and reshapes the corners based on the algorithm in + // https://drafts.csswg.org/css-backgrounds-3/#shadow-shape. + void InflateAndReshape(float size); + // expandRadii() does not have any effect on corner radii which have zero // width or height. This is because the process of expanding the radius of a // corner is not allowed to make sharp corners non-sharp. This applies when @@ -181,7 +191,7 @@ // This only works for convex quads. // This intersection is edge-inclusive and will return true even if the // intersecting area is empty (i.e., the intersection is a line or a point). - bool IntersectsQuad(const FloatQuad&) const; + bool IntersectsQuad(const gfx::QuadF&) const; // Whether the radii are constrained in the size of rect(). bool IsRenderable() const;
diff --git a/third_party/blink/renderer/platform/geometry/float_rounded_rect_test.cc b/third_party/blink/renderer/platform/geometry/float_rounded_rect_test.cc index 56bf7109..604ea3c 100644 --- a/third_party/blink/renderer/platform/geometry/float_rounded_rect_test.cc +++ b/third_party/blink/renderer/platform/geometry/float_rounded_rect_test.cc
@@ -30,9 +30,9 @@ #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/geometry/quad_f.h" namespace blink { @@ -190,46 +190,46 @@ FloatRoundedRect r(gfx::RectF(10, 10, 20, 20), corner_radii); // A quad fully inside the rounded rect should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(11, 11, 8, 8)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(11, 11, 8, 8)))); // A quad fully outside the rounded rect should not intersect. - EXPECT_FALSE(r.IntersectsQuad(FloatQuad(gfx::RectF(0, 0, 1, 1)))); + EXPECT_FALSE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(0, 0, 1, 1)))); // A quad touching the top edge of the rounded rect should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(15, 9, 5, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(15, 9, 5, 1)))); // A quad touching the right edge of the rounded rect should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(30, 15, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(30, 15, 1, 1)))); // A quad touching the bottom edge of the rounded rect should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(15, 30, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(15, 30, 1, 1)))); // A quad touching the left edge of the rounded rect should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(9, 15, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(9, 15, 1, 1)))); // A quad outside the top-left arc should not intersect. - EXPECT_FALSE(r.IntersectsQuad(FloatQuad(gfx::RectF(10, 10, 1, 1)))); + EXPECT_FALSE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(10, 10, 1, 1)))); // A quad inside the top-left arc should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(13, 13, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(13, 13, 1, 1)))); // A quad outside the top-right arc should not intersect. - EXPECT_FALSE(r.IntersectsQuad(FloatQuad(gfx::RectF(29, 10, 1, 1)))); + EXPECT_FALSE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(29, 10, 1, 1)))); // A quad inside the top-right arc should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(26, 13, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(26, 13, 1, 1)))); // A quad outside the bottom-right arc should not intersect. - EXPECT_FALSE(r.IntersectsQuad(FloatQuad(gfx::RectF(29, 29, 1, 1)))); + EXPECT_FALSE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(29, 29, 1, 1)))); // A quad inside the bottom-right arc should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(26, 26, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(26, 26, 1, 1)))); // A quad outside the bottom-left arc should not intersect. - EXPECT_FALSE(r.IntersectsQuad(FloatQuad(gfx::RectF(10, 29, 1, 1)))); + EXPECT_FALSE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(10, 29, 1, 1)))); // A quad inside the bottom-left arc should intersect. - EXPECT_TRUE(r.IntersectsQuad(FloatQuad(gfx::RectF(13, 26, 1, 1)))); + EXPECT_TRUE(r.IntersectsQuad(gfx::QuadF(gfx::RectF(13, 26, 1, 1)))); } TEST(FloatRoundedrectTest, ConstrainRadii) {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc index 53fe9f8..f73a9732 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -35,6 +35,7 @@ #include "cc/layers/texture_layer.h" #include "components/viz/common/resources/transferable_resource.h" #include "gpu/command_buffer/client/raster_interface.h" +#include "gpu/config/gpu_finch_features.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/platform.h" @@ -368,7 +369,8 @@ if (!lose_context_in_background_ && !lose_context_in_background_scheduled_ && ResourceProvider() && !context_lost_ && IsHidden() && - RuntimeEnabledFeatures::CanvasContextLostInBackgroundEnabled()) { + base::FeatureList::IsEnabled( + ::features::kCanvasContextLostInBackground)) { lose_context_in_background_scheduled_ = true; if (dont_use_idle_scheduling_for_testing_) { Thread::Current()->GetTaskRunner()->PostTask( @@ -381,7 +383,8 @@ } } else if (CANVAS2D_HIBERNATION_ENABLED && ResourceProvider() && IsAccelerated() && IsHidden() && !hibernation_scheduled_ && - !RuntimeEnabledFeatures::CanvasContextLostInBackgroundEnabled()) { + !base::FeatureList::IsEnabled( + ::features::kCanvasContextLostInBackground)) { if (layer_) layer_->ClearTexture(); logger_->ReportHibernationEvent(kHibernationScheduled);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc index 749acae..d573266f 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -64,8 +64,7 @@ const PaintChunkSubset& paint_chunks, const gfx::Vector2dF& layer_offset, const gfx::Size& layer_bounds, - const PropertyTreeState& layer_state, - bool draws_content) { + const PropertyTreeState& layer_state) { if (paint_chunks.begin()->is_cacheable) id_.emplace(paint_chunks.begin()->id); else @@ -128,7 +127,7 @@ cc_picture_layer_->SetBounds(layer_bounds); cc_picture_layer_->SetHitTestable(true); cc_picture_layer_->SetIsDrawable( - (!layer_bounds.IsEmpty() && draws_content) || + (!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) || // Backdrop effects and filters require the layer to be drawable even if // the layer draws nothing. layer_state.Effect().HasBackdropEffect() ||
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h index 3d33244..e91eef7 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h +++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
@@ -55,8 +55,7 @@ const PaintChunkSubset&, const gfx::Vector2dF& layer_offset, const gfx::Size& layer_bounds, - const PropertyTreeState&, - bool draws_content); + const PropertyTreeState&); RasterInvalidator& GetRasterInvalidator() { return raster_invalidator_; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 23a692b..ff4f25f 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -266,7 +266,7 @@ gfx::Size layer_bounds = pending_layer.LayerBounds(); auto cc_layer = content_layer_client->UpdateCcPictureLayer( pending_layer.Chunks(), layer_offset, layer_bounds, - pending_layer.GetPropertyTreeState(), pending_layer.DrawsContent()); + pending_layer.GetPropertyTreeState()); new_content_layer_clients.push_back(std::move(content_layer_client)); @@ -311,7 +311,6 @@ if (repainted.is_moved_from_cached_subsequence) { DCHECK_EQ(previous.bounds, repainted.bounds); - DCHECK_EQ(previous.DrawsContent(), repainted.DrawsContent()); DCHECK_EQ(previous.rect_known_to_be_opaque, repainted.rect_known_to_be_opaque); DCHECK_EQ(previous.text_known_to_be_on_opaque_background, @@ -362,12 +361,6 @@ if (previous.has_text != repainted.has_text) return true; - // |PaintChunk::DrawsContent()| affects whether a layer draws content which - // affects whether mask layers are created (see: - // |SwitchToEffectNodeWithSynthesizedClip|). - if (previous.DrawsContent() != repainted.DrawsContent()) - return true; - // Debugging for https://crbug.com/1237389 and https://crbug.com/1230104. // Before returning that a full update is not needed, check that the // properties are changed, which would indicate a missing call to @@ -479,10 +472,10 @@ if (num_previous_siblings > 2) return false; if (num_previous_siblings == 2 && - pending_layers_[first_layer_in_parent_group_index].DrawsContent()) + pending_layers_[first_layer_in_parent_group_index].MayDrawContent()) return false; const auto& previous_sibling = pending_layers_[layer_index - 1]; - if (previous_sibling.DrawsContent() && + if (previous_sibling.MayDrawContent() && !previous_sibling.CanMerge(layer, *upcast_state, prefers_lcd_text_)) return false; } @@ -935,8 +928,7 @@ } else { content_layer_client.UpdateCcPictureLayer( pending_layer.Chunks(), pending_layer.LayerOffset(), - pending_layer.LayerBounds(), pending_layer.GetPropertyTreeState(), - pending_layer.DrawsContent()); + pending_layer.LayerBounds(), pending_layer.GetPropertyTreeState()); } }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc index 0ced152..52052b0d 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -81,7 +81,6 @@ : bounds_(first_chunk.bounds), rect_known_to_be_opaque_(first_chunk.rect_known_to_be_opaque), has_text_(first_chunk.has_text), - draws_content_(first_chunk.DrawsContent()), text_known_to_be_on_opaque_background_( first_chunk.text_known_to_be_on_opaque_background), chunks_(&chunks.GetPaintArtifact(), first_chunk_index_in_paint_artifact), @@ -199,6 +198,10 @@ return *chunks_.begin().DisplayItems().begin(); } +bool PendingLayer::MayDrawContent() const { + return Chunks().size() > 1 || FirstPaintChunk().size() > 0; +} + // We will only allow merging if // merged_area - (home_area + guest_area) <= kMergeSparsityAreaTolerance static constexpr float kMergeSparsityAreaTolerance = 10000; @@ -232,7 +235,6 @@ rect_known_to_be_opaque_.Contains(bounds_)) { if (!dry_run) { chunks_.Merge(guest.Chunks()); - draws_content_ |= guest.draws_content_; text_known_to_be_on_opaque_background_ = true; has_text_ |= guest.has_text_; change_of_decomposited_transforms_ = @@ -287,7 +289,6 @@ chunks_.Merge(guest.Chunks()); bounds_ = merged_bounds; property_tree_state_ = *merged_state; - draws_content_ |= guest.draws_content_; rect_known_to_be_opaque_ = merged_rect_known_to_be_opaque; text_known_to_be_on_opaque_background_ = merged_text_known_to_be_on_opaque_background;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h index c046bef..b3fe83774 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
@@ -93,7 +93,7 @@ std::unique_ptr<JSONObject> ToJSON() const; - bool DrawsContent() const { return draws_content_; } + bool MayDrawContent() const; bool RequiresOwnLayer() const { return compositing_type_ != kOverlap && compositing_type_ != kOther; @@ -124,7 +124,6 @@ gfx::RectF bounds_; gfx::RectF rect_known_to_be_opaque_; bool has_text_ = false; - bool draws_content_ = false; bool text_known_to_be_on_opaque_background_ = false; PaintChunkSubset chunks_; PropertyTreeState property_tree_state_;
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.h b/third_party/blink/renderer/platform/graphics/paint/display_item.h index c3c9690..cca0e2d7 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -296,7 +296,7 @@ const gfx::Rect& visual_rect, RasterEffectOutset raster_effect_outset, PaintInvalidationReason paint_invalidation_reason, - bool draws_content) + bool draws_content = false) : client_id_(client_id), visual_rect_(visual_rect), fragment_(0),
diff --git a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc index 194ea0c..b6f3350d 100644 --- a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -25,8 +25,7 @@ type, gfx::Rect(origin, layer->bounds()), outset, - paint_invalidation_reason, - /*draws_content*/ true), + paint_invalidation_reason), layer_(std::move(layer)) { DCHECK(IsForeignLayerType(type)); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h index 7c85618..befb0cb 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
@@ -6,13 +6,13 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GEOMETRY_MAPPER_H_ #include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h" #include "third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" @@ -96,9 +96,9 @@ rect = Matrix().MapRect(rect); } - void MapQuad(FloatQuad& quad) const { + void MapQuad(gfx::QuadF& quad) const { if (LIKELY(IsIdentityOr2DTranslation())) - quad.Move(Translation2D().x(), Translation2D().y()); + quad += Translation2D(); else quad = Matrix().MapQuad(quad); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h index 4de8a024..a7ea8f3a 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h +++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
@@ -112,10 +112,6 @@ return *layer_selection_data; } - bool DrawsContent() const { - return !effectively_invisible && !drawable_bounds.IsEmpty(); - } - size_t MemoryUsageInBytes() const; // The no-argument version is for operator<< which is used in DCHECK and unit
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc index c5a7e57..811896e 100644 --- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -182,7 +182,6 @@ .Chunk(2) .Chunk(1) .Bounds(gfx::Rect(11, 22, 33, 44)) - .DrawableBounds(gfx::Rect(11, 22, 33, 44)) .Build()); invalidator_.Generate(base::DoNothing(), new_chunks, kDefaultLayerOffset, kDefaultLayerBounds, DefaultPropertyTreeState()); @@ -214,7 +213,6 @@ .IsMovedFromCachedSubsequence() .Chunk(1) .Bounds(gfx::Rect(11, 22, 33, 44)) - .DrawableBounds(gfx::Rect(11, 22, 33, 44)) .Chunk(2) .Build()); invalidator_.Generate(base::DoNothing(), new_chunks, kDefaultLayerOffset, @@ -401,17 +399,14 @@ auto clip1 = CreateClip(*clip0, t0(), clip_rect); PropertyTreeState layer_state = PropertyTreeState::Root(); - PaintChunkSubset chunks( - TestPaintArtifact() - .Chunk(0) - .Properties(t0(), *clip0, e0()) - .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .DrawableBounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .Chunk(1) - .Properties(t0(), *clip1, e0()) - .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .DrawableBounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .Build()); + PaintChunkSubset chunks(TestPaintArtifact() + .Chunk(0) + .Properties(t0(), *clip0, e0()) + .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) + .Chunk(1) + .Properties(t0(), *clip1, e0()) + .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) + .Build()); invalidator_.Generate(base::DoNothing(), chunks, kDefaultLayerOffset, kDefaultLayerBounds, layer_state); @@ -467,14 +462,12 @@ auto c1 = CreateClip(c0(), t0(), clip_rect); PropertyTreeState layer_state = PropertyTreeState::Root(); - PaintChunkSubset chunks( - TestPaintArtifact() - .Chunk(0) - .Properties(t0(), *c1, e0()) - .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .DrawableBounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .IsMovedFromCachedSubsequence() - .Build()); + PaintChunkSubset chunks(TestPaintArtifact() + .Chunk(0) + .Properties(t0(), *c1, e0()) + .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) + .IsMovedFromCachedSubsequence() + .Build()); invalidator_.Generate(base::DoNothing(), chunks, kDefaultLayerOffset, kDefaultLayerBounds, layer_state); @@ -511,7 +504,6 @@ .Chunk(0) .Properties(t0(), *clip, e0()) .Bounds(gfx::ToEnclosingRect(clip_rect.Rect())) - .DrawableBounds(gfx::ToEnclosingRect(clip_rect.Rect())) .SetRasterEffectOutset(RasterEffectOutset::kWholePixel) .Build()); @@ -733,7 +725,6 @@ .Chunk(0) .Properties(*chunk_transform, c0(), e0()) .Bounds(chunk_bounds) - .DrawableBounds(chunk_bounds) .Build()); invalidator_.Generate(base::DoNothing(), chunks, kDefaultLayerOffset,
diff --git a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc index 87cf8d77..268d098 100644 --- a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -642,9 +642,10 @@ switch (info_.jpeg_color_space) { case JCS_YCbCr: - FALLTHROUGH; // libjpeg can convert YCbCr image pixels to RGB. + [[fallthrough]]; // libjpeg can convert YCbCr image pixels to RGB. case JCS_GRAYSCALE: - FALLTHROUGH; // libjpeg can convert GRAYSCALE image pixels to RGB. + [[fallthrough]]; // libjpeg can convert GRAYSCALE image pixels to + // RGB. case JCS_RGB: info_.out_color_space = rgbOutputColorSpace(); break; @@ -769,7 +770,7 @@ return true; } } - FALLTHROUGH; + [[fallthrough]]; case kJpegStartDecompress: if (decoding_mode == JPEGImageDecoder::DecodingMode::kDecodeToYuv) { DCHECK(decoder_->CanDecodeToYUV()); @@ -808,7 +809,7 @@ // If this is a progressive JPEG ... state_ = (info_.buffered_image) ? kJpegDecompressProgressive : kJpegDecompressSequential; - FALLTHROUGH; + [[fallthrough]]; case kJpegDecompressSequential: if (state_ == kJpegDecompressSequential) { @@ -819,7 +820,7 @@ DCHECK_EQ(info_.output_scanline, info_.output_height); state_ = kJpegDone; } - FALLTHROUGH; + [[fallthrough]]; case kJpegDecompressProgressive: if (state_ == kJpegDecompressProgressive) { @@ -900,7 +901,7 @@ state_ = kJpegDone; } - FALLTHROUGH; + [[fallthrough]]; case kJpegDone: // Finish decompression.
diff --git a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc index 93e2f5e..f9178c2 100644 --- a/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
@@ -794,7 +794,7 @@ ApplyPostProcessing(frame_index); return false; } - FALLTHROUGH; + [[fallthrough]]; default: Clear(); return SetFailed();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index fc75a8ed..dca16f4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -137,7 +137,7 @@ return ResourceLoadPriority::kVeryHigh; case ResourceType::kXSLStyleSheet: DCHECK(RuntimeEnabledFeatures::XSLTEnabled()); - FALLTHROUGH; + [[fallthrough]]; case ResourceType::kRaw: case ResourceType::kScript: // Also visible resources/images (set explicitly in loadPriority) @@ -295,7 +295,7 @@ switch (type) { case ResourceType::kXSLStyleSheet: DCHECK(RuntimeEnabledFeatures::XSLTEnabled()); - FALLTHROUGH; + [[fallthrough]]; case ResourceType::kCSSStyleSheet: return mojom::blink::RequestContextType::STYLE; case ResourceType::kScript: @@ -332,7 +332,7 @@ switch (type) { case ResourceType::kXSLStyleSheet: DCHECK(RuntimeEnabledFeatures::XSLTEnabled()); - FALLTHROUGH; + [[fallthrough]]; case ResourceType::kCSSStyleSheet: return network::mojom::RequestDestination::kStyle; case ResourceType::kScript: @@ -1073,7 +1073,7 @@ switch (policy) { case RevalidationPolicy::kReload: GetMemoryCache()->Remove(resource); - FALLTHROUGH; + [[fallthrough]]; case RevalidationPolicy::kLoad: resource = CreateResourceForLoading(params, factory); break;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc index 1de05cb..dcba614ca 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
@@ -983,7 +983,7 @@ case network::mojom::RequestDestination::kFrame: case network::mojom::RequestDestination::kFencedframe: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case network::mojom::RequestDestination::kEmpty: case network::mojom::RequestDestination::kAudio:
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc index f11f568..c50a5f3 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc
@@ -318,10 +318,10 @@ max_pending_buffer_count_(kAbsoluteMaxPendingBuffers) { DVLOG(1) << __func__; // Default to hw-accelerated decoder, in case something checks before decoding - // a frame. It's unclear what we should report in the long run, but for now, + // a frame. It's unclear what we should report in the long run, but for now, // it's better to report hardware since that's all we support anyway. decoder_info_.implementation_name = kExternalDecoderName; - decoder_info_.is_hardware_accelerated = false; + decoder_info_.is_hardware_accelerated = true; DETACH_FROM_SEQUENCE(decoding_sequence_checker_); // This is normally constructed on the media thread, but the first one is // constructed immediately so that we can post to the media thread.
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index dadde50..3824320e 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1083,6 +1083,9 @@ status: "experimental", }, { + name: "FirstPartySets", + }, + { name: "Fledge", origin_trial_feature_name: "Fledge", }, @@ -1171,10 +1174,7 @@ }, { name: "HandwritingRecognition", - status: "experimental", - // Trial also requires kHandwritingRecognitionWebPlatformApiFinch enabled. - origin_trial_feature_name: "HandwritingRecognition", - origin_trial_os: ["chromeos"] + status: {"ChromeOS": "stable", "Lacros": "stable", "default": "experimental"}, }, { name: "HighlightAPI",
diff --git a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc index 0a7774c..19d39eb 100644 --- a/third_party/blink/renderer/platform/testing/test_paint_artifact.cc +++ b/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
@@ -33,9 +33,7 @@ // invalidation rects of chunks. The actual values don't matter. If the chunk // has display items, we will recalculate the bounds from the display items // when constructing the PaintArtifact. - gfx::Rect bounds(id * 110, id * 220, id * 220 + 200, id * 110 + 200); - Bounds(bounds); - DrawableBounds(bounds); + Bounds(gfx::Rect(id * 110, id * 220, id * 220 + 200, id * 110 + 200)); return *this; } @@ -155,6 +153,7 @@ TestPaintArtifact& TestPaintArtifact::Bounds(const gfx::Rect& bounds) { auto& chunk = paint_artifact_->PaintChunks().back(); chunk.bounds = bounds; + chunk.drawable_bounds = bounds; return *this; }
diff --git a/third_party/blink/renderer/platform/text/bidi_resolver.h b/third_party/blink/renderer/platform/text/bidi_resolver.h index cf62f25ea5..5e0deb2 100644 --- a/third_party/blink/renderer/platform/text/bidi_resolver.h +++ b/third_party/blink/renderer/platform/text/bidi_resolver.h
@@ -1019,7 +1019,7 @@ case WTF::unicode::kCommonNumberSeparator: if (status_.eor == WTF::unicode::kEuropeanNumber) break; - FALLTHROUGH; + [[fallthrough]]; case WTF::unicode::kEuropeanNumberTerminator: case WTF::unicode::kBoundaryNeutral: case WTF::unicode::kBlockSeparator: @@ -1074,7 +1074,7 @@ direction_ = WTF::unicode::kLeftToRight; break; } - FALLTHROUGH; + [[fallthrough]]; case WTF::unicode::kArabicNumber: dir_current = WTF::unicode::kArabicNumber; switch (status_.last) { @@ -1093,7 +1093,7 @@ case WTF::unicode::kCommonNumberSeparator: if (status_.eor == WTF::unicode::kArabicNumber) break; - FALLTHROUGH; + [[fallthrough]]; case WTF::unicode::kEuropeanNumberSeparator: case WTF::unicode::kEuropeanNumberTerminator: case WTF::unicode::kBoundaryNeutral:
diff --git a/third_party/blink/renderer/platform/text/date_components.cc b/third_party/blink/renderer/platform/text/date_components.cc index 2ab5c289..ffc58d55 100644 --- a/third_party/blink/renderer/platform/text/date_components.cc +++ b/third_party/blink/renderer/platform/text/date_components.cc
@@ -525,7 +525,7 @@ switch (effective_format) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case kNone: return String::Format("%02d:%02d", hour_, minute_); case kSecond:
diff --git a/third_party/blink/renderer/platform/text/layout_locale.cc b/third_party/blink/renderer/platform/text/layout_locale.cc index 8514847..af9e381 100644 --- a/third_party/blink/renderer/platform/text/layout_locale.cc +++ b/third_party/blink/renderer/platform/text/layout_locale.cc
@@ -240,7 +240,7 @@ switch (mode) { default: NOTREACHED(); - FALLTHROUGH; + [[fallthrough]]; case LineBreakIteratorMode::kDefault: // nullptr will cause any existing values to be removed. break;
diff --git a/third_party/blink/renderer/platform/theme/web_theme_engine_android.cc b/third_party/blink/renderer/platform/theme/web_theme_engine_android.cc index 8fab52e..7ca495e 100644 --- a/third_party/blink/renderer/platform/theme/web_theme_engine_android.cc +++ b/third_party/blink/renderer/platform/theme/web_theme_engine_android.cc
@@ -86,7 +86,7 @@ native_theme_extra_params->slider.zoom = extra_params->slider.zoom; native_theme_extra_params->slider.right_to_left = extra_params->slider.right_to_left; - FALLTHROUGH; + [[fallthrough]]; case WebThemeEngine::kPartSliderThumb: native_theme_extra_params->slider.vertical = extra_params->slider.vertical;
diff --git a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc index db93d71..0ebcfce 100644 --- a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc +++ b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc
@@ -109,7 +109,7 @@ native_theme_extra_params->slider.zoom = extra_params->slider.zoom; native_theme_extra_params->slider.right_to_left = extra_params->slider.right_to_left; - FALLTHROUGH; + [[fallthrough]]; // vertical and in_drag properties are used by both slider track and // slider thumb. case WebThemeEngine::kPartSliderThumb:
diff --git a/third_party/blink/renderer/platform/transforms/affine_transform.cc b/third_party/blink/renderer/platform/transforms/affine_transform.cc index 38d9d76..02f2b8c1 100644 --- a/third_party/blink/renderer/platform/transforms/affine_transform.cc +++ b/third_party/blink/renderer/platform/transforms/affine_transform.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/renderer/platform/transforms/affine_transform.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -289,10 +288,7 @@ return mapped_rect; } - // Still use FloatQuad because FloatQuad::BoundingBox() clamp to int range, - // which is required by some callers. - // TODO(crbug.com/738465): Find a way to use gfx types. - FloatQuad result; + gfx::QuadF result; result.set_p1(MapPoint(rect.origin())); result.set_p2(MapPoint(rect.top_right())); result.set_p3(MapPoint(rect.bottom_right())); @@ -300,10 +296,6 @@ return result.BoundingBox(); } -FloatQuad AffineTransform::MapQuad(const FloatQuad& q) const { - return FloatQuad(MapQuad(ToGfxQuadF(q))); -} - gfx::QuadF AffineTransform::MapQuad(const gfx::QuadF& q) const { if (IsIdentityOrTranslation()) { return q + gfx::Vector2dF(ClampTo<float>(transform_[4]),
diff --git a/third_party/blink/renderer/platform/transforms/affine_transform.h b/third_party/blink/renderer/platform/transforms/affine_transform.h index 5bf4f20..635d1e1 100644 --- a/third_party/blink/renderer/platform/transforms/affine_transform.h +++ b/third_party/blink/renderer/platform/transforms/affine_transform.h
@@ -42,7 +42,6 @@ namespace blink { -class FloatQuad; class TransformationMatrix; #define IDENTITY_TRANSFORM \ @@ -75,9 +74,7 @@ gfx::Rect MapRect(const gfx::Rect&) const; gfx::RectF MapRect(const gfx::RectF&) const; - gfx::QuadF MapQuad(const gfx::QuadF&) const; - FloatQuad MapQuad(const FloatQuad&) const; bool IsIdentity() const;
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc index 334b3c8..9ff2604 100644 --- a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc +++ b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
@@ -32,7 +32,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" -#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -40,6 +39,7 @@ #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "ui/gfx/geometry/box_f.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/quaternion.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -868,8 +868,8 @@ return gfx::PointF(static_cast<float>(out_x), static_cast<float>(out_y)); } -FloatQuad TransformationMatrix::ProjectQuad(const FloatQuad& q) const { - FloatQuad projected_quad; +gfx::QuadF TransformationMatrix::ProjectQuad(const gfx::QuadF& q) const { + gfx::QuadF projected_quad; bool clamped1 = false; bool clamped2 = false; @@ -885,7 +885,7 @@ // visible to the projected surface. bool everything_was_clipped = clamped1 && clamped2 && clamped3 && clamped4; if (everything_was_clipped) - return FloatQuad(); + return gfx::QuadF(); return projected_quad; } @@ -897,7 +897,7 @@ } LayoutRect TransformationMatrix::ClampedBoundsOfProjectedQuad( - const FloatQuad& q) const { + const gfx::QuadF& q) const { gfx::RectF mapped_quad_bounds = ProjectQuad(q).BoundingBox(); float left = ClampEdgeValue(floorf(mapped_quad_bounds.x())); @@ -977,7 +977,7 @@ return mapped_rect; } - FloatQuad result; + gfx::QuadF result; float max_x = r.right(); float max_y = r.bottom(); @@ -989,15 +989,13 @@ return result.BoundingBox(); } -FloatQuad TransformationMatrix::MapQuad(const FloatQuad& q) const { +gfx::QuadF TransformationMatrix::MapQuad(const gfx::QuadF& q) const { if (IsIdentityOrTranslation()) { - FloatQuad mapped_quad(q); - mapped_quad.Move(static_cast<float>(matrix_[3][0]), - static_cast<float>(matrix_[3][1])); - return mapped_quad; + return q + gfx::Vector2dF(ClampTo<float>(matrix_[3][0]), + ClampTo<float>(matrix_[3][1])); } - FloatQuad result; + gfx::QuadF result; result.set_p1(InternalMapPoint(q.p1())); result.set_p2(InternalMapPoint(q.p2())); result.set_p3(InternalMapPoint(q.p3()));
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix.h b/third_party/blink/renderer/platform/transforms/transformation_matrix.h index 03ee6b4..d24459c 100644 --- a/third_party/blink/renderer/platform/transforms/transformation_matrix.h +++ b/third_party/blink/renderer/platform/transforms/transformation_matrix.h
@@ -46,6 +46,7 @@ namespace gfx { class BoxF; class PointF; +class QuadF; class Rect; class RectF; class Transform; @@ -55,7 +56,6 @@ class AffineTransform; class LayoutRect; -class FloatQuad; class JSONArray; struct Rotation; @@ -220,7 +220,7 @@ // If the matrix has 3D components, the z component of the result is // dropped, effectively projecting the quad into the z=0 plane - FloatQuad MapQuad(const FloatQuad&) const; + gfx::QuadF MapQuad(const gfx::QuadF&) const; // Map a point on the z=0 plane into a point on the plane with with the // transform applied, by extending a ray perpendicular to the source plane and @@ -228,10 +228,10 @@ // with the destination plane. gfx::PointF ProjectPoint(const gfx::PointF&, bool* clamped = nullptr) const; // Projects the four corners of the quad. - FloatQuad ProjectQuad(const FloatQuad&) const; + gfx::QuadF ProjectQuad(const gfx::QuadF&) const; // Projects the four corners of the quad and takes a bounding box, // while sanitizing values created when the w component is negative. - LayoutRect ClampedBoundsOfProjectedQuad(const FloatQuad&) const; + LayoutRect ClampedBoundsOfProjectedQuad(const gfx::QuadF&) const; void TransformBox(gfx::BoxF&) const;
diff --git a/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc b/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc index abbebec..c6cc62e 100644 --- a/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc +++ b/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc
@@ -389,7 +389,7 @@ switch (state) { case UpdateState::kIsPasting: widget->set_is_pasting(true); - FALLTHROUGH; // Set both + [[fallthrough]]; // Set both case UpdateState::kIsSelectingRange: widget->set_handling_select_range(true); break;
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc index 5fc27592..469d6671 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -697,7 +697,11 @@ case WebInputEvent::Type::kGesturePinchBegin: { DCHECK(!gesture_pinch_in_progress_); - input_handler_->PinchGestureBegin(); + const WebGestureEvent& gesture_event = + static_cast<const WebGestureEvent&>(event); + input_handler_->PinchGestureBegin( + gfx::ToFlooredPoint(gesture_event.PositionInWidget()), + GestureScrollInputType(gesture_event.SourceDevice())); gesture_pinch_in_progress_ = true; return DID_HANDLE; } @@ -708,8 +712,7 @@ const WebGestureEvent& gesture_event = static_cast<const WebGestureEvent&>(event); input_handler_->PinchGestureEnd( - gfx::ToFlooredPoint(gesture_event.PositionInWidget()), - gesture_event.SourceDevice() == WebGestureDevice::kTouchpad); + gfx::ToFlooredPoint(gesture_event.PositionInWidget())); return DID_HANDLE; } @@ -1479,9 +1482,9 @@ void InputHandlerProxy::SynchronouslyZoomBy(float magnify_delta, const gfx::Point& anchor) { DCHECK(synchronous_input_handler_); - input_handler_->PinchGestureBegin(); + input_handler_->PinchGestureBegin(anchor, ui::ScrollInputType::kTouchscreen); input_handler_->PinchGestureUpdate(magnify_delta, anchor); - input_handler_->PinchGestureEnd(anchor, false); + input_handler_->PinchGestureEnd(anchor); } bool InputHandlerProxy::GetSnapFlingInfoAndSetAnimatingSnapTarget( @@ -1564,7 +1567,7 @@ DCHECK_NE(*currently_active_gesture_device_, WebGestureDevice::kUninitialized); if (gesture_pinch_in_progress_) { - input_handler_->PinchGestureEnd(gfx::ToFlooredPoint(position), true); + input_handler_->PinchGestureEnd(gfx::ToFlooredPoint(position)); } if (handling_gesture_on_impl_thread_) { input_handler_->RecordScrollEnd(
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc index a46ba2a..f045b6c 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -92,10 +92,11 @@ return weak_ptr_factory_.GetWeakPtr(); } - MOCK_METHOD0(PinchGestureBegin, void()); + MOCK_METHOD2(PinchGestureBegin, + void(const gfx::Point& anchor, ui::ScrollInputType type)); MOCK_METHOD2(PinchGestureUpdate, void(float magnify_delta, const gfx::Point& anchor)); - MOCK_METHOD2(PinchGestureEnd, void(const gfx::Point& anchor, bool snap)); + MOCK_METHOD1(PinchGestureEnd, void(const gfx::Point& anchor)); MOCK_METHOD0(SetNeedsAnimateInput, void()); @@ -1132,7 +1133,7 @@ VERIFY_AND_RESET_MOCKS(); gesture_.SetType(WebInputEvent::Type::kGesturePinchBegin); - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); EXPECT_EQ(expected_disposition_, HandleInputEventAndFlushEventQueue(mock_input_handler_, input_handler_.get(), gesture_)); @@ -1160,7 +1161,7 @@ VERIFY_AND_RESET_MOCKS(); gesture_.SetType(WebInputEvent::Type::kGesturePinchEnd); - EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point(9, 6), true)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point(9, 6))); EXPECT_EQ(expected_disposition_, HandleInputEventAndFlushEventQueue(mock_input_handler_, input_handler_.get(), gesture_)); @@ -1205,7 +1206,7 @@ VERIFY_AND_RESET_MOCKS(); gesture_.SetType(WebInputEvent::Type::kGesturePinchBegin); - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); EXPECT_EQ(expected_disposition_, HandleInputEventAndFlushEventQueue(mock_input_handler_, input_handler_.get(), gesture_)); @@ -1251,7 +1252,7 @@ VERIFY_AND_RESET_MOCKS(); gesture_.SetType(WebInputEvent::Type::kGesturePinchEnd); - EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point(9, 6), true)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point(9, 6))); EXPECT_EQ(expected_disposition_, HandleInputEventAndFlushEventQueue(mock_input_handler_, input_handler_.get(), gesture_)); @@ -2682,11 +2683,11 @@ EXPECT_CALL(mock_input_handler_, FindFrameElementIdAtPoint(_)) .Times(8) .WillRepeatedly(testing::Return(cc::ElementId())); - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); // Two |GesturePinchUpdate| will be coalesced. EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(0.7f, gfx::Point(13, 17))); - EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point(), false)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(gfx::Point())); EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(2); HandleGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, -30); @@ -2830,7 +2831,7 @@ } TEST_F(InputHandlerProxyEventQueueTest, VSyncAlignedCoalesceTouchpadPinch) { - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()); EXPECT_CALL(mock_input_handler_, FindFrameElementIdAtPoint(_)) .Times(1) @@ -2893,9 +2894,9 @@ .Times(::testing::AtLeast(1)); EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(2); - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(_, _)); - EXPECT_CALL(mock_input_handler_, PinchGestureEnd(_, _)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(_)); trace_analyzer::Start("*"); // Simulate scroll. @@ -3115,9 +3116,9 @@ EXPECT_EQ(false, latency_info_recorder_[2].coalesced()); // pinch start, handle scroll and pinch on compositor. - EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin(_, _)); EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(_, _)); - EXPECT_CALL(mock_input_handler_, PinchGestureEnd(_, _)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(_)); HandleGestureEvent(WebInputEvent::Type::kGesturePinchBegin); HandleGestureEvent(WebInputEvent::Type::kGesturePinchUpdate, 10.0f, 1, 10);
diff --git a/third_party/blink/renderer/platform/wtf/text/utf8.cc b/third_party/blink/renderer/platform/wtf/text/utf8.cc index 16eb886..50a7cf0 100644 --- a/third_party/blink/renderer/platform/wtf/text/utf8.cc +++ b/third_party/blink/renderer/platform/wtf/text/utf8.cc
@@ -92,7 +92,7 @@ case 2: *--target = (char)((ch | kByteMark) & kByteMask); ch >>= 6; - FALLTHROUGH; + [[fallthrough]]; case 1: *--target = (char)(ch | kFirstByteMark[bytes_to_write]); } @@ -171,15 +171,15 @@ case 4: *--target = (char)((ch | kByteMark) & kByteMask); ch >>= 6; - FALLTHROUGH; + [[fallthrough]]; case 3: *--target = (char)((ch | kByteMark) & kByteMask); ch >>= 6; - FALLTHROUGH; + [[fallthrough]]; case 2: *--target = (char)((ch | kByteMark) & kByteMask); ch >>= 6; - FALLTHROUGH; + [[fallthrough]]; case 1: *--target = (char)(ch | kFirstByteMark[bytes_to_write]); } @@ -202,11 +202,11 @@ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - FALLTHROUGH; + [[fallthrough]]; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - FALLTHROUGH; + [[fallthrough]]; case 2: if ((a = (*--srcptr)) > 0xBF) return false; @@ -233,7 +233,7 @@ if (a < 0x80) return false; } - FALLTHROUGH; + [[fallthrough]]; case 1: if (*source >= 0x80 && *source < 0xC2) @@ -261,23 +261,23 @@ case 6: character += static_cast<unsigned char>(*sequence++); character <<= 6; - FALLTHROUGH; + [[fallthrough]]; case 5: character += static_cast<unsigned char>(*sequence++); character <<= 6; - FALLTHROUGH; + [[fallthrough]]; case 4: character += static_cast<unsigned char>(*sequence++); character <<= 6; - FALLTHROUGH; + [[fallthrough]]; case 3: character += static_cast<unsigned char>(*sequence++); character <<= 6; - FALLTHROUGH; + [[fallthrough]]; case 2: character += static_cast<unsigned char>(*sequence++); character <<= 6; - FALLTHROUGH; + [[fallthrough]]; case 1: character += static_cast<unsigned char>(*sequence++); }
diff --git a/third_party/blink/tools/apache_config/apache2-httpd-2.4-prefork.conf b/third_party/blink/tools/apache_config/apache2-httpd-2.4-prefork.conf new file mode 100644 index 0000000..d139d1b --- /dev/null +++ b/third_party/blink/tools/apache_config/apache2-httpd-2.4-prefork.conf
@@ -0,0 +1,151 @@ +ServerTokens Prod +Mutex file:/tmp/WebKit +PidFile "/tmp/WebKit/httpd.pid" +ScoreBoardFile "/tmp/WebKit/httpd.scoreboard" + +Timeout 300 +KeepAlive On +# Setting this value too low may change header size sometimes making flakey tests. +MaxKeepAliveRequests 0 +KeepAliveTimeout 9999 + +MaxRequestWorkers 150 +MaxConnectionsPerChild 100000 + +LoadModule mpm_prefork_module libexec/apache2/mod_mpm_prefork.so +LoadModule unixd_module libexec/apache2/mod_unixd.so +LoadModule access_compat_module libexec/apache2/mod_access_compat.so +LoadModule authz_core_module libexec/apache2/mod_authz_core.so +LoadModule authz_host_module libexec/apache2/mod_authz_host.so +LoadModule include_module libexec/apache2/mod_include.so +LoadModule log_config_module libexec/apache2/mod_log_config.so +LoadModule headers_module libexec/apache2/mod_headers.so +LoadModule ssl_module libexec/apache2/mod_ssl.so +LoadModule mime_module libexec/apache2/mod_mime.so +LoadModule asis_module libexec/apache2/mod_asis.so +LoadModule cgi_module libexec/apache2/mod_cgi.so +LoadModule env_module libexec/apache2/mod_env.so +LoadModule negotiation_module libexec/apache2/mod_negotiation.so +LoadModule imagemap_module libexec/apache2/mod_imagemap.so +LoadModule actions_module libexec/apache2/mod_actions.so +LoadModule alias_module libexec/apache2/mod_alias.so +LoadModule rewrite_module libexec/apache2/mod_rewrite.so +LoadModule autoindex_module libexec/apache2/mod_autoindex.so + +ServerName 127.0.0.1 + +<Directory /> + Options Indexes FollowSymLinks MultiViews ExecCGI Includes + AllowOverride All + Order allow,deny + Allow from all +</Directory> + +AccessFileName .htaccess + +<Files ~ "^\.([Hh][Tt]|[Dd][Ss]_[Ss])"> + Order allow,deny + Deny from all + Satisfy All +</Files> + +UseCanonicalName On +HostnameLookups Off + +PassEnv TMPDIR + +LogLevel warn + +ErrorLog "/tmp/WebKit/error_log" + +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %b" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +ServerSignature On + +AddLanguage da .dk +AddLanguage nl .nl +AddLanguage en .en +AddLanguage et .ee +AddLanguage fr .fr +AddLanguage de .de +AddLanguage el .el +AddLanguage he .he +AddCharset ISO-8859-8 .iso8859-8 +AddLanguage it .it +AddLanguage ja .ja +AddCharset ISO-2022-JP .jis +AddLanguage kr .kr +AddCharset ISO-2022-KR .iso-kr +AddLanguage nn .nn +AddLanguage no .no +AddLanguage pl .po +AddCharset ISO-8859-2 .iso-pl +AddLanguage pt .pt +AddLanguage pt-br .pt-br +AddLanguage ltz .lu +AddLanguage ca .ca +AddLanguage es .es +AddLanguage sv .sv +AddLanguage cs .cz .cs +AddLanguage ru .ru +AddLanguage zh-TW .zh-tw +AddCharset Big5 .Big5 .big5 +AddCharset WINDOWS-1251 .cp-1251 +AddCharset CP866 .cp866 +AddCharset ISO-8859-5 .iso-ru +AddCharset KOI8-R .koi8-r +AddCharset UCS-2 .ucs2 +AddCharset UCS-4 .ucs4 +AddCharset UTF-8 .utf8 + +<IfModule mod_negotiation.c> + LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ru ltz ca es sv tw +</IfModule> + +AddType application/x-tar .tgz + +AddEncoding x-compress .Z +AddEncoding x-gzip .gz .tgz + +AddHandler cgi-script .cgi .pl + +AddType text/html .shtml +AddHandler server-parsed .shtml + +AddHandler send-as-is asis + +AddType application/x-httpd-php .php +AddType application/x-httpd-php .bat +AddType application/x-httpd-php-source .phps + +<IfModule mod_dir.c> + DirectoryIndex index.html index.php +</IfModule> + + +RewriteEngine On +RewriteCond %{REQUEST_METHOD} ^TRACE +RewriteRule .* - [F] + +<VirtualHost *:8443> + ServerName 127.0.0.1 + SSLEngine On +</VirtualHost> + +# +# Apple-specific filesystem protection. +# +<Files "rsrc"> + Order allow,deny + Deny from all + Satisfy All +</Files> + +<Directory ~ ".*\.\.namedfork"> + Order allow,deny + Deny from all + Satisfy All +</Directory>
diff --git a/third_party/blink/tools/blinkpy/common/system/platform_info.py b/third_party/blink/tools/blinkpy/common/system/platform_info.py index 34302cf..17616962 100644 --- a/third_party/blink/tools/blinkpy/common/system/platform_info.py +++ b/third_party/blink/tools/blinkpy/common/system/platform_info.py
@@ -65,6 +65,14 @@ def is_mac(self): return self.os_name == 'mac' + def is_mac_monterey(self): + if not self.is_mac(): + return False + + command = ['sw_vers', '-productVersion'] + version = self._executive.run_command(command).strip() + return version.startswith('12.') + def is_win(self): return self.os_name == 'win'
diff --git a/third_party/blink/tools/blinkpy/common/system/platform_info_mock.py b/third_party/blink/tools/blinkpy/common/system/platform_info_mock.py index c129ee3..4996a75 100644 --- a/third_party/blink/tools/blinkpy/common/system/platform_info_mock.py +++ b/third_party/blink/tools/blinkpy/common/system/platform_info_mock.py
@@ -45,6 +45,9 @@ def is_mac(self): return self.os_name == 'mac' + def is_mac_monterey(self): + return False + def is_linux(self): return self.os_name == 'linux'
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 059ecfe7..ea586fc5 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -47,6 +47,7 @@ 'base::AutoReset', 'base::Contains', 'base::CreateSequencedTaskRunner', + 'base::ValuesEquivalent', 'base::Days', 'base::DefaultTickClock', 'base::ElapsedTimer',
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py index d647b530..4323c8c 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
@@ -357,8 +357,8 @@ def _test_input_for_file(self, test_file, retry_attempt): return TestInput( test_file, - self._options.slow_time_out_ms - if self._test_is_slow(test_file) else self._options.time_out_ms, + self._options.slow_timeout_ms + if self._test_is_slow(test_file) else self._options.timeout_ms, self._test_requires_lock(test_file), retry_attempt=retry_attempt)
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index e586488..5095962 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -412,7 +412,7 @@ """Returns the amount of time in seconds to wait before killing the process in driver.stop().""" # We want to wait for at least 3 seconds, but if we are really slow, we # want to be slow on cleanup as well (for things like ASAN, Valgrind, etc.) - return (3.0 * float(self.get_option('time_out_ms', '0')) / + return (3.0 * float(self.get_option('timeout_ms', '0')) / self._default_timeout_ms()) def default_batch_size(self):
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py b/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py index fff487f..1fd95d9 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py
@@ -348,10 +348,9 @@ # Use Scenic on AEMU else: cmd.extend([ - '--ozone-platform=scenic', '--enable-oop-rasterization', - '--use-vulkan', '--enable-gpu-rasterization', - '--force-device-scale-factor=1', '--use-gl=stub', - '--enable-features=UseSkiaRenderer,Vulkan', + '--ozone-platform=scenic', '--use-vulkan', + '--enable-gpu-rasterization', '--force-device-scale-factor=1', + '--use-gl=stub', '--enable-features=UseSkiaRenderer,Vulkan', '--gpu-watchdog-timeout-seconds=60' ]) return cmd
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/mac.py b/third_party/blink/tools/blinkpy/web_tests/port/mac.py index ccfb560..b1bd7c80 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/mac.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/mac.py
@@ -111,6 +111,12 @@ return '/usr/sbin/httpd' def path_to_apache_config_file(self): + # TODO(crbug.com/1190885): Workaround for Monterey, should be reverted + # once we build chromium specific httpd. + if self.host.platform.is_mac_monterey(): + config_file_name = "apache2-httpd-2.4-prefork.conf" + return self._filesystem.join(self.apache_config_directory(), config_file_name) + config_file_basename = 'apache2-httpd-' + self._apache_version() if self.host.platform.os_version not in ['mac10.12']: config_file_basename += '-php7'
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index 334db23..355122e 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -554,7 +554,7 @@ help='A colon-separated list of tests to run. Wildcards are ' 'NOT supported. It is the same as listing the tests as ' 'positional arguments.'), - optparse.make_option('--time-out-ms', + optparse.make_option('--timeout-ms', help='Set the timeout for each test'), optparse.make_option( '--initialize-webgpu-adapter-at-startup-timeout-ms', @@ -693,10 +693,10 @@ if not options.configuration: options.configuration = port.default_configuration() - if not options.time_out_ms: - options.time_out_ms = str(port.timeout_ms()) + if not options.timeout_ms: + options.timeout_ms = str(port.timeout_ms()) - options.slow_time_out_ms = str(5 * int(options.time_out_ms)) + options.slow_timeout_ms = str(5 * int(options.timeout_ms)) if options.additional_platform_directory: additional_platform_directories = []
diff --git a/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py b/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py index 1cdde24..15f29e2 100644 --- a/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py +++ b/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py
@@ -121,11 +121,13 @@ '-c', 'TypesConfig "%s"' % mime_types_path, '-c', 'CustomLog "%s" common' % self._access_log_path, '-c', 'ErrorLog "%s"' % self._error_log_path, - '-c', 'PHPINIDir "%s"' % php_ini_dir, '-c', 'PidFile %s' % self._pid_file, '-c', 'SSLCertificateFile "%s"' % cert_file, '-c', 'DefaultType None', ] + if not self._port_obj.host.platform.is_mac_monterey(): + start_cmd += ['-c', 'PHPINIDir "%s"' % php_ini_dir] + # yapf: enable if self._is_win:
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/printing.py b/third_party/blink/tools/blinkpy/web_tests/views/printing.py index 9e3490e..576817b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/views/printing.py +++ b/third_party/blink/tools/blinkpy/web_tests/views/printing.py
@@ -116,7 +116,7 @@ self._print_default('Using %s build' % self._options.configuration) self._print_default( 'Regular timeout: %s, slow test timeout: %s' % - (self._options.time_out_ms, self._options.slow_time_out_ms)) + (self._options.timeout_ms, self._options.slow_timeout_ms)) self._print_default('Command line: ' + ' '.join(port.driver_cmd_line()))
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py index 82527735..698fe9f 100644 --- a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
@@ -122,8 +122,8 @@ printer, err = self.get_printer() # FIXME: Make it so these options don't have to be set directly. # pylint: disable=protected-access - printer._options.time_out_ms = 6000 - printer._options.slow_time_out_ms = 12000 + printer._options.timeout_ms = 6000 + printer._options.slow_timeout_ms = 12000 printer._options.order = 'random' printer._options.seed = 1234 printer.print_config(self._port)
diff --git a/third_party/blink/tools/debug_web_tests b/third_party/blink/tools/debug_web_tests index 4cbb498..e9e3bc4 100755 --- a/third_party/blink/tools/debug_web_tests +++ b/third_party/blink/tools/debug_web_tests
@@ -5,7 +5,7 @@ # Runs run-webkit-tests and attaches a debugger to the single renderer process. -DEFAULT_TARGET_FLAGS=(--jobs=1 --time-out-ms=100000000 --additional-driver-flag=--no-sandbox --additional-driver-flag=--renderer-startup-dialog) +DEFAULT_TARGET_FLAGS=(--jobs=1 --timeout-ms=100000000 --additional-driver-flag=--no-sandbox --additional-driver-flag=--renderer-startup-dialog) SAW_DISABLE_FEATURES=false for TARGET_FLAG in "$@"; do
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index 56d7776..7c0e2627 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -144,6 +144,8 @@ crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-066.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-073.html [ Failure ] +crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-079.html [ Failure ] +crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-080.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/overflow-clip-000.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/overflow-clip-001.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/overflow-clip-010.html [ Failure ] @@ -1369,10 +1371,6 @@ ### wpt_internal/webcodecs/ crbug.com/591099 wpt_internal/webcodecs/annexb_decoding.https.any.html [ Failure ] crbug.com/591099 wpt_internal/webcodecs/annexb_decoding.https.any.worker.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/basic_video_encoding.https.any.worker.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/reconfiguring_encoder.https.any.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/reconfiguring_encoder.https.any.worker.html [ Failure ] # broken by https://chromium-review.googlesource.com/c/chromium/src/+/2392444 crbug.com/958381 external/wpt/css/css-flexbox/table-as-item-wide-content.html [ Failure ] @@ -1470,8 +1468,6 @@ crbug.com/591099 virtual/oopr-canvas2d/fast/canvas/image-object-in-canvas.html [ Failure ] crbug.com/591099 virtual/oopr-canvas2d/fast/canvas/patternfill-repeat.html [ Failure ] crbug.com/591099 wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/temporal_svc.https.any.html [ Failure ] -crbug.com/591099 wpt_internal/webcodecs/temporal_svc.https.any.worker.html [ Failure ] crbug.com/591099 external/wpt/css/css-contain/contain-body-t-o-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-contain/contain-body-t-o-002.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/flex-aspect-ratio-img-row-013.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility index 925a411..ef7d46a 100644 --- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility +++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -63,11 +63,4 @@ wpt_internal/webcodecs/annexb_decoding.https.any.html [ Skip ] wpt_internal/webcodecs/annexb_decoding.https.any.worker.html [ Skip ] wpt_internal/webcodecs/avc_encoder_config.https.any.html [ Skip ] -wpt_internal/webcodecs/avc_encoder_config.https.any.worker.html [ Skip ] -wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Skip ] -wpt_internal/webcodecs/basic_video_encoding.https.any.worker.html [ Skip ] -wpt_internal/webcodecs/reconfiguring_encoder.https.any.html [ Skip ] -wpt_internal/webcodecs/reconfiguring_encoder.https.any.worker.html [ Skip ] -crbug.com/1176474 wpt_internal/webcodecs/temporal_svc.https.any.html [ Skip ] -crbug.com/1176474 wpt_internal/webcodecs/temporal_svc.https.any.worker.html [ Skip ] - +wpt_internal/webcodecs/avc_encoder_config.https.any.worker.html [ Skip ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/FlagSpecificConfig b/third_party/blink/web_tests/FlagSpecificConfig index 5cf6cbd..cff0f35 100644 --- a/third_party/blink/web_tests/FlagSpecificConfig +++ b/third_party/blink/web_tests/FlagSpecificConfig
@@ -53,7 +53,6 @@ "--enable-gpu-rasterization", "--enable-features=UseSkiaRenderer", "--use-gl=any", - "--enable-oop-rasterization", "--disable-software-compositing-fallback", "--disable-headless-mode" ] @@ -64,7 +63,6 @@ "--enable-gpu-rasterization", "--enable-features=UseSkiaRenderer,Vulkan", "--use-gl=any", - "--enable-oop-rasterization", "--disable-software-compositing-fallback", "--use-vulkan=native", "--disable-vulkan-fallback-to-gl-for-testing", @@ -76,7 +74,6 @@ "args": [ "--enable-gpu-rasterization", "--enable-features=UseSkiaRenderer,Vulkan", - "--enable-oop-rasterization", "--use-vulkan=swiftshader", "--disable-vulkan-fallback-to-gl-for-testing" ] @@ -129,4 +126,3 @@ ] } ] -
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index fa85f9d..d1034f0 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -740,8 +740,6 @@ crbug.com/1182691 external/wpt/webcodecs/audio-encoder.https.any.html [ Slow ] crbug.com/1182691 external/wpt/webcodecs/video-encoder.https.any.html [ Slow ] crbug.com/1182691 external/wpt/webcodecs/video-encoder.https.any.worker.html [ Slow ] -crbug.com/1176474 wpt_internal/webcodecs/temporal_svc.https.any.html [ Slow ] -crbug.com/1176474 wpt_internal/webcodecs/temporal_svc.https.any.worker.html [ Slow ] # Composited scroll snap is not accelerated for testing. crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-scrollbar-scrolling-arrow.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 6c2c808..84ee924 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -690,8 +690,6 @@ crbug.com/1175040 external/wpt/css/css-backgrounds/background-repeat-space-6.html [ Failure ] crbug.com/1175040 external/wpt/css/css-backgrounds/background-repeat-space-7.html [ Failure ] -crbug.com/667006 external/wpt/css/css-backgrounds/background-attachment-fixed-inside-transform-1.html [ Failure ] - # Bug accidentally masked by using square mask geometry. crbug.com/1155161 svg/masking/mask-of-root.html [ Failure ] @@ -1083,6 +1081,54 @@ crbug.com/1253732 external/wpt/css/css-ui/input-security-none-sensitive-text-input.html [ Failure ] # Layout team disagrees with the spec for this particular test. crbug.com/591099 external/wpt/css/css-ui/text-overflow-015.html [ Failure ] +# Various issues related to the 'appearance' property: +crbug.com/1284269 external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-attachment-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-clip-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-image-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-origin-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-size-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-right-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-end-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-outset-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-repeat-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Crash Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-style-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-width-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-end-radius-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure Timeout ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-color-001.html [ Failure ] +crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-left-radius-001.html [ Failure ] +crbug.com/1284270 external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] + # [css-flexbox] @@ -1178,6 +1224,10 @@ crbug.com/993813 [ Mac ] external/wpt/css/css-overflow/webkit-line-clamp-025.html [ Failure ] crbug.com/993813 external/wpt/css/css-overflow/webkit-line-clamp-029.html [ Failure ] +# Temporary failures while we evaluate the web-compat of adding inline-end padding for overflow. +crbug.com/1245722 external/wpt/css/css-overflow/overflow-padding.html [ Failure ] +crbug.com/1245722 external/wpt/css/css-overflow/orthogonal-flow-with-inline-end-margin.html [ Failure ] + # Lack of support for font-language-override crbug.com/481430 external/wpt/css/css-fonts/font-language-override-01.html [ Failure ] crbug.com/481430 external/wpt/css/css-fonts/font-language-override-02.html [ Failure ] @@ -1688,6 +1738,7 @@ # @container crbug.com/1273913 external/wpt/css/css-contain/container-queries/pseudo-elements-002.tentative.html [ Failure ] +crbug.com/1284918 external/wpt/css/css-contain/container-queries/table-inside-container-changing-display.html [ Failure ] # CSS Scrollbars crbug.com/891944 external/wpt/css/css-scrollbars/textarea-scrollbar-width-none.html [ Failure ] @@ -2964,6 +3015,21 @@ crbug.com/626703 [ Mac11 ] external/wpt/css/css-flexbox/abspos/flex-abspos-staticpos-align-self-006.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac11 ] external/wpt/css/css-color-adjust/inheritance.html [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/private-network-access/fetch.window.html [ Timeout ] +crbug.com/626703 [ Mac11 ] external/wpt/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html [ Crash ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/caption-side-vrl-002.xht [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/float-vrl-002.xht [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/margin-collapse-vlr-037.xht [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/margin-collapse-vrl-008.xht [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/filter-effects/backdrop-filters-sepia.html [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] virtual/not-site-per-process/external/wpt/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html [ Crash ] +crbug.com/626703 [ Mac11-arm64 ] virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-042.html [ Crash ] +crbug.com/626703 [ Mac11-arm64 ] wpt_internal/bluetooth/characteristic/getDescriptors/blocklisted-descriptors-not-present.https.html [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] wpt_internal/css/css-transforms/raster-scale-perspective-001.html [ Crash Failure ] +crbug.com/626703 [ Mac11-arm64 ] wpt_internal/css/selectors/focus-visible-select-001.html [ Crash Failure ] +crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html [ Failure ] crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-constructor-error.https.html [ Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-022.html [ Crash Failure ] crbug.com/626703 external/wpt/css/css-text-decor/text-decoration-dotted-001.html [ Failure ] @@ -2995,169 +3061,11 @@ crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-overflow/scrollbar-gutter-vertical-rl-002.html [ Failure ] crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-overflow/scrollbar-gutter-vertical-rl-002.html [ Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-overflow/scrollbar-gutter-vertical-rl-002.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] crbug.com/626703 [ Mac11-arm64 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomainport.sub.https.html [ Crash Failure ] crbug.com/626703 [ Mac11-arm64 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-yes-subdomain-child2-no-subdomain.sub.https.html [ Crash Failure ] crbug.com/626703 [ Mac11-arm64 ] virtual/plz-dedicated-worker/external/wpt/content-security-policy/inside-worker/serviceworker-report-only.https.sub.html [ Timeout ] crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/color-mix-percents-01.html [ Failure ] crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/color-mix-percents-02.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-fallback-props-revert-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-attachment-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-clip-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-image-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-origin-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-position-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-background-size-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-style-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-end-width-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-style-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-block-start-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-color-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-left-radius-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-right-radius-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-style-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-bottom-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-end-radius-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-end-start-radius-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-outset-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-repeat-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-slice-001.html [ Crash Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-source-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-image-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-style-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-end-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-color-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-style-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-inline-start-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-color-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-style-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-left-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-style-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-right-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-end-radius-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-start-start-radius-001.html [ Failure Timeout ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-color-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-left-radius-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-right-radius-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-style-001.html [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Mac11 ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-width-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/CSS2/normal-flow/width-081.xht [ Crash Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-contain/contain-layout-ignored-cases-no-principal-box-002.html [ Crash Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-writing-modes/margin-collapse-vrl-014.xht [ Crash Failure ] @@ -3710,7 +3618,6 @@ crbug.com/626703 external/wpt/infrastructure/channels/test_serialize.html [ Timeout ] crbug.com/626703 [ Win10.20h2 ] external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https.html [ Failure Timeout ] crbug.com/626703 [ Win10.20h2 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https.html [ Failure Timeout ] -crbug.com/626703 [ Mac ] wpt_internal/webcodecs/basic_video_encoding.https.any.worker.html [ Crash Timeout ] crbug.com/626703 [ Mac10.15 ] virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Skip Timeout ] crbug.com/626703 [ Mac10.12 ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/presentation-receiver.https.html [ Crash Failure ] crbug.com/626703 [ Mac10.12 ] external/wpt/websockets/constructor/009.html?wpt_flags=h2 [ Crash Failure ] @@ -3727,7 +3634,6 @@ crbug.com/626703 [ Mac11-arm64 ] external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html [ Skip Timeout ] crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Skip Timeout ] crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-onsignalingstatechanged.https.html [ Timeout ] -crbug.com/626703 [ Mac11 ] wpt_internal/webcodecs/reconfiguring_encoder.https.any.worker.html [ Timeout ] crbug.com/626703 [ Mac10.15 ] external/wpt/streams/piping/abort.any.html [ Failure Timeout ] crbug.com/626703 [ Mac10.15 ] external/wpt/streams/piping/abort.any.sharedworker.html [ Crash Failure ] crbug.com/626703 [ Mac11-arm64 ] virtual/consume-code-cache-off-thread/external/wpt/html/semantics/scripting-1/the-script-element/json-module/parse-error.html [ Timeout ] @@ -3753,7 +3659,6 @@ crbug.com/626703 [ Mac11 ] virtual/scroll-unification-unified-autoplay/external/wpt/feature-policy/feature-policy-header-policy-declined.https.sub.html [ Timeout ] crbug.com/626703 [ Mac11 ] external/wpt/secure-payment-confirmation/authentication-accepted.https.html [ Failure Timeout ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-004.html [ Failure ] -crbug.com/626703 [ Linux ] wpt_internal/webcodecs/reconfiguring_encoder.https.any.worker.html [ Timeout ] crbug.com/626703 [ Mac10.15 ] external/wpt/page-visibility/minimize.html [ Failure Skip Timeout ] crbug.com/626703 [ Mac10.15 ] virtual/shared_array_buffer_on_desktop/external/wpt/compression/decompression-constructor-error.tentative.any.serviceworker.html [ Timeout ] crbug.com/626703 [ Win10.20h2 ] external/wpt/web-locks/bfcache/abort.tentative.https.html [ Failure Skip Timeout ] @@ -3916,8 +3821,6 @@ crbug.com/626703 [ Mac10.15 ] virtual/no-alloc-direct-call/external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html [ Failure Timeout ] crbug.com/626703 [ Linux ] virtual/plz-dedicated-worker/external/wpt/xhr/event-loadstart-upload.any.worker.html [ Crash ] crbug.com/626703 [ Mac10.15 ] virtual/plz-dedicated-worker/external/wpt/xhr/event-loadstart-upload.any.worker.html [ Crash ] -crbug.com/626703 [ Linux ] wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Timeout ] -crbug.com/626703 [ Mac11 ] wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/cookies/attributes/domain.sub.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/cookies/attributes/domain.sub.html [ Failure ] crbug.com/626703 external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker.html [ Failure ] @@ -6952,11 +6855,6 @@ # Failing css-transforms-2 web platform tests. crbug.com/847356 external/wpt/css/css-transforms/transform-box/view-box-mutation-001.html [ Failure ] -crbug.com/1261900 external/wpt/css/css-transforms/transform-fixed-bg-002.html [ Failure ] -crbug.com/1261900 external/wpt/css/css-transforms/transform-fixed-bg-004.html [ Failure ] -crbug.com/1261900 external/wpt/css/css-transforms/transform-fixed-bg-005.html [ Failure ] -crbug.com/1261900 external/wpt/css/css-transforms/transform-fixed-bg-006.html [ Failure ] -crbug.com/1261900 external/wpt/css/css-transforms/transform-fixed-bg-007.html [ Failure ] # Started failing after rolling new version of check-layout-th.js css3/flexbox/perpendicular-writing-modes-inside-flex-item.html [ Failure ] @@ -7570,9 +7468,6 @@ crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/annexb_decoding.https.any.worker.html [ Failure Pass ] crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/avc_encoder_config.https.any.html [ Failure Pass ] crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/avc_encoder_config.https.any.worker.html [ Failure Pass ] -crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Failure Pass ] -crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/temporal_svc.https.any.html [ Failure Pass ] -crbug.com/1249176 [ Mac11-arm64 ] wpt_internal/webcodecs/temporal_svc.https.any.worker.html [ Failure Pass ] crbug.com/1249176 [ Mac11-arm64 ] external/wpt/webcodecs/audioDecoder-codec-specific.https.any.worker.html?adts_aac [ Pass Timeout ] crbug.com/1249176 [ Mac11-arm64 ] external/wpt/webcodecs/audioDecoder-codec-specific.https.any.worker.html?mp4_aac [ Pass Timeout ] crbug.com/1249176 [ Mac11-arm64 ] external/wpt/webcodecs/videoDecoder-codec-specific.https.any.worker.html?h264_annexb [ Pass Timeout ] @@ -7985,3 +7880,6 @@ # Sheriff 2022-01-04 crbug.com/1283865 external/wpt/webmessaging/without-ports/020.html [ Failure Pass ] + +# Sheriff 2022-01-05 +crbug.com/1284572 [ Linux ] virtual/threaded/http/tests/devtools/isolated-code-cache/same-origin-module-test.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 03f91e36..c00694e 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -58,7 +58,6 @@ "args": ["--enable-threaded-compositing", "--enable-blink-features=OffMainThreadCSSPaint", "--enable-gpu-rasterization", - "--enable-oop-rasterization", "--enable-accelerated-2d-canvas", "--disable-features=CanvasOopRasterization"] }, @@ -832,7 +831,6 @@ "bases": [ "fast/canvas" ], "args": [ "--enable-features=CanvasOopRasterization", "--enable-accelerated-2d-canvas", - "--enable-oop-rasterization", "--enable-gpu-rasterization" ] }, { @@ -1055,7 +1053,7 @@ "wpt_internal/fenced_frame", "http/tests/inspector-protocol/fenced-frame" ], - "args": ["--enable-features=FencedFrames:implementation_type/mparch,Prerender2"] + "args": ["--enable-features=FencedFrames:implementation_type/mparch,Prerender2,PartitionedCookies"] }, { "prefix": "fenced-frame-shadow-dom", @@ -1063,7 +1061,7 @@ "fenced_frame", "wpt_internal/fenced_frame" ], - "args": ["--enable-features=FencedFrames:implementation_type/shadow_dom,Prerender2"] + "args": ["--enable-features=FencedFrames:implementation_type/shadow_dom,Prerender2,PartitionedCookies"] }, { "prefix": "disable-custom-element-default-style",
diff --git a/third_party/blink/web_tests/editing/selection/drag-far-outside-multicol-crash.html b/third_party/blink/web_tests/editing/selection/drag-far-outside-multicol-crash.html new file mode 100644 index 0000000..87eb5afa --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/drag-far-outside-multicol-crash.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<div style="columns:2;"> + <div contenteditable id="container" style="height:100px;"></div> +</div> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + test(()=> { + var y = container.offsetTop; + eventSender.mouseMoveTo(container.offsetLeft, y); + eventSender.mouseDown(); + eventSender.mouseMoveTo(1000000, y); + eventSender.mouseUp(); + }, "no crash or DCHECK failure"); +</script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index f9cabba..c330d691 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -300,6 +300,13 @@ {} ] ], + "auto-overflow-inside-second-abspos-fragment-crash.html": [ + "c4ce36abac8299afe5157705c97b5b693c260e78", + [ + null, + {} + ] + ], "break-before-with-no-fragmentation-crash.html": [ "fb80ec45bceec093481fa54513c606c5952628b1", [ @@ -307,6 +314,20 @@ {} ] ], + "chrome-bug-1283776-000-crash.html": [ + "6df83b5e6371aecfd235a1eaebd07f26b3b83179", + [ + null, + {} + ] + ], + "chrome-bug-1283776-001-crash.html": [ + "1c242a99c1f024e15971d6c91d743db3b039b787", + [ + null, + {} + ] + ], "flexbox": { "fixed-flex-item-inside-abs-flex-in-multicol-crash.html": [ "29ba56748f9a81615977ded26f4299fa744475f0", @@ -494,6 +515,13 @@ {} ] ], + "input-column-group-container-crash.html": [ + "5e520a45cffb9c203085118efde823b6b40cdf60", + [ + null, + {} + ] + ], "pseudo-container-crash.html": [ "f998c3a4464ca3eb3ce07687cf24d9dcdc9a16af", [ @@ -2090,6 +2118,13 @@ {} ] ], + "delete-in-empty-editable-list-followed-by-non-editable-listitem.html": [ + "9e872f5ac47a1f6bda848dfe4b61efcf6679a966", + [ + null, + {} + ] + ], "execCommand-at-load-with-changing-editing-host.html": [ "ec1dd30dc023205ce479df1038d08279c315ae62", [ @@ -81191,6 +81226,58 @@ {} ] ], + "out-of-flow-in-multicolumn-077.html": [ + "f37858bb2649fda65899a2f4741c633f20f2b93c", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "out-of-flow-in-multicolumn-078.html": [ + "b19bb9f5d10f6da3ecc61015b6bce0644a0fbdf3", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "out-of-flow-in-multicolumn-079.html": [ + "f4d4c32b99e6978cdedcfcd134f36292dc87ff77", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "out-of-flow-in-multicolumn-080.html": [ + "4b620ae4177a476f807e4ff6db3e278d5a0c7a96", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "overflow-clip-000.html": [ "72b10f5cdd3092a042f1f90bff04e9428d61608e", [ @@ -90462,6 +90549,19 @@ {} ] ], + "table-inside-container-changing-display.html": [ + "bdb99c182417fa090296fb86bc44327b915f8338", + [ + null, + [ + [ + "/css/css-contain/container-queries/table-inside-container-changing-display-ref.html", + "==" + ] + ], + {} + ] + ], "top-layer-dialog-backdrop.html": [ "20c78d58e27546bffbc17feed2e02e03df943218", [ @@ -136266,6 +136366,19 @@ {} ] ], + "overflow-clip-margin-010.html": [ + "e2d1983069f367dc6edc4065de6535b5a2431c13", + [ + null, + [ + [ + "/css/css-overflow/overflow-clip-margin-010-ref.html", + "==" + ] + ], + {} + ] + ], "overflow-clip-margin-invalidation.html": [ "d9c87a34a53f17451b0d3ae8c2071971d1df3a94", [ @@ -143137,7 +143250,7 @@ ] ], "target-text-dynamic-001.html": [ - "1a7a72ca4e0cc98fcd511f022c3c0af12bc57e9a", + "63cbaa52b257674993afab1e22be3c5ed0927406", [ null, [ @@ -172748,7 +172861,7 @@ }, "css-transforms": { "2d-rotate-001.html": [ - "23c412f7afff5caa2c5928809e50a93f57a24a0f", + "9e87de5fd284bf80bc9693edf1e91d6e8c2ba9ce", [ null, [ @@ -172764,10 +172877,10 @@ [ [ 87, - 128 + 159 ], [ - 981, + 643, 1193 ] ] @@ -173408,7 +173521,7 @@ ] ], "css-skew-002.html": [ - "1b24515e43e936d5a5233cd8b4e170a9d557bb73", + "ff042380206b31194fa95cc284a1a7bd5ee54bf8", [ null, [ @@ -173427,7 +173540,7 @@ 32 ], [ - 24, + 12, 159 ] ] @@ -176688,7 +176801,7 @@ ] ], "rotate_45deg.html": [ - "e5ca42f2bc277d08a1988688c825deb5ccc18459", + "a4876acd3bdb8b1328fa3a43e951423b0569bf6c", [ null, [ @@ -176707,7 +176820,7 @@ 255 ], [ - 100, + 50, 200 ] ] @@ -176717,7 +176830,7 @@ ] ], "rotate_x_45deg.html": [ - "f55bdf1f01c48af66db909a653766d7398066ecc", + "04a584abdcbc4a43b688d9d82cbe449fc82899a6", [ null, [ @@ -176736,7 +176849,7 @@ 255 ], [ - 100, + 50, 200 ] ] @@ -176746,7 +176859,7 @@ ] ], "rotate_y_45deg.html": [ - "5b705c403115abf4123f06ab1b843c06ff97c064", + "e3c06521328b704ff8f523a1374cfe1a7e41c8d3", [ null, [ @@ -176765,7 +176878,7 @@ 255 ], [ - 100, + 50, 200 ] ] @@ -177089,7 +177202,7 @@ ] ], "skew-test1.html": [ - "a68e59e0422ba3e3d7b91e6e3fce2a011051b2c0", + "30e0028664b62ac00362028641d03e4ed786277e", [ null, [ @@ -177105,7 +177218,7 @@ [ [ 17, - 97 + 233 ], [ 96, @@ -180852,7 +180965,7 @@ ] ], "transform-percent-008.html": [ - "dcdec73fa523207e058b97e61921163e35931b5e", + "e4b333216333c320dafb7697a7cf47acfc20e3f5", [ null, [ @@ -180872,7 +180985,7 @@ [ [ 0, - 99 + 102 ], [ 0, @@ -183412,7 +183525,7 @@ ] ], "ttwf-transform-skewx-001.html": [ - "f633bf4344e8bfacdde8efa5495392fb922468e7", + "40b6ea80531467448447b6fe693b53c2920bef1e", [ null, [ @@ -183431,7 +183544,7 @@ 64 ], [ - 200, + 100, 200 ] ] @@ -183441,7 +183554,7 @@ ] ], "ttwf-transform-skewy-001.html": [ - "ce64b53d0e21cf1ed4163cbf0e81872de5a4eed1", + "599d615cb9d690e2ef9001fa612324d8e0ff07ad", [ null, [ @@ -183457,10 +183570,10 @@ [ [ 63, - 66 + 68 ], [ - 200, + 100, 200 ] ] @@ -231763,6 +231876,14 @@ "b8a1d0a6098492b615dfae8a1e5e44ade8a2f3db", [] ], + "cookieListItem_attributes.https.any-expected.txt": [ + "084f511984369c8f1ef7b06bf6a46f4cc037d930", + [] + ], + "cookieListItem_attributes.https.any.serviceworker-expected.txt": [ + "084f511984369c8f1ef7b06bf6a46f4cc037d930", + [] + ], "resources": { "always_changing_sw.sub.js": [ "9fdf99848fa50316e275cd6636a5755270a9bb1e", @@ -242412,6 +242533,12 @@ "e72f837c95c06189d2945adedaa02351989590ab", [] ], + "parsing": { + "print-color-adjust-expected.txt": [ + "1fbbb6154eea30c0ec1253dcb8d69f12889bb733", + [] + ] + }, "print-color-adjust-parsing-expected.txt": [ "1fbbb6154eea30c0ec1253dcb8d69f12889bb733", [] @@ -242803,6 +242930,10 @@ [] ] }, + "table-inside-container-changing-display-ref.html": [ + "c0355d2f5019b8c7c1e0b387e2f9c3b1a0c1f81c", + [] + ], "top-layer-dialog-backdrop-ref.html": [ "49c46974c9de23284852d302b57b0ad206158d0f", [] @@ -259374,6 +259505,10 @@ "efbf8985e56728c6f1a962fac8da8209d5a112af", [] ], + "overflow-clip-margin-010-ref.html": [ + "e548417c728fce159e7a7388d5530966944bd4ea", + [] + ], "overflow-clip-margin-invalidation-ref.html": [ "1ec2a5ce0a21c8dd578b3fcfde702307e4e2a9a8", [] @@ -260876,11 +261011,11 @@ ], "parsing": { "marker-supported-properties-expected.txt": [ - "1d6999f2ffb0e8722aa14df88d01a5e79ae48044", + "b599ad933fc63e2535c7740ac8cca8e933e17883", [] ], "marker-supported-properties-in-animation-expected.txt": [ - "10967acc54685e3b6ee6f454df09641eca9f741a", + "6bd099eac1c177010daa3d51c265533fc6148f85", [] ] }, @@ -286708,7 +286843,7 @@ }, "imagebitmap": { "common.sub.js": [ - "aa1e382a2088fee541a1020a03a4299a3b18d6cd", + "1889035202287d8ee8e6e192647826c702b60be5", [] ], "createImageBitmap-drawImage-expected.txt": [ @@ -287680,7 +287815,7 @@ [] ], "path-objects.yaml": [ - "1eb0ac1c2d460debda815feb73c5e965be71f955", + "e6ac79585eb76a61511e942df95f0a3e1786d798", [] ], "pixel-manipulation.yaml": [ @@ -287844,6 +287979,10 @@ "6604450991a122e3e241e40b1b9e0516c525389d", [] ], + "block-local-documents-inheriting-none.https-expected.txt": [ + "d6a62671f448633dd4ec0f7e71c9b1fc362a521e", + [] + ], "cache-storage-reporting-dedicated-worker.https-expected.txt": [ "f305a39c1e214f9e9c968998b50c327b288c0fec", [] @@ -299769,6 +299908,10 @@ "35a8dfcf34d58060ec70f0a2a04e0d58e357e084", [] ], + "wide-gamut-pattern.png": [ + "f35cd4a2e1628bf0b6cd0bb58ea1c3b0d51f0e45", + [] + ], "wpt-logo": { "wpt-logo-darkblue-bg.svg": [ "49f374c00cd1358f446a436122941a0d40b90937", @@ -310489,15 +310632,15 @@ [] ], "redirect-scope.py": [ - "2e7ae0163cb9853272b4501553280976438f59cb", + "84a97e594b25669fe4d61fa8fe60878175428dba", [] ], "redirect-worker.js": [ - "f7479edef9290c98c574a2dc72bc37fbd1f9b177", + "1b55f2ef0d98c00a949132e1880a6f11227f54c7", [] ], "request-headers-scope.py": [ - "46151cdcbb01d7adbce1d3d8be88ab828ec562a8", + "5bab5b01f3638b83f8ae07764e8d0cddf0a5725f", [] ], "request-headers-worker.js": [ @@ -315811,7 +315954,7 @@ [] ], "corp.har": [ - "36c2a014e8e3e006eaf0b30cd08e8e3b8fce7e6c", + "59b20da3b0af278be2e6e88fa99b0307ddd80925", [] ], "cross-origin-no-cors.har": [ @@ -315882,7 +316025,7 @@ }, "nested": { "nested-sub.wbn": [ - "c50fc67e9885213377732a6751ad880cb38312f3", + "840773f8dbf0ec0e35152d4025f92c778578ece2", [] ], "resource.js": [ @@ -316021,7 +316164,7 @@ [] ], "corp.wbn": [ - "ef48295875188ba081e889cd7de417b669f78c19", + "6679b0bf5c72fe07fd33f48131d580a0228f3582", [] ], "cross-origin-b1.wbn": [ @@ -316064,39 +316207,39 @@ ] }, "dynamic1-b1.wbn": [ - "53aa4ba8ad18c80796983dea802fa958e8d4d8ff", + "943e00e6ec719cf32b346ebb5548eb46a9e3564b", [] ], "dynamic1-crossorigin-b1.wbn": [ - "c2f73708b8789b8d0b2bc20f72646e462d040229", + "4d2d42dd534f2b363d7870fdb4d3167dfa78c4fb", [] ], "dynamic1-crossorigin.wbn": [ - "a02538bdf22c4bac504b0b8bccbb9f11c6a24498", + "e003f3948146799fbd54c0a76add8babf2ddfec2", [] ], "dynamic1.wbn": [ - "77ffd6e99535677881d765d387c8d9922b9c0a70", + "f9b8e01404470e21c961a89b7d57ac2a2323d372", [] ], "dynamic2-b1.wbn": [ - "23130c2da328297a9bbb7e9f404c8c1f0701280e", + "0d9a6e743af21c7d7c65c106ea48b9a24eb84758", [] ], "dynamic2.wbn": [ - "6097e1a896ae38a3ce30c6e8899150c9daf7b6ba", + "f23fb4fad4a478840e4a545d9a449d4cbae842c7", [] ], "location-b1.wbn": [ - "44873d8a0e03f22ccf1442a138525e13bb59f4f1", + "a566446df65ed74f71589f9e2173d6659066ca54", [] ], "location.wbn": [ - "b0dd7e2b287cbe56ded4029db3ddc09cdc726632", + "54d8f40fce5c07cdf8f59bc8f769137dfe820508", [] ], "nested-main.wbn": [ - "e33d71614de57370590fa8a561fc090b9af52fe0", + "9c21e732207660fb655c487865dc30324b3e8aab", [] ], "no-cors": { @@ -316122,11 +316265,11 @@ [] ], "path-restriction-b1.wbn": [ - "bc01a91517fb80585b6321d313ec30712ebcde7e", + "e031084521c974abd8b6068cdd10f107d5faa8f1", [] ], "path-restriction.wbn": [ - "0edf4592df9546b95b08d1af26c4593f7ceecc8e", + "73a02a08293bd24666edecc40d384963e7f8bc03", [] ], "relative-url.wbn": [ @@ -316186,11 +316329,11 @@ } }, "static-element.wbn": [ - "4d06cea7d6cb6ed17f991f86bfe1d562d4e68f04", + "dd50ef320a0adb7c79285e92be6c20e4869be9b4", [] ], "subresource.wbn": [ - "297e1ef6c8acc991cf6e45b21a935ca2169327e7", + "840773f8dbf0ec0e35152d4025f92c778578ece2", [] ], "urn-uuid-b1.wbn": [ @@ -323532,7 +323675,7 @@ ] ], "Blob-in-worker.worker.js": [ - "a67060e7b85effa52a5b93856fcda3b62e572eaa", + "a0ca84551dd7cc3fd3a3bfb2850f414787bacac8", [ "FileAPI/blob/Blob-in-worker.worker.html", {} @@ -358400,7 +358543,7 @@ }, "css-color-adjust": { "inheritance.html": [ - "f7f6529349bf1ba0436e2d1165a81552de95ffaa", + "f834d7bb54cd7b8adf32ce56a3b0fe1acbd58a0b", [ null, {} @@ -358427,15 +358570,15 @@ null, {} ] + ], + "print-color-adjust.html": [ + "03522bc32db278d667cc02908b7facd241add480", + [ + null, + {} + ] ] }, - "print-color-adjust-parsing.html": [ - "03522bc32db278d667cc02908b7facd241add480", - [ - null, - {} - ] - ], "rendering": { "dark-color-scheme": { "color-scheme-color-property.html": [ @@ -361708,6 +361851,13 @@ {} ] ], + "crash-large-grapheme-cluster.html": [ + "c1238e6f35232e52fa6f1cec83b174e53911517e", + [ + null, + {} + ] + ], "fallback-remote-to-data-url.html": [ "cf4feccd5aced06d9c21538913d3a21dfbe23756", [ @@ -369066,7 +369216,7 @@ ] ], "marker-supported-properties-in-animation.html": [ - "d2b9961351fb20c534caf2f86041ba1c2d47603b", + "259a5b84eb5122c309294973b5ad745da11216e5", [ null, {} @@ -375197,6 +375347,13 @@ {} ] ], + "text-emphasis-computed.html": [ + "460035a55179ada38a78be2dd7a280c8a0bd3518", + [ + null, + {} + ] + ], "text-emphasis-position-computed.html": [ "f288fdf57edc5cf2e463441415c755e1d99e51ce", [ @@ -376366,6 +376523,13 @@ {} ] ], + "retargetted-transition-with-box-sizing.html": [ + "ef5b116cb91a126db61e34df92531152b74eda04", + [ + null, + {} + ] + ], "starting-of-transitions-001.html": [ "f80d8134366f861a7220acc348c69c4715de821e", [ @@ -425604,6 +425768,13 @@ {} ] ], + "createImageBitmap-colorSpaceConversion.html": [ + "c7b49884d38f23035b96abeeadd4e91744291e99", + [ + null, + {} + ] + ], "createImageBitmap-drawImage-closed.html": [ "3b8644cff50803dcc6227108672447fce9d26171", [ @@ -426752,14 +426923,28 @@ ] ], "2d.path.roundrect.1.radius.dompoint.html": [ - "17bb1abccb62d79cac4b96f3c8bc8507b6801e63", + "ad7168a793c82e84ca8e75e69443044c94b1be23", + [ + null, + {} + ] + ], + "2d.path.roundrect.1.radius.dompoint.single argument.html": [ + "5fc1425dec04e69bcddfd6599da4fd21836b5b4c", [ null, {} ] ], "2d.path.roundrect.1.radius.dompointinit.html": [ - "1926bccfdac65af7401467cb19d909c6068052f5", + "7ca4dd7265a4d16fa8fab35359352a7e31508068", + [ + null, + {} + ] + ], + "2d.path.roundrect.1.radius.dompointinit.single.argument.html": [ + "17f4946a9b075d50e9d3948907098af41cbdfe8b", [ null, {} @@ -426772,6 +426957,13 @@ {} ] ], + "2d.path.roundrect.1.radius.double.single.argument.html": [ + "c097ac9b506086d426b4e2c8682e1c26b1759e84", + [ + null, + {} + ] + ], "2d.path.roundrect.2.radii.1.dompoint.html": [ "e74e0f1eabe48ae8416ad7f6b63af3ed7b4ae28c", [ @@ -441417,6 +441609,13 @@ {} ] ], + "block-local-documents-inheriting-none.https.html": [ + "ab645b7e8f1c4f7854878ad90067b30fda28c121", + [ + null, + {} + ] + ], "cache-storage-reporting-dedicated-worker.https.html": [ "f4b2599141a786c9573991467a126d59c9cc3fd5", [ @@ -514315,6 +514514,24 @@ } ] ], + "resize-event-order.html": [ + "41a13728bc3ff61cfc32bb02839eab5a11d1d33b", + [ + null, + { + "testdriver": true + } + ] + ], + "scroll-event-order.html": [ + "5ab5e0747a67bbc82e3620da5cafd1813277245c", + [ + null, + { + "testdriver": true + } + ] + ], "viewport-no-resize-event-on-overflow-recalc.html": [ "dcb9432da83cb21b6f0403080d3c7b3b5df1659e", [ @@ -561823,6 +562040,27 @@ null, {} ] + ], + "nested-multicol-with-spanner-and-oof-crash-001.html": [ + "88b902af50283f87439e73fde9564cbb2bcba73a", + [ + null, + {} + ] + ], + "nested-multicol-with-spanner-and-oof-crash-002.html": [ + "3a5b1da331116e86a6d16aaf8341cc5bf6a075aa", + [ + null, + {} + ] + ], + "nested-multicol-with-spanner-and-oof-crash-003.html": [ + "e6c1293e3b76488d9bd48fa8234ce4e78737be66", + [ + null, + {} + ] ] }, "css-counter-styles": {
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-in-worker.worker.js b/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-in-worker.worker.js index a67060e..a0ca845 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-in-worker.worker.js +++ b/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-in-worker.worker.js
@@ -1,14 +1,9 @@ importScripts("/resources/testharness.js"); -async_test(function() { - var data = "TEST"; - var blob = new Blob([data], {type: "text/plain"}); - var reader = new FileReader(); - reader.onload = this.step_func_done(function() { - assert_equals(reader.result, data); - }); - reader.onerror = this.unreached_func("Unexpected error event"); - reader.readAsText(blob); -}, "Create Blob in Worker"); +promise_test(async () => { + const data = "TEST"; + const blob = new Blob([data], {type: "text/plain"}); + assert_equals(await blob.text(), data); +}, 'Create Blob in Worker'); done();
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt new file mode 100644 index 0000000..084f5119 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +FAIL CookieListItem - cookieStore.set defaults with positional name and value assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set defaults with name and value in options assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with expires set to a timestamp 10 years in the future assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +PASS CookieListItem - cookieStore.set with expires set to a Date 10 years in the future +FAIL CookieListItem - cookieStore.set with domain set to the current hostname assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with path set to the current directory assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set adds / to path if it does not end with / assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to strict assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to lax assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to none assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt new file mode 100644 index 0000000..084f5119 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +FAIL CookieListItem - cookieStore.set defaults with positional name and value assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set defaults with name and value in options assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with expires set to a timestamp 10 years in the future assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +PASS CookieListItem - cookieStore.set with expires set to a Date 10 years in the future +FAIL CookieListItem - cookieStore.set with domain set to the current hostname assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with path set to the current directory assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set adds / to path if it does not end with / assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to strict assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to lax assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +FAIL CookieListItem - cookieStore.set with sameSite set to none assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/auto-overflow-inside-second-abspos-fragment-crash.html b/third_party/blink/web_tests/external/wpt/css/css-break/auto-overflow-inside-second-abspos-fragment-crash.html new file mode 100644 index 0000000..c4ce36a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/auto-overflow-inside-second-abspos-fragment-crash.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1282508"> +<div style="columns:2; column-fill:auto; height:100px;"> + <div style="height:90px;"></div> + <div style="position:relative;"> + <div style="position:absolute;"> + <div style="height:5px;"></div> + <div style="overflow-y:auto; width:10px; height:50px;"> + <div style="height:60px;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-001.html b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-001.html new file mode 100644 index 0000000..88b902a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-001.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1278277"> +<p>PASS if no crash or DCHECK failure.</p> +<div style="columns:2;"> + <div style="columns:2;"> + <div style="column-span:all; position:relative;"> + <div style="position:absolute; height:10px;"></div> + <div style="position:absolute; height:20px;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-002.html b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-002.html new file mode 100644 index 0000000..3a5b1da3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-002.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1278277"> +<p>PASS if no crash or DCHECK failure.</p> +<div style="columns:2;"> + <div style="columns:2;"> + <div style="column-span:all;"> + <div style="position:relative;"> + <div style="position:absolute; height:10px;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-003.html b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-003.html new file mode 100644 index 0000000..e6c1293 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/nested-multicol-with-spanner-and-oof-crash-003.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1278277"> +<p>PASS if no crash or DCHECK failure.</p> +<div style="columns:2;"> + <div style="columns:2;"> + <div style="column-span:all; position:relative;"> + <div style="transform: translateX(0);"> + <div style="position:absolute; height:10px;"> + <div style="position:fixed; height:20px;"></div> + </div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-077.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-077.html new file mode 100644 index 0000000..f37858bb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-077.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1280662"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; height:100px; width:100px; background:green; column-fill:auto; column-gap:0;"> + <div style="height:40px;"></div> + <div style="columns:2; width:50px; column-fill:auto; column-gap:0;"> + <div style="position:relative; column-span:all; height:160px; background:red;"> + <div style="position:absolute; height:160px; width:50px; background:green;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-078.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-078.html new file mode 100644 index 0000000..b19bb9f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-078.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1280662"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; height:100px; width:100px; background:green; column-fill:auto; column-gap:0;"> + <div style="height:40px;"></div> + <div style="columns:2; width:50px; column-fill:auto; column-gap:0;"> + <div style="position:relative; column-span:all; height:160px; background:red;"> + <div style="position:absolute; top:0; bottom:0; width:50px; background:green;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-079.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-079.html new file mode 100644 index 0000000..f4d4c32 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-079.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1280662"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; height:100px; width:100px; background:green; column-fill:auto; column-gap:0;"> + <div style="height:40px;"></div> + <div style="columns:2; width:50px; column-fill:auto; column-gap:0;"> + <div style="column-span:all; height: 160px; background:red;"> + <div style="height:40px; width:50px; background: green;"></div> + <div style="position:relative; height:120px; width:50px;"> + <div style="position:absolute; height:120px; width:50px; background:green;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-080.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-080.html new file mode 100644 index 0000000..4b620ae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-080.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1280662"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; height:100px; width:100px; background:green; column-fill:auto; column-gap:0;"> + <div style="height:40px;"></div> + <div style="columns:2; width:50px; column-fill:auto; column-gap:0;"> + <div style="column-span:all; height: 160px; background:red;"> + <div style="height:40px; width:50px; background: green;"></div> + <div style="position:relative; height:120px; width:50px;"> + <div style="position:absolute; top:0; bottom:0; width:50px; background:green;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/inheritance.html b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/inheritance.html index f7f65293..f834d7b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/inheritance.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/inheritance.html
@@ -10,4 +10,7 @@ </div> <script> assert_inherited('color-scheme', 'normal', 'light dark'); + assert_inherited('color-adjust', 'economy', 'exact'); + assert_inherited('forced-color-adjust', 'auto', 'preserve-parent-color'); + assert_inherited('print-color-adjust', 'economy', 'exact'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt new file mode 100644 index 0000000..1fbbb61 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL e.style['print-color-adjust'] = "exact" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['print-color-adjust'] = "economy" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color-adjust'] = "exact" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color-adjust'] = "economy" should set the property value assert_not_equals: property should be set got disallowed value "" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/print-color-adjust-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/parsing/print-color-adjust.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-color-adjust/print-color-adjust-parsing.html rename to third_party/blink/web_tests/external/wpt/css/css-color-adjust/parsing/print-color-adjust.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/input-column-group-container-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/input-column-group-container-crash.html new file mode 100644 index 0000000..5e520a4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/input-column-group-container-crash.html
@@ -0,0 +1,14 @@ +<!doctype html> +<title>CSS Container Queries Test: </title> +<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries"> +<link rel="help" href="https://crbug.com/1282782"> +<p>Pass if this test does not crash</p> +<span style="column-count: 1"> + <span style="display:table-column-group"></span> + <input id="inp"> +</span> +<script> + document.body.offsetTop; + document.body.style.setProperty("container", "inline-size"); + inp.setAttribute("type", "image"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display-ref.html new file mode 100644 index 0000000..c0355d2f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display-ref.html
@@ -0,0 +1,4 @@ +<!doctype html> +<title>CSS Test Reference</title> +<p>You should see the word PASS below.</p> +<table><td>PASS</td></table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display.html new file mode 100644 index 0000000..bdb99c18 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/table-inside-container-changing-display.html
@@ -0,0 +1,16 @@ +<!doctype html> +<title>CSS Container Queries Test: table inside @container changing display type</title> +<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries"> +<link rel="help" href="https://crbug.com/1284918"> +<link rel="match" href="table-inside-container-changing-display-ref.html"> +<p>You should see the word PASS below.</p> +<div id="container" style="width: 200px; height: 200px; container-type:inline-size;"> + <div> + <table><td>PASS</td></table> + </div> +</div> +<script> + document.body.offsetTop; + document.querySelector("#container").style.display = "inline-block"; + document.querySelector("table").style.color = "currentColor"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010-ref.html new file mode 100644 index 0000000..e548417 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010-ref.html
@@ -0,0 +1,40 @@ +<!doctype html> +<html class="reftest"> +<meta charset="utf-8"> +<title>Overflow-clip-margin corner shape (ref)</title> +<link rel="help" href="https://www.w3.org/TR/css-overflow-3/#propdef-overflow-clip-margin"> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<style> +.container { + width: 100px; + height: 100px; + + position: relative; + top: 30px; + left: 30px; + + border: 5px solid green; + + border-radius: 0px 15px 25px 35px; +} +.clipper { + width: 140px; + height: 140px; + + margin: -20px; + border-radius:0px 27.5px 40px 50px; + overflow: clip; +} +.child { + width: 400px; + height: 400px; + background: lightblue; + opacity: 0.8; +} +</style> + +<div class=container> + <div class=clipper> + <div class=child></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010.html new file mode 100644 index 0000000..e2d19830 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-010.html
@@ -0,0 +1,34 @@ +<!doctype html> +<html class="reftest"> +<meta charset="utf-8"> +<title>Overflow-clip-margin corner shape</title> +<link rel="help" href="https://www.w3.org/TR/css-overflow-3/#propdef-overflow-clip-margin"> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="overflow-clip-margin-010-ref.html"> +<style> +.container { + width: 100px; + height: 100px; + + position: relative; + top: 30px; + left: 30px; + + border: 5px solid green; + + overflow: clip; + overflow-clip-margin: 20px; + border-radius: 0px 15px 25px 35px; +} +.child { + width: 400px; + height: 400px; + margin: -200px; + background: lightblue; + opacity: 0.8; +} +</style> + +<div class=container> + <div class=child></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt index 1d6999f2..b599ad9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 61 tests; 58 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 61 tests; 59 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Property font value 'italic small-caps 900 expanded 25px / 50px Ahem' in ::marker PASS Property font-family value 'Ahem' in ::marker PASS Property font-feature-settings value '"smcp"' in ::marker @@ -49,7 +49,7 @@ PASS Property word-break value 'break-word' in ::marker PASS Property word-spacing value '10px' in ::marker PASS Property text-decoration-skip-ink value 'none' in ::marker -FAIL Property text-emphasis value 'filled dot rgb(0, 255, 0)' in ::marker assert_equals: expected "filled dot rgb(0, 255, 0)" but got "" +PASS Property text-emphasis value 'filled dot rgb(0, 255, 0)' in ::marker PASS Property text-emphasis-color value 'rgb(0, 255, 0)' in ::marker PASS Property text-emphasis-position value 'under left' in ::marker PASS Property text-emphasis-style value 'filled dot' in ::marker
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation-expected.txt index 10967acc..6bd099e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 94 tests; 88 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 94 tests; 90 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Animation of font in ::marker PASS Animation of font-family in ::marker PASS Animation of font-feature-settings in ::marker @@ -35,7 +35,7 @@ PASS Animation of word-break in ::marker PASS Animation of word-spacing in ::marker PASS Animation of text-decoration-skip-ink in ::marker -FAIL Animation of text-emphasis in ::marker assert_equals: expected "triangle rgb(50, 100, 100)" but got "" +PASS Animation of text-emphasis in ::marker PASS Animation of text-emphasis-color in ::marker PASS Animation of text-emphasis-position in ::marker PASS Animation of text-emphasis-style in ::marker @@ -82,7 +82,7 @@ PASS Transition of word-break in ::marker PASS Transition of word-spacing in ::marker PASS Transition of text-decoration-skip-ink in ::marker -FAIL Transition of text-emphasis in ::marker assert_equals: expected "triangle rgb(50, 100, 100)" but got "" +PASS Transition of text-emphasis in ::marker PASS Transition of text-emphasis-color in ::marker PASS Transition of text-emphasis-position in ::marker PASS Transition of text-emphasis-style in ::marker
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation.html index d2b9961..259a5b8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation.html
@@ -245,7 +245,7 @@ property: "text-emphasis", from: "dot rgb(0, 200, 0)", to: "triangle rgb(100, 0, 200)", - midPoint: "triangle rgb(50, 100, 100)", + midPoint: "filled triangle rgb(50, 100, 100)", }, { property: "text-emphasis-color",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-001.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-001.html index 1a7a72c..63cbaa5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-001.html
@@ -19,7 +19,8 @@ <script> location.href = "#:~:text=Example"; requestAnimationFrame(() => requestAnimationFrame(() => { - document.styleSheets[0].cssRules[0].style.backgroundColor = "magenta"; + if (document.styleSheets[0].cssRules[0]) + document.styleSheets[0].cssRules[0].style.backgroundColor = "magenta"; takeScreenshot(); })); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-emphasis-computed.html b/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-emphasis-computed.html new file mode 100644 index 0000000..460035a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-emphasis-computed.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Text Decoration Test: getComputedStyle().textEmphasis</title> +<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-emphasis-property"> +<meta name="assert" content="text-emphasis computed value is as specified."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +<style> +#target { + color: blue; +} +</style> +</head> +<body> +<div id="target"></div> +<script> +'use strict'; +const currentColor = "rgb(0, 0, 255)"; +test_computed_value("text-emphasis", "none", `none ${currentColor}`); +test_computed_value("text-emphasis", "dot", `filled dot ${currentColor}`); +test_computed_value("text-emphasis", "open sesame", `open sesame ${currentColor}`); +test_computed_value("text-emphasis", "'*'", `"*" ${currentColor}`); + +test_computed_value("text-emphasis", "currentColor", `none ${currentColor}`); +test_computed_value("text-emphasis", "black", `none rgb(0, 0, 0)`); + +test_computed_value("text-emphasis", "dot red", `filled dot rgb(255, 0, 0)`); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/2d-rotate-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/2d-rotate-001.html index 23c412f7..9e87de5f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/2d-rotate-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/2d-rotate-001.html
@@ -5,7 +5,7 @@ <link rel="author" title="Rick Hurst" href="http://mrkn.co/axegs"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="match" href="2d-rotate-ref.html"> - <meta name="fuzzy" content="maxDifference=87-128;totalPixels=981-1193"> + <meta name="fuzzy" content="maxDifference=87-159;totalPixels=643-1193"> <meta name="flags" content="svg"> <meta name="assert" content="asserting that you can rotate an element with CSS"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/css-skew-002.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/css-skew-002.html index 1b24515..ff0423802 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/css-skew-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/css-skew-002.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#two-d-transform-functions"> <link rel="author" title="Adrien Pachkoff" href="mailto:adrien@pachkoff.com"> <link rel="match" href="css-skew-002-ref.html"> - <meta name="fuzzy" content="maxDifference=5-32;totalPixels=24-159"> + <meta name="fuzzy" content="maxDifference=5-32;totalPixels=12-159"> <style type="text/css"> div { top:0px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_45deg.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_45deg.html index e5ca42f..a4876acd3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_45deg.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_45deg.html
@@ -5,7 +5,7 @@ <link rel="author" title="Ebay Inc." href="mailto:xiatian@ebay.com"/> <link rel="help" href="https://www.w3.org/TR/css-transforms-1/#funcdef-transform-rotate"/> <link rel="match" href="rotate_45deg-ref.html"/> - <meta name="fuzzy" content="maxDifference=159-255;totalPixels=100-200"> + <meta name="fuzzy" content="maxDifference=159-255;totalPixels=50-200"> <meta name="flags" content="" /> <meta name="assert" content="Rotate 45 degree in y axis"/> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_x_45deg.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_x_45deg.html index f55bdf1f0..04a584a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_x_45deg.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_x_45deg.html
@@ -5,7 +5,7 @@ <link rel="author" title="Ebay Inc." href="mailto:xiatian@ebay.com"/> <link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering"/> <link rel="match" href="rotate_x_45deg-ref.html"/> - <meta name="fuzzy" content="maxDifference=159-255;totalPixels=100-200"> + <meta name="fuzzy" content="maxDifference=159-255;totalPixels=50-200"> <meta name="flags" content="" /> <meta name="assert" content="Rotate 45 degree in y axis"/> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_y_45deg.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_y_45deg.html index 5b705c40..e3c0652 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_y_45deg.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/rotate_y_45deg.html
@@ -5,7 +5,7 @@ <link rel="author" title="Ebay Inc." href="mailto:xiatian@ebay.com"/> <link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering"/> <link rel="match" href="rotate_y_45deg-ref.html"/> - <meta name="fuzzy" content="maxDifference=159-255;totalPixels=100-200"> + <meta name="fuzzy" content="maxDifference=159-255;totalPixels=50-200"> <meta name="flags" content="" /> <meta name="assert" content="Rotate 45 degree in y axis"/> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/skew-test1.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/skew-test1.html index a68e59e..30e0028 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/skew-test1.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/skew-test1.html
@@ -8,7 +8,7 @@ <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#svg-transform"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#two-d-transform-functions"> <link rel="match" href="reference/skew-test1-ref.html"> - <meta name="fuzzy" content="maxDifference=17-97;totalPixels=96-771"> + <meta name="fuzzy" content="maxDifference=17-233;totalPixels=96-771"> <meta name="flags" content="svg"> <meta name="assert" content="The lime square in this test has a skew method applied : 30deg on x and 20deg on y. The red polygon should be totally hidden by the lime skewed square. Both start at 0,0"> <style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform-percent-008.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform-percent-008.html index dcdec73..e4b3332 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform-percent-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform-percent-008.html
@@ -9,7 +9,7 @@ transformed element's border box. This test adds a thicker border plus margin and padding to make any discrepancies more evident."> <link rel="match" href="transform-percent-ref.html"> - <meta name="fuzzy" content="maxDifference=0-99;totalPixels=0-416"> + <meta name="fuzzy" content="maxDifference=0-102;totalPixels=0-416"> <link rel="mismatch" href="transform-percent-notref.html"> <style> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewx-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewx-001.html index f633bf43..40b6ea80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewx-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewx-001.html
@@ -5,7 +5,7 @@ <link rel="author" title="Mihai Corlan" href="mailto:mcorlan@adobe.com"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="match" href="reference/ttwf-reftest-transform-skewx-001.html"> - <meta name="fuzzy" content="maxDifference=63-64;totalPixels=200-200"> + <meta name="fuzzy" content="maxDifference=63-64;totalPixels=100-200"> <meta name="assert" content="Test that the green shape is skew on X axis by 45 degrees"> <style type="text/css"> .greenSquare {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewy-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewy-001.html index ce64b53..599d615 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewy-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/ttwf-transform-skewy-001.html
@@ -5,7 +5,7 @@ <link rel="author" title="Mihai Corlan" href="mailto:mcorlan@adobe.com"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="match" href="reference/ttwf-reftest-transform-skewy-001.html"> - <meta name="fuzzy" content="maxDifference=63-66;totalPixels=200-200"> + <meta name="fuzzy" content="maxDifference=63-68;totalPixels=100-200"> <meta name="assert" content="Test that the green shape is skew on Y axis by 45 degrees"> <style type="text/css"> .greenSquare {
diff --git a/third_party/blink/web_tests/transitions/retargetted-transition-with-box-sizing.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/retargetted-transition-with-box-sizing.html similarity index 68% rename from third_party/blink/web_tests/transitions/retargetted-transition-with-box-sizing.html rename to third_party/blink/web_tests/external/wpt/css/css-transitions/retargetted-transition-with-box-sizing.html index 62b76b0..ef5b116 100644 --- a/third_party/blink/web_tests/transitions/retargetted-transition-with-box-sizing.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/retargetted-transition-with-box-sizing.html
@@ -1,6 +1,8 @@ <!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=571437"> +<link rel=help href="https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <style> #target { width: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html b/third_party/blink/web_tests/external/wpt/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html new file mode 100644 index 0000000..9e872f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html id="a"> +<meta charset="utf-8"> +<script id="b"> +window.onload = () => { + c.appendChild(document.head) + a.appendChild(d) + document.execCommand("selectAll") + document.execCommand("delete") +} +</script> +<dl id="c" contenteditable="true"> +<dt id="d">
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/common.sub.js b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/common.sub.js index aa1e382..18890352 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/common.sub.js +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/common.sub.js
@@ -139,16 +139,18 @@ }); } -function makeBlob() { - return new Promise(function(resolve, reject) { - var xhr = new XMLHttpRequest(); - xhr.open("GET", '/images/pattern.png'); - xhr.responseType = 'blob'; - xhr.send(); - xhr.onload = function() { - resolve(xhr.response); - }; - }); +function makeBlob(src) { + return function () { + return new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", src); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + } } var imageSourceTypes = [ @@ -162,5 +164,5 @@ { name: 'an OffscreenCanvas', factory: makeOffscreenCanvas }, { name: 'an ImageData', factory: makeImageData }, { name: 'an ImageBitmap', factory: makeImageBitmap }, - { name: 'a Blob', factory: makeBlob }, + { name: 'a Blob', factory: makeBlob("/images/pattern.png") }, ];
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html new file mode 100644 index 0000000..c7b4988 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html
@@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> +<title>Test colorSpaceConversion option for createImageBitmap</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<script src="/common/media.js"></script> +<script src="common.sub.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body> +<script> +function testCanvasDisplayingPattern(canvas, width, height) +{ + var tolerance = 10; // high tolerance for differing colour management results + const check = (x, y, r, g, b, a) => + _assertPixelApprox(canvas, x,y, r,g,b,a, `${x},${y}`, `${r},${g},${b},${a}`, tolerance); + + check(1 * width / 4, 1 * height / 4, 124,0,27,255); + check(3 * width / 4, 1 * height / 4, 0,124,46,255); + check(1 * width / 4, 3 * height / 4, 60,0,123,255); + check(3 * width / 4, 3 * height / 4, 0,0,0,255); +} + +function testDrawImageBitmap(source, options) +{ + var canvas = document.createElement("canvas"); + canvas.width = 20; + canvas.height = 20; + var ctx = canvas.getContext("2d"); + return createImageBitmap(source, options).then(imageBitmap => { + ctx.drawImage(imageBitmap, 0, 0); + testCanvasDisplayingPattern(canvas, 20, 20); + }); +} + +var wideGamutImageSourceTypes = [ + {name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/wide-gamut-pattern.png")}, + {name: 'a Blob', factory: makeBlob("/images/wide-gamut-pattern.png")}, +]; + +for (let { name, factory } of wideGamutImageSourceTypes) { + promise_test(function() { + return factory().then(function(img) { + return testDrawImageBitmap(img, {colorSpaceConversion: "none"}); + }); + }, `createImageBitmap from ${name}, and drawImage on the created ImageBitmap with colorSpaceConversion: none`); +} +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html index 17bb1ab..ad7168a 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html
@@ -8,7 +8,7 @@ <body class="show_output"> <h1>2d.path.roundrect.1.radius.dompoint</h1> -<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottom-left corners.</p> +<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.</p> <p class="output">Actual output:</p> @@ -16,7 +16,7 @@ <ul id="d"></ul> <script> -var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottom-left corners."); +var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners."); _addTest(function(canvas, ctx) { ctx.fillStyle = '#f00';
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html new file mode 100644 index 0000000..5fc1425 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.1.radius.dompoint.single argument</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.1.radius.dompoint.single argument</h1> +<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20)); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html index 1926bccf..7ca4dd72 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html
@@ -8,7 +8,7 @@ <body class="show_output"> <h1>2d.path.roundrect.1.radius.dompointinit</h1> -<p class="desc">Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners.</p> +<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.</p> <p class="output">Actual output:</p> @@ -16,7 +16,7 @@ <ul id="d"></ul> <script> -var t = async_test("Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners."); +var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners."); _addTest(function(canvas, ctx) { ctx.fillStyle = '#f00';
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html new file mode 100644 index 0000000..17f4946 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.1.radius.dompointinit.single.argument</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.1.radius.dompointinit.single.argument</h1> +<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20}); +ctx.fillStyle = '#0f0'; +ctx.fill(); + +// top-left corner +_assertPixel(canvas, 20,1, 255,0,0,255, "20,1", "255,0,0,255"); +_assertPixel(canvas, 41,1, 0,255,0,255, "41,1", "0,255,0,255"); +_assertPixel(canvas, 1,10, 255,0,0,255, "1,10", "255,0,0,255"); +_assertPixel(canvas, 1,21, 0,255,0,255, "1,21", "0,255,0,255"); + +// top-right corner +_assertPixel(canvas, 79,1, 255,0,0,255, "79,1", "255,0,0,255"); +_assertPixel(canvas, 58,1, 0,255,0,255, "58,1", "0,255,0,255"); +_assertPixel(canvas, 98,10, 255,0,0,255, "98,10", "255,0,0,255"); +_assertPixel(canvas, 98,21, 0,255,0,255, "98,21", "0,255,0,255"); + +// bottom-right corner +_assertPixel(canvas, 79,48, 255,0,0,255, "79,48", "255,0,0,255"); +_assertPixel(canvas, 58,48, 0,255,0,255, "58,48", "0,255,0,255"); +_assertPixel(canvas, 98,39, 255,0,0,255, "98,39", "255,0,0,255"); +_assertPixel(canvas, 98,28, 0,255,0,255, "98,28", "0,255,0,255"); + +// bottom-left corner +_assertPixel(canvas, 20,48, 255,0,0,255, "20,48", "255,0,0,255"); +_assertPixel(canvas, 41,48, 0,255,0,255, "41,48", "0,255,0,255"); +_assertPixel(canvas, 1,39, 255,0,0,255, "1,39", "255,0,0,255"); +_assertPixel(canvas, 1,28, 0,255,0,255, "1,28", "0,255,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html new file mode 100644 index 0000000..c097ac9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.path.roundrect.1.radius.double.single.argument</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.path.roundrect.1.radius.double.single.argument</h1> +<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners."); +_addTest(function(canvas, ctx) { + +ctx.fillStyle = '#f00'; +ctx.fillRect(0, 0, 100, 50); +ctx.roundRect(0, 0, 100, 50, 20); +ctx.fillStyle = '#0f0'; +ctx.fill(); +_assertPixel(canvas, 1,1, 255,0,0,255, "1,1", "255,0,0,255"); +_assertPixel(canvas, 98,1, 255,0,0,255, "98,1", "255,0,0,255"); +_assertPixel(canvas, 98,48, 255,0,0,255, "98,48", "255,0,0,255"); +_assertPixel(canvas, 1,48, 255,0,0,255, "1,48", "255,0,0,255"); + + +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml index 1eb0ac1..e6ac7958 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml
@@ -2319,8 +2319,21 @@ @assert pixel 98,48 == 255,0,0,255; @assert pixel 1,48 == 255,0,0,255; +- name: 2d.path.roundrect.1.radius.double.single.argument + desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, 20); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 1,1 == 255,0,0,255; + @assert pixel 98,1 == 255,0,0,255; + @assert pixel 98,48 == 255,0,0,255; + @assert pixel 1,48 == 255,0,0,255; + - name: 2d.path.roundrect.1.radius.dompoint - desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottom-left corners. + desc: Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners. code: | ctx.fillStyle = '#f00'; ctx.fillRect(0, 0, 100, 50); @@ -2352,8 +2365,41 @@ @assert pixel 1,39 == 255,0,0,255; @assert pixel 1,28 == 0,255,0,255; +- name: 2d.path.roundrect.1.radius.dompoint.single argument + desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20)); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + - name: 2d.path.roundrect.1.radius.dompointinit - desc: Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-left corners. + desc: Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners. code: | ctx.fillStyle = '#f00'; ctx.fillRect(0, 0, 100, 50); @@ -2385,6 +2431,39 @@ @assert pixel 1,39 == 255,0,0,255; @assert pixel 1,28 == 0,255,0,255; +- name: 2d.path.roundrect.1.radius.dompointinit.single.argument + desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners. + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20}); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + // top-left corner + @assert pixel 20,1 == 255,0,0,255; + @assert pixel 41,1 == 0,255,0,255; + @assert pixel 1,10 == 255,0,0,255; + @assert pixel 1,21 == 0,255,0,255; + + // top-right corner + @assert pixel 79,1 == 255,0,0,255; + @assert pixel 58,1 == 0,255,0,255; + @assert pixel 98,10 == 255,0,0,255; + @assert pixel 98,21 == 0,255,0,255; + + // bottom-right corner + @assert pixel 79,48 == 255,0,0,255; + @assert pixel 58,48 == 0,255,0,255; + @assert pixel 98,39 == 255,0,0,255; + @assert pixel 98,28 == 0,255,0,255; + + // bottom-left corner + @assert pixel 20,48 == 255,0,0,255; + @assert pixel 41,48 == 0,255,0,255; + @assert pixel 1,39 == 255,0,0,255; + @assert pixel 1,28 == 0,255,0,255; + - name: 2d.path.roundrect.radius.intersecting.1 desc: Check that roundRects with intersecting corner arcs are rendered correctly. code: |
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https-expected.txt new file mode 100644 index 0000000..d6a6267 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Prevent local scheme documents from loading within a COEP: require-corp iframe if they inherit COEP: none assert_equals: expected 3 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https.html new file mode 100644 index 0000000..ab645b7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/block-local-documents-inheriting-none.https.html
@@ -0,0 +1,104 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/common/utils.js"></script> +<div id=log></div> + +<script> +const script = ` + <script> + top.postMessage({event: "loaded", type: location.protocol}, "*"); + <\/script>`; + +const test_cases = [ + {name: "data", url: encodeURI(`data:text/html,${script}`)}, + {name: "blob", url: URL.createObjectURL(new Blob([script], { type: "text/html" }))}, + {name: "about", url: "about:blank"}, + ]; + +const observeReports = async (frame) => { + const reports = []; + + const observer = new frame.contentWindow.ReportingObserver( + rs => reports.push(...rs.map(r => r.toJSON())) + ); + observer.observe(); + + // Wait for reports. Use a timeout to catch both expected and unexpected + // reports. + await new Promise(resolve => step_timeout(resolve, 3000)); + return reports; +}; + +promise_test(async t => { + const this_window_token = token(); + + // Expect the nested frame to not load, since they inherit COEP: none from the + // top frame, which is incompatible with first_frame's COEP: require-corp. + const received_events = []; + addEventListener("message", event => { + if(event.data.event == "loaded") + received_events.push(`Nested ${event.data.type} loaded!`); + }); + + // Create an iframe with COEP: require-corp + const first_iframe = document.createElement("iframe"); + t.add_cleanup( () => first_iframe.remove() ); + first_iframe.src = "/common/blank.html?pipe=header(cross-origin-embedder-policy,require-corp)"; + let iframe_load_promise = new Promise( resolve => first_iframe.addEventListener("load", resolve) ); + + document.body.append(first_iframe); + await iframe_load_promise; + + const reportPromise = observeReports(first_iframe); + // 1. Create nested frames. + // They initially navigate to blank.html and have COEP: require-corp set. + // This initial navigation is required because it uses the parent frame as the + // initiator. That is first_iframe is the initiator, while we want top to be + // the initiator for this test, which will be done in step 3 with a second + // navigation from that blank.html document to the local scheme one. + const nested_frames = {}; + const nested_frames_promises = []; + test_cases.forEach(test => { + nested_frame = document.createElement("iframe"); + nested_frame.src = "/common/blank.html?pipe=header(cross-origin-embedder-policy,require-corp)"; + t.add_cleanup( () => nested_frame.remove() ); + nested_frames_promises.push(new Promise( resolve => nested_frame.addEventListener("load", resolve) ) ); + first_iframe.contentDocument.body.append(nested_frame); + nested_frames[test.name] = nested_frame; + }); + + // 2. Wait for the loads of all iframes to complete. + await Promise.all(nested_frames_promises); + + // 3. Navigate nested frames to a local scheme document. + // COEP should be inherited from the initiator or blobURL's creator (top in both + // cases), this results in COEP being none and the documents not being allowed + // to load under the COEP: require-corp iframe (first_iframe). + test_cases.forEach(test => { + // Top navigates nested_frame_[test.name] to a test.url + const frame = nested_frames[test.name]; + // Use frame.contentDocument.location to ensure the initiator is this (top) + // frame. frame.src is not used here as this makes the parent of the nested + // frame (first_iframe) the initiator. + frame.contentDocument.location = test.url; + }); + + // 4. Wait and validate reports. + const reports = await reportPromise; + assert_equals(reports.length, test_cases.length); + test_cases.forEach(test => { + assert_true(reports.some( report => { + return report.type == 'coep' && + report.body.type == 'navigation' && + report.body.blockedURL == test.url; + }), `No report matched for test "${test.name}"`); + }); + // Also verify that no message was sent by the nested frames and stored in + // received_events. + assert_equals([], received_events.sort()); +}, "Prevent local scheme documents from loading within a COEP: require-corp iframe if they inherit COEP: none"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html index a73d32b3..42ecb22 100644 --- a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html
@@ -24,6 +24,17 @@ max-height: 50px; overflow: scroll; } + +.fieldset3 { + width: 20em; + max-height: 250px; + padding: 7px; + margin: 0; + overflow: auto; + box-sizing: border-box; + border: 1em solid transparent; + border-top: 40px solid transparent; +} </style> <p>There should be no red.</p> <div class=fieldset> @@ -33,3 +44,21 @@ <div class=fieldset2> <div style="height:200px; background:blue"></div> </div> + +<div class="fieldset3"> + <p> +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. + </p> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html index feaa0b11..83813f9 100644 --- a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html
@@ -28,6 +28,22 @@ overflow: scroll; } +#f3 { + width: 20em; + max-height: 250px; + padding: 7px; + overflow: auto; + box-sizing: border-box; + border-color: transparent; + background: transparent; +} + +#f3 legend { + height: 40px; + border: none; + color: transparent; + background: transparent; +} </style> <p>There should be no red.</p> <fieldset id="f1"> @@ -43,3 +59,24 @@ <script> document.getElementById('last').scrollIntoView(); </script> + +<!-- crbug.com/1282408 --> +<fieldset id="f3"> + <legend>Legend</legend> + <p> +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. +The quick brown fox jumps over the lazy dog. + </p> +</fieldset> +
diff --git a/third_party/blink/web_tests/external/wpt/images/wide-gamut-pattern.png b/third_party/blink/web_tests/external/wpt/images/wide-gamut-pattern.png new file mode 100644 index 0000000..f35cd4a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/images/wide-gamut-pattern.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html index 75545ad..439e547 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html
@@ -4,6 +4,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="resources/test-helpers.sub.js"></script> +<script src="/common/utils.js"></script> <script> 'use strict'; @@ -51,4 +52,18 @@ iframeTest(SCOPE + '?stream&use-fetch-stream', (t, iwin) => { assert_equals(iwin.document.body.textContent, 'PASS\n'); }, 'Main resource built from a ReadableStream - fetch stream'); + +iframeTest(SCOPE, async (t, iwin) => { + const id = token(); + let response = await iwin.fetch('?stream&observe-cancel&id=${id}'); + response.body.cancel(); + + // Wait for a while to avoid a race between the cancel handling and the + // second fetch request. + await new Promise(r => step_timeout(r, 10)); + + response = await iwin.fetch('?stream&query-cancel&id=${id}'); + assert_equals(await response.text(), 'cancelled'); +}, 'Cancellation in the page should be observable in the service worker'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-scope.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-scope.py index 2e7ae0163..84a97e5 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-scope.py +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-scope.py
@@ -11,6 +11,7 @@ if type == b"no-location": response.status = 302 + response.headers.append(b"Content-Type", b"text/html") response.headers.append(b"Custom-Header", b"hello") return b""
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js index f7479ed..1b55f2e 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js
@@ -26,6 +26,9 @@ event.preloadResponse .then( res => { + if (res.url.includes("base")) { + return res; + } return post_to_page(get_response_info(res)).then(_ => res); }, err => new Response(err.toString())));
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-scope.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-scope.py index 46151cd..5bab5b0 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-scope.py +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-scope.py
@@ -9,4 +9,6 @@ values = [isomorphic_decode(value) for value in values] normalized[isomorphic_decode(key.upper())] = values + response.headers.append(b"Content-Type", b"text/html") + return json.dumps(normalized)
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js index aaabdc3..e54cb6dd 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js
@@ -1,10 +1,48 @@ 'use strict'; importScripts("/resources/testharness.js"); +const map = new Map(); + self.addEventListener('fetch', event => { const url = new URL(event.request.url); if (!url.searchParams.has('stream')) return; + if (url.searchParams.has('observe-cancel')) { + const id = url.searchParams.get('id'); + if (id === undefined) { + event.respondWith(new Error('error')); + return; + } + event.waitUntil(new Promise(resolve => { + map.set(id, {label: 'pending', resolve}); + })); + + const stream = new ReadableStream({ + cancel() { + map.get(id).label = 'cancelled'; + } + }); + event.respondWith(new Response(stream)); + return; + } + + if (url.searchParams.has('query-cancel')) { + const id = url.searchParams.get('id'); + if (id === undefined) { + event.respondWith(new Error('error')); + return; + } + const entry = map.get(id); + if (entry === undefined) { + event.respondWith(new Error('not found')); + return; + } + map.delete(id); + entry.resolve(); + event.respondWith(new Response(entry.label)); + return; + } + if (url.searchParams.has('use-fetch-stream')) { event.respondWith(async function() { const response = await fetch('pass.txt');
diff --git a/third_party/blink/web_tests/external/wpt/visual-viewport/resize-event-order.html b/third_party/blink/web_tests/external/wpt/visual-viewport/resize-event-order.html new file mode 100644 index 0000000..41a13728 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/visual-viewport/resize-event-order.html
@@ -0,0 +1,72 @@ +<!doctype html> +<title>Visual Viewport Resize Event Order</title> +<meta charset=utf-8> +<link rel="help" href="https://wicg.github.io/visual-viewport/index.html"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<style> + iframe { + width: 300px; + height: 300px; + } +</style> + +<body> + <iframe srcdoc="<!DOCTYPE html>"></iframe> +</body> + +<script> + +async function oneRaf(win) { + return new Promise((resolve) => { + win.requestAnimationFrame(resolve); + }); +} + +// Runs the test on the given window object, asserts that event handlers on the +// DOMWindow object are fired before those on the VisualViewport object. +// `resizeFunc` is used to perform the resize. +async function runTest(win, resizeFunc) { + const resize_events = []; + + win.onresize = () => { resize_events.push('window-attribute'); } + win.addEventListener('resize', () => { resize_events.push('window-addEventListener'); }); + win.visualViewport.onresize = () => { resize_events.push('visualViewport-attribute'); } + win.visualViewport.addEventListener('resize', () => { + resize_events.push('visualViewport-addEventListener'); }); + + assert_equals(resize_events.toString(), '', 'PRECONDITION'); + resizeFunc(500, 600); + + await oneRaf(win); + + assert_equals(resize_events.toString(), + 'window-attribute,window-addEventListener,' + + 'visualViewport-attribute,visualViewport-addEventListener'); +} + +onload = () => { + // Test the event order in a top-level window which we will programmatically + // resize. + promise_test(async t => { + let popup = null; + test_driver.bless('Open a popup in a new window', () => { + popup = window.open('about:blank', 'newwindow', 'width=300,height=300'); + }); + await t.step_wait(() => popup != null, "Opened popup window"); + + await runTest(popup, (x, y) => {popup.resizeTo(x, y);}); + }, 'Popup: DOMWindow resize fired before VisualViewport.'); + + // Also test the resize resulting from an iframe's size change. + promise_test(async t => { + const iframe = frames[0]; + await runTest(iframe, (x, y) => {iframe.frameElement.style.width = x + 'px'; + iframe.frameElement.style.height = y + 'px'; + iframe.frameElement.offsetWidth; /* force reflow */}); + }, 'iframe: DOMWindow resize fired before VisualViewport.'); +} + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/visual-viewport/scroll-event-order.html b/third_party/blink/web_tests/external/wpt/visual-viewport/scroll-event-order.html new file mode 100644 index 0000000..5ab5e07 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/visual-viewport/scroll-event-order.html
@@ -0,0 +1,113 @@ +<!doctype html> +<title>Visual Viewport Scroll Event Order</title> +<meta charset=utf-8> +<link rel="help" href="https://wicg.github.io/visual-viewport/index.html"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<style> + #target { + width: 100px; + height: 100px; + background-color: red; + position: absolute; + top: 300vh; + } + + #scroller1,#scroller2 { + width: 200px; + height: 200px; + overflow: auto; + } + + #spacer { + width: 80px; + height: 1000px; + background-image: linear-gradient(45deg, #808080 25%, transparent 25%), + linear-gradient(-45deg, #808080 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, #808080 75%), + linear-gradient(-45deg, transparent 75%, #808080 75%); + background-size: 40px 40px; + background-position: 0 0, 0 20px, 20px -20px, -20px 0px; + } +</style> + +<body> + <div id="target"></div> + <div id="scroller1"><div id="spacer"></div></div> + <div id="scroller2"><div id="spacer"></div></div> +</body> + +<script> + +async function oneRaf() { + return new Promise((resolve) => { + window.requestAnimationFrame(resolve); + }); +} + +function pinch_zoom_in() { + return new test_driver.Actions() + .setContext(window) + .addPointer("finger1", "touch") + .addPointer("finger2", "touch") + .pointerMove(400, 250, {origin: "viewport", sourceName: "finger1"}) + .pointerMove(400, 350, {origin: "viewport", sourceName: "finger2"}) + .pointerDown({sourceName: "finger1"}) + .pointerDown({sourceName: "finger2"}) + .pointerMove(400, 200, {origin: "viewport", sourceName: "finger1"}) + .pointerMove(400, 400, {origin: "viewport", sourceName: "finger2"}) + .pointerUp({sourceName: "finger1"}) + .pointerUp({sourceName: "finger2"}) + .send(); +} + +const scroller1 = document.getElementById('scroller1'); +const scroller2 = document.getElementById('scroller2'); + +promise_test(async t => { + // Pinch-zoom in so that the scrollIntoView call below causes scrolling in + // both the layout and visual viewports within the same rAF. + await pinch_zoom_in(); + assert_greater_than(window.visualViewport.scale, 1, 'Must have zoomed in'); + + await oneRaf(); + + const scroll_events = []; + + // Register the scroll handlers on the window, visualViewport, and both + // <div> scrollers. + { + window.onscroll = () => { scroll_events.push('window-attribute'); } + window.addEventListener('scroll', () => { scroll_events.push('window-addEventListener'); }); + window.visualViewport.onscroll = () => { scroll_events.push('visualViewport-attribute'); } + window.visualViewport.addEventListener('scroll', () => { + scroll_events.push('visualViewport-addEventListener'); }); + scroller1.addEventListener('scroll', + () => { scroll_events.push('scroller1'); }); + scroller2.addEventListener('scroll', + () => { scroll_events.push('scroller2'); }); + } + + // Cause scrolling in each scroller and scrollIntoView so that the layout + // and visual viewports both scroll. + scroller1.scrollTop = 200; + document.getElementById('target').scrollIntoView(); + scroller2.scrollTop = 200; + + // Wait a rAF since scroll events are delievered as part of the event loop. + await oneRaf(); + + // The scroll events must be delivered in the order they were executed, + // scroller1 first, then the viewport (window then visualViewport), then + // scroller2. + assert_equals(scroll_events.toString(), + 'scroller1,' + + 'window-attribute,window-addEventListener,' + + 'visualViewport-attribute,visualViewport-addEventListener,' + + 'scroller2'); +}, "Scroll event ordering"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/corp.har b/third_party/blink/web_tests/external/wpt/web-bundle/resources/corp.har index 36c2a01..59b20da 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/corp.har +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/corp.har
@@ -122,6 +122,10 @@ "value": "text/html" }, { + "name": "Cross-Origin-Embedder-Policy", + "value": "require-corp" + }, + { "name": "Cross-Origin-Resource-Policy", "value": "cross-origin" } @@ -133,4 +137,4 @@ } ] } -} \ No newline at end of file +}
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/nested/nested-sub.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/nested/nested-sub.wbn index c50fc67..840773f8 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/nested/nested-sub.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/nested/nested-sub.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/cors/corp.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/cors/corp.wbn index ef482958..6679b0bf 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/cors/corp.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/cors/corp.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-b1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-b1.wbn index 53aa4ba..943e00e6 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-b1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-b1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin-b1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin-b1.wbn index c2f7370..4d2d42d 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin-b1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin-b1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn index a02538b..e003f39 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn index 77ffd6e9..f9b8e014 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2-b1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2-b1.wbn index 23130c2d..0d9a6e743 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2-b1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2-b1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn index 6097e1a..f23fb4f 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location-b1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location-b1.wbn index 44873d8..a566446 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location-b1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location-b1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location.wbn index b0dd7e2b..54d8f40fc 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/location.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/nested-main.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/nested-main.wbn index e33d716..9c21e73 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/nested-main.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/nested-main.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction-b1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction-b1.wbn index bc01a91..e031084 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction-b1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction-b1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction.wbn index 0edf459..73a02a0 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/path-restriction.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/static-element.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/static-element.wbn index 4d06cea7..dd50ef3 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/static-element.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/static-element.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/subresource.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/subresource.wbn index 297e1ef6c..840773f8 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/subresource.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/subresource.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js index 3d159d3..e2ddeca0 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
@@ -10,7 +10,7 @@ var ENCODER_CONFIG = null; promise_setup(async () => { const config = { - '?av1': {codec: 'av01.0.04M.08'}, // Not supported yet + '?av1': {codec: 'av01.0.04M.08'}, '?vp8': {codec: 'vp8'}, '?vp9_p0': {codec: 'vp09.00.10.08'}, '?vp9_p2': {codec: 'vp09.02.10.10'},
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.https.any.js index 3ac6889..876a591d 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.https.any.js
@@ -372,8 +372,9 @@ }) .then(_ => { // Ensure feeding the source after closing doesn't crash. - source.addFrame(); - return promise_rejects_dom(t, 'InvalidStateError', decoder.decode()); + assert_throws_js(TypeError, () => { + source.addFrame(); + }); }); }, 'Test ReadableStream of gif');
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js index e4ed3b8..c380fa77 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js
@@ -10,7 +10,7 @@ var ENCODER_CONFIG = null; promise_setup(async () => { const config = { - '?av1': {codec: 'av01.0.04M.08'}, // Not supported yet + '?av1': {codec: 'av01.0.04M.08'}, '?vp8': {codec: 'vp8'}, '?vp9_p0': {codec: 'vp09.00.10.08'}, '?vp9_p2': {codec: 'vp09.02.10.10'},
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/temporal-svc-encoding.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/temporal-svc-encoding.https.any.js index c759250..7cf7225 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/temporal-svc-encoding.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/temporal-svc-encoding.https.any.js
@@ -8,7 +8,7 @@ var ENCODER_CONFIG = null; promise_setup(async () => { const config = { - '?av1': {codec: 'av01.0.04M.08'}, // Not supported yet + '?av1': {codec: 'av01.0.04M.08'}, '?vp8': {codec: 'vp8'}, '?vp9': {codec: 'vp09.00.10.08'}, '?h264': {codec: 'avc1.42001E', avc: {format: 'annexb'}}
diff --git a/third_party/blink/web_tests/fast/css/invalidation/font-face-load-expected.txt b/third_party/blink/web_tests/fast/css/invalidation/font-face-load-expected.txt index eb8dfbb..325661f 100644 --- a/third_party/blink/web_tests/fast/css/invalidation/font-face-load-expected.txt +++ b/third_party/blink/web_tests/fast/css/invalidation/font-face-load-expected.txt
@@ -2,7 +2,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS internals.updateStyleAndReturnAffectedElementCount() is 5 +PASS internals.updateStyleAndReturnAffectedElementCount() is 1 PASS getComputedStyle(x).color is "rgb(0, 128, 0)" PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/fast/css/invalidation/font-face-load.html b/third_party/blink/web_tests/fast/css/invalidation/font-face-load.html index cbf46e9..722909c 100644 --- a/third_party/blink/web_tests/fast/css/invalidation/font-face-load.html +++ b/third_party/blink/web_tests/fast/css/invalidation/font-face-load.html
@@ -17,7 +17,7 @@ document.fonts.load("40px dummy"); if (window.internals) - shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "5"); + shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1"); shouldBeEqualToString("getComputedStyle(x).color", "rgb(0, 128, 0)"); </script>
diff --git a/third_party/blink/web_tests/fast/css/invalidation/inherit-through-insertion-point-v0.html b/third_party/blink/web_tests/fast/css/invalidation/inherit-through-insertion-point-v0.html index ea97581..e8de97c 100644 --- a/third_party/blink/web_tests/fast/css/invalidation/inherit-through-insertion-point-v0.html +++ b/third_party/blink/web_tests/fast/css/invalidation/inherit-through-insertion-point-v0.html
@@ -20,6 +20,6 @@ host.offsetTop; root.querySelector("#shadowDiv").style.color = "red"; assert_true(!!window.internals, "This test only works with --expose-internals-for-testing."); - assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 2, "Inheritance propagation should stop at #stopInherit element."); + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 1, "Inheritance propagation should stop at #stopInherit element."); }, "Inheritance propagation should not cause full subtree recalcs in flat-tree."); </script>
diff --git a/third_party/blink/web_tests/fast/css/recalc-inherit-001-expected.txt b/third_party/blink/web_tests/fast/css/recalc-inherit-001-expected.txt index 85672d2..9397350c 100644 --- a/third_party/blink/web_tests/fast/css/recalc-inherit-001-expected.txt +++ b/third_party/blink/web_tests/fast/css/recalc-inherit-001-expected.txt
@@ -2,7 +2,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS internals.updateStyleAndReturnAffectedElementCount() is 2 +PASS internals.updateStyleAndReturnAffectedElementCount() is 1 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css/recalc-inherit-001.html b/third_party/blink/web_tests/fast/css/recalc-inherit-001.html index acd8f4b9..af5f9a62 100644 --- a/third_party/blink/web_tests/fast/css/recalc-inherit-001.html +++ b/third_party/blink/web_tests/fast/css/recalc-inherit-001.html
@@ -33,5 +33,5 @@ document.getElementById("t").style.color = "pink"; if (window.internals) - shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "2"); + shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1"); </script>
diff --git a/third_party/blink/web_tests/fast/lists/list-color-change-no-layout-expected.txt b/third_party/blink/web_tests/fast/lists/list-color-change-no-layout-expected.txt index dcfa703..1fe01fb 100644 --- a/third_party/blink/web_tests/fast/lists/list-color-change-no-layout-expected.txt +++ b/third_party/blink/web_tests/fast/lists/list-color-change-no-layout-expected.txt
@@ -2,7 +2,7 @@ TEST COMPLETE -PASS internals.updateStyleAndReturnAffectedElementCount() is 3 +PASS internals.updateStyleAndReturnAffectedElementCount() is 2 PASS internals.needsLayoutCount() is 0 Should not layout when list color changes. List item
diff --git a/third_party/blink/web_tests/fast/lists/list-color-change-no-layout.html b/third_party/blink/web_tests/fast/lists/list-color-change-no-layout.html index 176c93a..f2a28c05 100644 --- a/third_party/blink/web_tests/fast/lists/list-color-change-no-layout.html +++ b/third_party/blink/web_tests/fast/lists/list-color-change-no-layout.html
@@ -6,7 +6,7 @@ var target = document.getElementById('target'); target.style.color = 'green'; if (window.internals) { - shouldBe('internals.updateStyleAndReturnAffectedElementCount()', '3'); + shouldBe('internals.updateStyleAndReturnAffectedElementCount()', '2'); shouldBe('internals.needsLayoutCount()', '0'); } }
diff --git a/third_party/blink/web_tests/fast/multicol/box-reflect-and-mask-crash.html b/third_party/blink/web_tests/fast/multicol/box-reflect-and-mask-crash.html new file mode 100644 index 0000000..61acc47 --- /dev/null +++ b/third_party/blink/web_tests/fast/multicol/box-reflect-and-mask-crash.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<div style="columns:2; column-gap:0; column-fill:auto; height:100px;"> + <div style="columns:1; -webkit-box-reflect:right; -webkit-mask:url('?');"> + <div></div> + <div style="break-before:column;"> + <span style="-webkit-box-reflect:right; -webkit-mask:url('?');"></span> + </div> + </div> +</div> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + test(()=> {}, "no crash"); +</script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt index 88ffc0a..31eb852 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
@@ -45,7 +45,6 @@ "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [352, 288], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index ce46b04..060045c 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [150, 60], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt index d8462e0c..f867ea2 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt
@@ -45,7 +45,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [528, 432], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/inheritance-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/inheritance-expected.txt new file mode 100644 index 0000000..1686f10 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/inheritance-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Property color-scheme has initial value normal +PASS Property color-scheme inherits +FAIL Property color-adjust has initial value economy assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property color-adjust inherits assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +PASS Property forced-color-adjust has initial value auto +FAIL Property forced-color-adjust inherits assert_equals: expected "preserve-parent-color" but got "auto" +FAIL Property print-color-adjust has initial value economy assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property print-color-adjust inherits assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt new file mode 100644 index 0000000..1fbbb61 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/css-color-adjust/parsing/print-color-adjust-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL e.style['print-color-adjust'] = "exact" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['print-color-adjust'] = "economy" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color-adjust'] = "exact" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color-adjust'] = "economy" should set the property value assert_not_equals: property should be set got disallowed value "" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index ed99cd7..211d236 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [225, 90], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index ed99cd7..211d236 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [225, 90], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt new file mode 100644 index 0000000..5021f0f --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE MESSAGE: Clear-Site-Data header on 'https://cookies.not-example.test:8443/cookies/resources/clear-site-data.php': Cleared data types: "cookies". Clearing channel IDs and HTTP authentication cache is currently not supported, as it breaks active network connections. +This is a testharness.js-based test. +PASS Clearing partitioned cookies +FAIL Clearing partitioned cookies in another partition assert_equals: expected "" but got "__Host-pc=0" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https.html b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https.html new file mode 100644 index 0000000..92099a4 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/clear-site-data.https.html
@@ -0,0 +1,25 @@ +<!doctype html> +<head> +<title>Test Clear-Site-Data and partitioned cookies</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/testharness-helpers.js"></script> +</head> +<body> +<script> + +if (window.location.hostname != ORIGINAL_HOST) { + window.location.hostname = ORIGINAL_HOST; +} + +const iframe = document.createElement("iframe"); +const url = new URL( + "/cookies/partitioned-cookies/resources/" + + "clear-site-data-cross-site-frame.html?step=1", + `https://${TEST_HOST}:${window.location.port}`); +iframe.src = String(url); +document.body.appendChild(iframe); +fetch_tests_from_window(iframe.contentWindow); + +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-frame.html b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-frame.html new file mode 100644 index 0000000..5bae9fc --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-frame.html
@@ -0,0 +1,51 @@ +<!doctype html> +<head> +<title>Test Clear-Site-Data and partitioned cookies</title> +<script src="/resources/testharness.js"></script> +<script src="/cookies/resources/testharness-helpers.js"></script> +</head> +<body> +<script> + +const step = new URL(location.href).searchParams.get("step"); +const originFromHost = + host => `https://${host}:${window.location.port}`; + +promise_test(async () => { + assert_equals(window.location.hostname, TEST_HOST); + assert_true(step == 1 || step == 2); + + if (step == 1) { + assert_equals(document.cookie, ""); + + const cookieLine = "__Host-pc=0; Secure; Path=/; SameSite=None; Partitioned"; + + document.cookie = cookieLine; + assert_true(document.cookie.includes("__Host-pc")); + + // Test that Clear-Site-Data deletes the cookie in this partition. + const resp = await fetch( + "/cookies/resources/clear-site-data.php", {method: "GET"}); + assert_equals(resp.status, 200); + assert_equals(document.cookie, ""); + + // Reset the cookie, we will use this later to verify that this cookie + // should not get removed when another partition receives Clear-Site-Data. + document.cookie = cookieLine; + } + + assert_true(document.cookie.includes("__Host-pc")); + + if (step == 1) { + const url = new URL( + "/cookies/partitioned-cookies/resources/" + + "clear-site-data-cross-site-window.html", + originFromHost(TEST_HOST)); + const popup = window.open(String(url)); + fetch_tests_from_window(popup); + } +}, (step == 1 ? "Clearing partitioned cookies" + : "Clear-Site-Data does not leak across partitions")); + +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-window.html b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-window.html new file mode 100644 index 0000000..16d44391 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-cross-site-window.html
@@ -0,0 +1,34 @@ +<!doctype html> +<head> +<title>Test Clear-Site-Data and partitioned cookies</title> +<script src="/resources/testharness.js"></script> +<script src="/cookies/resources/testharness-helpers.js"></script> +</head> +<body> +<script> + +promise_test(async () => { + assert_equals(window.location.hostname, TEST_HOST); + assert_equals(document.cookie, ""); + + const cookieLine = "__Host-pc=0; Secure; Path=/; SameSite=None; Partitioned"; + + document.cookie = cookieLine; + assert_true(document.cookie.includes("__Host-pc")); + + // Test that Clear-Site-Data deletes the cookie in this partition. + const resp = await fetch( + "/cookies/resources/clear-site-data.php", {method: "GET"}); + assert_equals(resp.status, 200); + assert_equals(document.cookie, ""); + + const url = new URL( + "/cookies/partitioned-cookies/resources/" + + "clear-site-data-same-site-window.html", + `https://${ORIGINAL_HOST}:${window.location.port}`); + const popup = window.open(String(url)); + fetch_tests_from_window(popup); +}, "Clearing partitioned cookies in another partition"); + +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-same-site-window.html b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-same-site-window.html new file mode 100644 index 0000000..60ab3dd8 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/partitioned-cookies/resources/clear-site-data-same-site-window.html
@@ -0,0 +1,26 @@ +<!doctype html> +<head> +<title>Test Clear-Site-Data and partitioned cookies</title> +<script src="/resources/testharness.js"></script> +<script src="/cookies/resources/testharness-helpers.js"></script> +</head> +<body> +<script> + +// We verify that calling Clear-Site-Data in another partition did +// not delete this partition's cookie. +test(() => { + assert_equals(window.location.hostname, ORIGINAL_HOST); + + const iframe = document.createElement("iframe"); + const url = new URL( + "/cookies/partitioned-cookies/resources/" + + "clear-site-data-cross-site-frame.html?step=2", + `https://${TEST_HOST}:${window.location.port}`); + iframe.src = String(url); + document.body.appendChild(iframe); + fetch_tests_from_window(iframe.contentWindow); +}, "Opened page from first partition"); + +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/cookies/resources/clear-site-data.php b/third_party/blink/web_tests/http/tests/cookies/resources/clear-site-data.php new file mode 100644 index 0000000..2ca2fea --- /dev/null +++ b/third_party/blink/web_tests/http/tests/cookies/resources/clear-site-data.php
@@ -0,0 +1,4 @@ +<?php +header("Content-Type: text/plain"); +header('Clear-Site-Data: "cookies"'); +?>
diff --git a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js index f49d40b..11e530d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js +++ b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js
@@ -42,10 +42,8 @@ } function populateFileSystem(name) { - var urlPrefix = - TestRunner.mainTarget.inspectedURL().substr(0, TestRunner.mainTarget.inspectedURL().lastIndexOf('/') + 1); var url = TestRunner.url('resources/' + name); - return Root.Runtime.loadResourcePromise(url).then(function(text) { + return fetch(url).then(result => result.text()).then(function(text) { fs.root.addFile(name, text); }); }
diff --git a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js index 9e49fb1..4785de03 100644 --- a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js +++ b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js
@@ -58,7 +58,7 @@ function loadResource(name) { var url = TestRunner.url('resources/' + name); - return Root.Runtime.loadResourcePromise(url).then(function(text) { + return fetch(url).then(result => result.text()).then(function(text) { resources[name] = text; }); }
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout-expected.txt new file mode 100644 index 0000000..e16c4588 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout-expected.txt
@@ -0,0 +1,8 @@ +Tests that an InvalidateLayout trace event is dispatched at LocalFrameView::ScheduleRelayout +Recording started +Tracing complete +Trace event received +Event name: InvalidateLayout +Type of event frame: string +Type of event nodeId: number +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout.js b/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout.js new file mode 100644 index 0000000..28fb226 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/timeline/invalidate-layout.js
@@ -0,0 +1,27 @@ +(async function(testRunner) { + const {session, dp} = await testRunner.startBlank('Tests that an InvalidateLayout trace event is dispatched at LocalFrameView::ScheduleRelayout'); + + const TracingHelper = await testRunner.loadScript('../resources/tracing-test.js'); + const tracingHelper = new TracingHelper(testRunner, session); + await tracingHelper.startTracing(); + + dp.Page.navigate({url: 'http://127.0.0.1:8000/inspector-protocol/resources/relayout.html'}); + + // Wait for trace events. + await new Promise(resolve => setTimeout(resolve, 1000)) + + const devtoolsEvents = await tracingHelper.stopTracing(); + const invalidateLayoutEvents = devtoolsEvents.filter(event => event.name === 'InvalidateLayout'); + if (!invalidateLayoutEvents.length) { + testRunner.log('FAIL: did not receive any InvalidateRelayout event'); + testRunner.completeTest(); + return; + } + + const invalidateLayoutEvent = invalidateLayoutEvents[0]; + testRunner.log('Trace event received'); + testRunner.log(`Event name: ${invalidateLayoutEvent.name}`); + testRunner.log(`Type of event frame: ${typeof invalidateLayoutEvent.args.data.frame}`); + testRunner.log(`Type of event nodeId: ${typeof invalidateLayoutEvent.args.data.nodeId}`); + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index 2f3bf8c..eb16f6f 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [150, 60], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-color-adjust/inheritance-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-color-adjust/inheritance-expected.txt new file mode 100644 index 0000000..1686f10 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-color-adjust/inheritance-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Property color-scheme has initial value normal +PASS Property color-scheme inherits +FAIL Property color-adjust has initial value economy assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property color-adjust inherits assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +PASS Property forced-color-adjust has initial value auto +FAIL Property forced-color-adjust inherits assert_equals: expected "preserve-parent-color" but got "auto" +FAIL Property print-color-adjust has initial value economy assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property print-color-adjust inherits assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/css/css-color-adjust/inheritance-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/css/css-color-adjust/inheritance-expected.txt new file mode 100644 index 0000000..1686f10 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/css/css-color-adjust/inheritance-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Property color-scheme has initial value normal +PASS Property color-scheme inherits +FAIL Property color-adjust has initial value economy assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property color-adjust inherits assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +PASS Property forced-color-adjust has initial value auto +FAIL Property forced-color-adjust inherits assert_equals: expected "preserve-parent-color" but got "auto" +FAIL Property print-color-adjust has initial value economy assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property print-color-adjust inherits assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt index 5d2502f..ae935f5 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -45,7 +45,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [352, 288], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index e841af8..2280a61 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [150, 60], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt index e481296..5db5b0d2 100644 --- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -45,7 +45,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [352, 288], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-color-adjust/inheritance-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-color-adjust/inheritance-expected.txt new file mode 100644 index 0000000..1686f10 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-color-adjust/inheritance-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Property color-scheme has initial value normal +PASS Property color-scheme inherits +FAIL Property color-adjust has initial value economy assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property color-adjust inherits assert_true: color-adjust doesn't seem to be supported in the computed style expected true got false +PASS Property forced-color-adjust has initial value auto +FAIL Property forced-color-adjust inherits assert_equals: expected "preserve-parent-color" but got "auto" +FAIL Property print-color-adjust has initial value economy assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +FAIL Property print-color-adjust inherits assert_true: print-color-adjust doesn't seem to be supported in the computed style expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt index 0f075a0..1f9ff19 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,7 +61,6 @@ "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'", "bounds": [150, 60], "contentsOpaqueForText": true, - "drawsContent": false, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/synthetic_gestures/basic_pinch_zoom.html b/third_party/blink/web_tests/synthetic_gestures/basic_pinch_zoom.html new file mode 100644 index 0000000..70e085f --- /dev/null +++ b/third_party/blink/web_tests/synthetic_gestures/basic_pinch_zoom.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<script src='../resources/testharness.js'></script> +<script src='../resources/testharnessreport.js'></script> +<script src='../resources/testdriver.js'></script> +<script src='../resources/testdriver-actions.js'></script> +<script src='../resources/testdriver-vendor.js'></script> +<style> + body, html { + margin: 0; + height: 10000px; + } +</style> + +<script> + // Test that a basic pointer action sequence resulting in a pinch-zoom works + // without crashing or DCHECK. + window.onload = () => { + promise_test(() => { + assert_equals(window.visualViewport.scale, 1, + "PRECONDITION: Page loaded unzoomed."); + const pinch_zoom = new test_driver.Actions() + .setContext(window) + .addPointer("finger1", "touch") + .addPointer("finger2", "touch") + .pointerMove(400, 250, {origin: "viewport", sourceName: "finger1"}) + .pointerMove(400, 350, {origin: "viewport", sourceName: "finger2"}) + .pointerDown({sourceName: "finger1"}) + .pointerDown({sourceName: "finger2"}) + .pointerMove(400, 100, {origin: "viewport", sourceName: "finger1"}) + .pointerMove(400, 500, {origin: "viewport", sourceName: "finger2"}) + .pointerUp({sourceName: "finger1"}) + .pointerUp({sourceName: "finger2"}) + .send(); + + return pinch_zoom.then(() => { + assert_greater_than(window.visualViewport.scale, 1.5, + "Action must have caused pinch-zoom."); + }); + }, 'Simulated pinch-zoom with test_driver Actions API'); + + } +</script>
diff --git a/third_party/blink/web_tests/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt b/third_party/blink/web_tests/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt new file mode 100644 index 0000000..80040e9 --- /dev/null +++ b/third_party/blink/web_tests/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS Cookie access from top-level fenced frame +PASS Cookie access from iframe nested in a fenced frame +PASS Cookie access from nested fenced frame +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt b/third_party/blink/web_tests/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt new file mode 100644 index 0000000..80040e9 --- /dev/null +++ b/third_party/blink/web_tests/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/unique-cookie-partition.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS Cookie access from top-level fenced frame +PASS Cookie access from iframe nested in a fenced frame +PASS Cookie access from nested fenced frame +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/README.txt b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/README.txt index 65f41f5..32ed0c4 100644 --- a/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/README.txt +++ b/third_party/blink/web_tests/virtual/oopr-canvas2d/fast/canvas/README.txt
@@ -1,3 +1,3 @@ # This suite runs the tests in LayoutTests/fast/canvas/ with --enable-features=CanvasOopRasterization, -# --enable-accelerated-2d-canvas, --enable-oop-rasterization, and --enable-gpu-rasterization. -# See the virtual_test_suites() method in tools/blinkpy/web_tests/port/base.py. \ No newline at end of file +# --enable-accelerated-2d-canvas, and --enable-gpu-rasterization. +# See the virtual_test_suites() method in tools/blinkpy/web_tests/port/base.py.
diff --git a/third_party/blink/web_tests/virtual/partitioned-cookies/external/wpt/html/cross-origin-embedder-policy/anonymous-iframe/cookie-store.tentative.https.window-expected.txt b/third_party/blink/web_tests/virtual/partitioned-cookies/external/wpt/html/cross-origin-embedder-policy/anonymous-iframe/cookie-store.tentative.https.window-expected.txt deleted file mode 100644 index ab6abb9..0000000 --- a/third_party/blink/web_tests/virtual/partitioned-cookies/external/wpt/html/cross-origin-embedder-policy/anonymous-iframe/cookie-store.tentative.https.window-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Set/Get cookie via JS API assert_equals: expected "cookie_value_1" but got "" -FAIL Get Cookie via subresource requests assert_equals: expected (string) "cookie_value_1" but got (undefined) undefined -FAIL Set Cookie via subresource requests assert_equals: expected "cookie_value_2" but got "" -FAIL Set Cookie via navigation requests assert_equals: expected "cookie_value_3" but got "" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt b/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt new file mode 100644 index 0000000..5e23b5e --- /dev/null +++ b/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/cookies/partitioned-cookies/clear-site-data.https-expected.txt
@@ -0,0 +1,9 @@ +CONSOLE MESSAGE: Clear-Site-Data header on 'https://cookies.not-example.test:8443/cookies/resources/clear-site-data.php': Cleared data types: "cookies". Clearing channel IDs and HTTP authentication cache is currently not supported, as it breaks active network connections. +CONSOLE MESSAGE: Clear-Site-Data header on 'https://cookies.not-example.test:8443/cookies/resources/clear-site-data.php': Cleared data types: "cookies". Clearing channel IDs and HTTP authentication cache is currently not supported, as it breaks active network connections. +This is a testharness.js-based test. +PASS Clearing partitioned cookies +PASS Clearing partitioned cookies in another partition +PASS Opened page from first partition +PASS Clear-Site-Data does not leak across partitions +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html index d4858a7c..600b69f 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html
@@ -35,7 +35,7 @@ t.step_timeout(() => t.done(), 3000); const frame = setupTest("no coep"); const result = await nextValueFromServer(no_coep_key); - t.unreached_func("embedded page should not be loaded."); + assert_unreached("embedded page should not be loaded."); }, "Create fencedframe without COEP header"); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html new file mode 100644 index 0000000..28fada754 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script src="utils.js"></script> +<title>Page loaded in a frame in a fenced frame tree</title> +<script> + // This page is loaded either in an iframe or a fenced frame + // nested inside a root fenced frame. + document.cookie = 'G=nested_in_fenced_frame; SameSite=Lax'; + const cookie_value_key = KEYS["cookie_value"] + const cookie_value = document.cookie; + writeValueToServer(cookie_value_key, cookie_value); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html.headers new file mode 100644 index 0000000..1b63235 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/cookie-access.https.html.headers
@@ -0,0 +1 @@ +Supports-Loading-Mode: fenced-frame
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html new file mode 100644 index 0000000..f445fae --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="utils.js"></script> +<title>Fenced frame accessing cookies</title> + +<body> +<script> +async function init() { + // This file is meant to run in a <fencedframe>. It sets up multiple frames + // in the following arrangements: + // 1.) A top-level fenced frame + // 2.) An iframe within a fenced frame + // 3.) A nested fenced frame + const test_type = new URL(location.href).searchParams.get('test_type'); + + // Set cookies in the root fenced frame via document and cookieStore APIs. + const cookie_value_key = KEYS["cookie_value"]; + document.cookie = 'C=fenced; SameSite=Lax'; + document.cookie = 'D=fenced; SameSite=None; Secure'; + await cookieStore.set('E', 'fenced'); + + switch (test_type) { + case "top-level fenced frame": + const cookie_value = document.cookie; + writeValueToServer(cookie_value_key, cookie_value); + break; + case "nested iframe": + const iframe = document.createElement('iframe'); + document.body.append(iframe); + iframe.src = `cookie-access.https.html`; + break; + case "nested fenced frame": + const ff = attachFencedFrame("cookie-access.https.html"); + break; + } +} + +init(); +</script> +</body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html.headers new file mode 100644 index 0000000..e2b453f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unique-cookie-partition-inner.https.html.headers
@@ -0,0 +1,2 @@ +Supports-Loading-Mode: fenced-frame +Set-Cookie: F=fenced; SameSite=Lax
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js index 58acdc4..31280aa 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -109,6 +109,8 @@ "resize_lock_report_inner_dimensions" : "00000000-0000-0000-0000-00000000004A", "csp" : "00000000-0000-0000-0000-00000000004B", + + "cookie_value" : "00000000-0000-0000-0000-00000000004C", // Add keys above this list, incrementing the key UUID in hexadecimal }
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/unique-cookie-partition.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/unique-cookie-partition.https.html new file mode 100644 index 0000000..090aa35a --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/unique-cookie-partition.https.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<title>Test cookies accessed from a Fenced Frame Tree</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/utils.js"></script> + +<body> +<script> +const cookie_value_key = KEYS["cookie_value"]; +const kAssertion = "Cookie accessed from unique fenced frame tree partition "; +const kAssertion_outer = "Cookie values changed in the fenced frame tree should not impact the outer frame"; + +async function runTest(test_type) { + document.cookie = 'A=outer; SameSite=Lax'; + document.cookie = 'B=outer; SameSite=None; Secure'; + const fenced_frame = + attachFencedFrame(`resources/unique-cookie-partition-inner.https.html?test_type=${test_type}`); + + result = await nextValueFromServer(cookie_value_key); + switch (test_type) { + case "top-level fenced frame": + assert_equals(result, "F=fenced; C=fenced; D=fenced; E=fenced", kAssertion + test_type); + break; + case "nested iframe": + assert_equals(result, "F=fenced; C=fenced; D=fenced; G=nested_in_fenced_frame; E=fenced", kAssertion + test_type); + break; + case "nested fenced frame": + assert_equals(result, "G=nested_in_fenced_frame", kAssertion + test_type); + break; + } + + // The cookie values changed in the fenced frame tree should not impact the outer frame. + const result_outer_frame = document.cookie; + assert_equals(result_outer_frame, "A=outer; B=outer", kAssertion_outer); + + // Clean up the fenced frame + document.body.removeChild(fenced_frame); +} + +promise_test(async () => { + return runTest("top-level fenced frame"); +}, "Cookie access from top-level fenced frame"); + +promise_test(async () => { + return runTest("nested iframe"); +}, "Cookie access from iframe nested in a fenced frame"); + +promise_test(async () => { + return runTest("nested fenced frame"); +}, "Cookie access from nested fenced frame"); +</script> +</body>
diff --git a/third_party/blink/web_tests/wpt_internal/webcodecs/basic_video_encoding.https.any.js b/third_party/blink/web_tests/wpt_internal/webcodecs/basic_video_encoding.https.any.js deleted file mode 100644 index 17b271eb..0000000 --- a/third_party/blink/web_tests/wpt_internal/webcodecs/basic_video_encoding.https.any.js +++ /dev/null
@@ -1,154 +0,0 @@ -// META: global=window,dedicatedworker -// META: script=/wpt_internal/webcodecs/encoder_utils.js - -async function encode_decode_test(codec, avc_format) { - const acc = "prefer-software"; - const w = 320; - const h = 200; - let next_ts = 0 - let frames_to_encode = 16; - let frames_encoded = 0; - let frames_decoded = 0; - let errors = 0; - - let decoder = new VideoDecoder({ - output(frame) { - assert_equals(frame.visibleRect.width, w, "visibleRect.width"); - assert_equals(frame.visibleRect.height, h, "visibleRect.height"); - assert_equals(frame.timestamp, next_ts++, "timestamp"); - frames_decoded++; - assert_true(validateBlackDots(frame, frame.timestamp), - "frame doesn't match. ts: " + frame.timestamp); - frame.close(); - }, - error(e) { - errors++; - console.log(e.message); - } - }); - - const encoder_init = { - output(chunk, metadata) { - let config = metadata.decoderConfig; - if (config) { - config.hardwareAcceleration = acc; - decoder.configure(config); - } - decoder.decode(chunk); - frames_encoded++; - }, - error(e) { - errors++; - console.log(e.message); - } - }; - - let encoder_config = { - codec: codec, - hardwareAcceleration: acc, - width: w, - height: h, - bitrate: 1000000, - bitrateMode: "constant" - }; - - if (avc_format != null) { - encoder_config.avc = {format: avc_format}; - } - - let encoder = new VideoEncoder(encoder_init); - encoder.configure(encoder_config); - - for (let i = 0; i < frames_to_encode; i++) { - let frame = createFrame(w, h, i); - let keyframe = (i % 5 == 0); - encoder.encode(frame, { keyFrame: keyframe }); - frame.close(); - } - await encoder.flush(); - await decoder.flush(); - encoder.close(); - decoder.close(); - assert_equals(frames_encoded, frames_to_encode); - assert_equals(frames_decoded, frames_to_encode); - assert_equals(errors, 0); -} - -async function encode_test(codec) { - const acc = "prefer-software"; - let w = 320; - let h = 200; - let next_ts = 0 - let frames_to_encode = 25; - let frames_processed = 0; - let errors = 0; - - let process_video_chunk = function (chunk, metadata) { - assert_greater_than_equal(chunk.timestamp, next_ts++); - let config = metadata.decoderConfig; - let data = new Uint8Array(chunk.data); - let type = (chunk.timestamp % 5 == 0) ? "key" : "delta"; - assert_equals(chunk.type, type); - assert_greater_than_equal(data.length, 0); - if (config) { - assert_equals(config.codec, codec); - assert_equals(config.codedWidth, w); - assert_equals(config.codedHeight, h); - let data = new Uint8Array(config.description); - } - frames_processed++; - }; - - const init = { - output: process_video_chunk, - error: (e) => { - errors++; - console.log(e.message); - }, - }; - const params = { - codec: codec, - hardwareAcceleration: acc, - width: w, - height: h, - bitrate: 5000000, - framerate: 24, - }; - let encoder = new VideoEncoder(init); - encoder.configure(params); - for (let i = 0; i < frames_to_encode; i++) { - let size_mismatch = (i % 16); - let frame = createFrame(w + size_mismatch, h + size_mismatch, i); - let keyframe = (i % 5 == 0); - encoder.encode(frame, { keyFrame: keyframe }); - frame.close(); - } - await encoder.flush(); - encoder.close(); - assert_equals(frames_processed, frames_to_encode); - assert_equals(errors, 0); -} - -promise_test( - encode_test.bind(null, 'vp09.00.10.08'), 'encoding vp9 profile0'); - -promise_test( - encode_test.bind(null, 'vp09.02.10.10'), 'encoding vp9 profile2'); - -promise_test( - encode_decode_test.bind(null, 'vp09.02.10.10', null), - 'encoding and decoding vp9 profile2'); - -promise_test(encode_test.bind(null, 'vp8'), 'encoding vp8'); - -promise_test( - encode_decode_test.bind(null, 'vp8', null), - 'encoding and decoding vp8'); - -promise_test( - encode_decode_test.bind(null, 'avc1.42001E', 'annexb'), - 'encoding and decoding avc1.42001E (annexb)'); - -promise_test( - encode_decode_test.bind(null, 'avc1.42001E', 'avc'), - 'encoding and decoding avc1.42001E (avc)');
diff --git a/third_party/blink/web_tests/wpt_internal/webcodecs/encoder_utils.js b/third_party/blink/web_tests/wpt_internal/webcodecs/encoder_utils.js index a6f9885..66bb4d6 100644 --- a/third_party/blink/web_tests/wpt_internal/webcodecs/encoder_utils.js +++ b/third_party/blink/web_tests/wpt_internal/webcodecs/encoder_utils.js
@@ -67,10 +67,4 @@ fourColorsFrame(ctx, width, height, text); putBlackDots(ctx, width, height, ts); return new VideoFrame(cnv, { timestamp: ts }); -} - -function delay(time_ms) { - return new Promise((resolve, reject) => { - setTimeout(resolve, time_ms); - }); -}; +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/webcodecs/reconfiguring_encoder.https.any.js b/third_party/blink/web_tests/wpt_internal/webcodecs/reconfiguring_encoder.https.any.js deleted file mode 100644 index 4215c201..0000000 --- a/third_party/blink/web_tests/wpt_internal/webcodecs/reconfiguring_encoder.https.any.js +++ /dev/null
@@ -1,119 +0,0 @@ -// META: global=window,dedicatedworker -// META: script=/wpt_internal/webcodecs/encoder_utils.js - -async function change_encoding_params_test(codec) { - const acc = "prefer-software"; - let original_w = 800; - let original_h = 600; - let original_bitrate = 5_000_000; - - let new_w = 640; - let new_h = 480; - let new_bitrate = 3_000_000; - - let next_ts = 0 - let reconf_ts = 0; - let frames_to_encode = 16; - let before_reconf_frames = 0; - let after_reconf_frames = 0; - let errors = 0; - - let process_video_chunk = function (chunk, metadata) { - let config = metadata.decoderConfig; - var data = new Uint8Array(chunk.data); - assert_greater_than_equal(data.length, 0); - let after_reconf = (reconf_ts != 0) && (chunk.timestamp >= reconf_ts); - if (after_reconf) { - after_reconf_frames++; - if (config) { - assert_equals(config.codedWidth, new_w); - assert_equals(config.codedHeight, new_h); - } - } else { - before_reconf_frames++; - if (config) { - assert_equals(config.codedWidth, original_w); - assert_equals(config.codedHeight, original_h); - } - } - }; - - const init = { - output: (chunk, md) => { - try { - process_video_chunk(chunk, md); - } catch (e) { - errors++; - console.log(e.message); - } - }, - error: (e) => { - errors++; - console.log(e.message); - }, - }; - const params = { - codec: codec, - hardwareAcceleration: acc, - width: original_w, - height: original_h, - bitrate: original_bitrate, - scalabilityMode: "L1T2", - framerate: 30, - }; - let encoder = new VideoEncoder(init); - encoder.configure(params); - - // Remove this flush after crbug.com/1275789 is fixed - await encoder.flush(); - - // Encode |frames_to_encode| frames with original settings - for (let i = 0; i < frames_to_encode; i++) { - var frame = createFrame(original_w, original_h, next_ts++); - encoder.encode(frame, {}); - } - - params.width = new_w; - params.height = new_h; - params.bitrate = new_bitrate; - - // Reconfigure encoder and run |frames_to_encode| frames with new settings - encoder.configure(params); - reconf_ts = next_ts; - - for (let i = 0; i < frames_to_encode; i++) { - var frame = createFrame(new_w, new_h, next_ts++); - encoder.encode(frame, {}); - } - - await encoder.flush(); - - // Configure back to original config - params.width = original_w; - params.height = original_h; - params.bitrate = original_bitrate; - encoder.configure(params); - await encoder.flush(); - - encoder.close(); - assert_equals(before_reconf_frames, frames_to_encode); - assert_equals(after_reconf_frames, frames_to_encode); - assert_equals(errors, 0); -} - -promise_test( - change_encoding_params_test.bind(null, 'vp8'), - 'reconfiguring vp8'); - -promise_test( - change_encoding_params_test.bind(null, 'vp09.00.10.08'), - 'reconfiguring vp9 profile0'); - -promise_test( - change_encoding_params_test.bind(null, 'vp09.02.10.10'), - 'reconfiguring vp9 profile2'); - -promise_test( - change_encoding_params_test.bind(null, 'avc1.42001E'), - 'reconfiguring avc1.42001E'); -
diff --git a/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js b/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js deleted file mode 100644 index f38f95f7..0000000 --- a/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js +++ /dev/null
@@ -1,114 +0,0 @@ -// META: global=window,dedicatedworker -// META: script=/wpt_internal/webcodecs/encoder_utils.js - -async function svc_test(codec, layers, base_layer_decimator) { - const w = 320; - const h = 200; - const acc = "prefer-software"; - let frames_to_encode = 40; - let frames_decoded = 0; - let frames_encoded = 0; - let errors = 0; - let chunks = []; - let corrupted_frames = []; - - const encoder_init = { - output(chunk, metadata) { - frames_encoded++; - - // Filter out all frames, but base layer. - assert_own_property(metadata, "svc"); - assert_own_property(metadata.svc, "temporalLayerId"); - assert_less_than(metadata.svc.temporalLayerId, layers); - if (metadata.svc.temporalLayerId == 0) - chunks.push(chunk); - }, - error(e) { - errors++; - } - }; - - let encoder_config = { - codec: codec, - hardwareAcceleration: acc, - width: w, - height: h, - bitrate: 5000000, - scalabilityMode: "L1T" + layers, - }; - - if (codec.includes("avc")) - encoder_config.avc = {format: "annexb"}; - - let encoder = new VideoEncoder(encoder_init); - encoder.configure(encoder_config); - - for (let i = 0; i < frames_to_encode; i++) { - let frame = createFrame(w, h, i); - encoder.encode(frame, { keyFrame: false }); - frame.close(); - } - await encoder.flush(); - assert_equals(errors, 0); - - let decoder = new VideoDecoder({ - output(frame) { - frames_decoded++; - // Check that we have intended number of dots and no more. - // Completely black frame shouldn't pass the test. - if(!validateBlackDots(frame, frame.timestamp) || - validateBlackDots(frame, frame.timestamp + 1)) { - corrupted_frames.push(frame.timestamp) - } - frame.close(); - }, - error(e) { - errors++; - } - }); - - let decoder_config = { - codec: codec, - hardwareAcceleration: acc, - codedWidth: w, - codedHeight: h, - }; - decoder.configure(decoder_config); - - for (let chunk of chunks) { - decoder.decode(chunk); - await delay(1); - } - await decoder.flush(); - assert_equals(errors, 0); - - encoder.close(); - decoder.close(); - assert_equals(frames_encoded, frames_to_encode); - - let base_layer_frames = frames_to_encode / base_layer_decimator; - assert_equals(chunks.length, base_layer_frames); - assert_equals(frames_decoded, base_layer_frames); - assert_equals(corrupted_frames.length, 0, - `corrupted_frames: ${corrupted_frames}`); -} - -promise_test(svc_test.bind(null, "avc1.42001E", 2, 2), "SVC H264 L1T2"); -promise_test(svc_test.bind(null, "avc1.42001E", 3, 4), "SVC H264 L1T3"); - -promise_test(svc_test.bind(null, "vp8", 2, 2), "SVC VP8 L1T2"); -promise_test(svc_test.bind(null, "vp8", 3, 4), "SVC VP8 L1T3"); - -promise_test(svc_test.bind(null, "vp09.00.10.08", 2, 2), "SVC VP9 8 L1T2"); -promise_test(svc_test.bind(null, "vp09.00.10.08", 3, 4), "SVC VP9 8 L1T3"); - -promise_test(svc_test.bind(null, "vp09.02.10.10", 2, 2), "SVC VP9 10 L1T2"); -promise_test(svc_test.bind(null, "vp09.02.10.10", 3, 4), "SVC VP9 10 L1T3"); - -promise_test(async t => { - for (let i = 0; i < 10; i++) { - let frame = createFrame(320, 200, i); - assert_true(validateBlackDots(frame, i)); - assert_false(validateBlackDots(frame, i + 1)); - } -}, "Dot counting self test");
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index d6cb8e3..ff83c0db 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -45,3 +45,4 @@ (crashpad/util/BUILD.gn, crashpad/util/linux/memory_map_test.cc) - CloseMultipleNowOrOnExec has been updated to invoke the new base::subtle::ResetFDOwnership() API + - FALLTHROUGH macro has been replaced with C++17 attribute [[fallthrough]]
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc index c9fbb0a..aef252f 100644 --- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc +++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc
@@ -198,7 +198,7 @@ if (HaveCapSysPtrace()) { return Strategy::kDirectPtrace; } - FALLTHROUGH; + [[fallthrough]]; case PtraceScope::kNoAttach: LOG(WARNING) << "no ptrace"; return Strategy::kNoPtrace;
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc index db7e595..8c870ee 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc
@@ -323,7 +323,7 @@ full_version_ = base::UTF16ToUTF8(info.BuildString); #endif full_version_ = full_version_.substr(0, full_version_.find(';')); - FALLTHROUGH; + [[fallthrough]]; case sizeof(MINIDUMP_MISC_INFO_3): case sizeof(MINIDUMP_MISC_INFO_2): case sizeof(MINIDUMP_MISC_INFO):
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 9fcb959..7dfcb3b 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-1-17-g2b672e721 -Revision: 2b672e7210a6e989aca4787fb81f4b2542bad9c1 +Version: VER-2-11-1-18-gafb4ca015 +Revision: afb4ca0151959a8bedfb39a9a9140504168be7ea CPEPrefix: cpe:/a:freetype:freetype:2.11.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/nearby/OWNERS b/third_party/nearby/OWNERS index 84e9ecd2..c921117 100644 --- a/third_party/nearby/OWNERS +++ b/third_party/nearby/OWNERS
@@ -1,3 +1,6 @@ hansberry@chromium.org file://chrome/browser/nearby_sharing/OWNERS + +# To ease autorolling. +per-file README.chromium=*
diff --git a/third_party/r8/README.chromium b/third_party/r8/README.chromium index 14332397..f11f73e0 100644 --- a/third_party/r8/README.chromium +++ b/third_party/r8/README.chromium
@@ -30,6 +30,8 @@ desugared version accesses the "dark greylisted" SynchronizedCollection.mutex field, which caused modal dialogs to appear on Android P instrumentation tests. https://crbug.com/1256614 + * Removed references to ThreadLocalRandom to avoid streams APIs being pulled + in unnecessarily. https://crbug.com/1280841 * Added "java/src/org/chromium/build/CustomD8.java", custom_d8.jar, and BUILD.gn. * Used in "build/android/gyp/dex.py" to enable desugar dependencies. @@ -90,7 +92,13 @@ * Update instructions for desugar_jdk_libs.json: unzip -p third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/*.jar META-INF/desugar/d8/desugar.json > third_party/r8/desugar_jdk_libs.json - * Remove all mentions of ConcurrentHashMap and TimeZone#getTimeZone and remove trailing commas. + * Remove all mentions of: + * ConcurrentHashMap + * TimeZone#getTimeZone + * Collections#synchronizedMap + * Collections#synchronizedSortedMap + * ThreadLocalRandom + * Don't forget to remove trailing commas where applicable. * Update //build/config/android/internal_rules.gni to point at the new .jar files: * desugar_jdk_libs-1.1.1.jar * desugar_jdk_libs_configuration-1.1.1.jar
diff --git a/third_party/r8/desugar_jdk_libs.json b/third_party/r8/desugar_jdk_libs.json index 040d18d..c2cdcb0 100644 --- a/third_party/r8/desugar_jdk_libs.json +++ b/third_party/r8/desugar_jdk_libs.json
@@ -118,7 +118,6 @@ "java.util.StringJoiner": "j$.util.StringJoiner", "java.util.Tripwire": "j$.util.Tripwire", "java.util.concurrent.DesugarUnsafe": "j$.util.concurrent.DesugarUnsafe", - "java.util.concurrent.ThreadLocalRandom": "j$.util.concurrent.ThreadLocalRandom", "java.util.concurrent.atomic.DesugarAtomic": "j$.util.concurrent.atomic.DesugarAtomic" }, "retarget_lib_member": { @@ -188,7 +187,6 @@ "java.util.PrimitiveIterator": "j$.util.PrimitiveIterator", "java.util.Spliterator": "j$.util.Spliterator", "java.util.StringJoiner": "j$.util.StringJoiner", - "java.util.concurrent.ThreadLocalRandom": "j$.util.concurrent.ThreadLocalRandom", "java.util.concurrent.atomic.DesugarAtomic": "j$.util.concurrent.atomic.DesugarAtomic" }, "retarget_lib_member": {
diff --git a/third_party/sinonjs/OWNERS b/third_party/sinonjs/OWNERS index 1eac0a3..237ac6f 100644 --- a/third_party/sinonjs/OWNERS +++ b/third_party/sinonjs/OWNERS
@@ -1 +1 @@ -jamiewalch@chromium.org +xiaohuic@chromium.org
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium index 9305f1e4..eb35b85 100644 --- a/third_party/tflite/README.chromium +++ b/third_party/tflite/README.chromium
@@ -1,8 +1,8 @@ Name: TensorFlow Lite Short Name: tflite URL: https://github.com/tensorflow/tensorflow -Version: dd57f5328f37a81197b0dadd052e05c9d9461b16 -Date: 2021/12/14 +Version: a4289fcb7a4fc982886aa2d11c7b0d87e9815ed7 +Date: 2022/01/06 License: Apache 2.0 License File: LICENSE Security Critical: Yes
diff --git a/tools/android/avd/avd.py b/tools/android/avd/avd.py index bd7901e..13a6675 100755 --- a/tools/android/avd/avd.py +++ b/tools/android/avd/avd.py
@@ -64,6 +64,25 @@ action='store_true', help='Keep the AVD after creating the CIPD package.') create_parser.add_argument( + '--privileged-apk', + action='append', + default=[], + dest='privileged_apk_pairs', + nargs=2, + metavar=('APK_PATH', 'DEVICE_PARTITION'), + help='Privileged apks to be installed during AVD launching. Expecting ' + 'two strings where the first element being the path to the APK, and the ' + 'second element being the system image partition on device where the APK ' + 'will be pushed to. Example: --privileged-apk path/to/some.apk /system') + create_parser.add_argument( + '--additional-apk', + action='append', + default=[], + dest='additional_apks', + metavar='APK_PATH', + type=os.path.realpath, + help='Additional apk to be installed during AVD launching') + create_parser.add_argument( '--cipd-json-output', type=os.path.realpath, metavar='PATH', @@ -79,6 +98,8 @@ force=args.force, snapshot=args.snapshot, keep=args.keep, + additional_apks=args.additional_apks, + privileged_apk_tuples=[tuple(p) for p in args.privileged_apk_pairs], cipd_json_output=args.cipd_json_output, dry_run=args.dry_run) return 0 @@ -89,21 +110,32 @@ 'start', help='Start an AVD instance with the given config.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) - start_parser.add_argument('--wipe-data', - action='store_true', - default=False, - help='Reset user data image for this emulator.') + start_parser.add_argument( + '--wipe-data', + action='store_true', + default=False, + help='Reset user data image for this emulator. Note that when set, all ' + 'the customization, e.g. wifi, additional apks, privileged apks will be ' + 'gone') + start_parser.add_argument( + '--read-only', + action='store_true', + help='Allowing running multiple instances of emulators on the same AVD, ' + 'but cannot save snapshot. This will be forced to False if emulator ' + 'has a system snapshot.') start_parser.add_argument( '--no-read-only', action='store_false', - dest='read_only', - default=True, - help='Run a modifiable emulator. Will save snapshots on exit.') + dest='read_only') + # TODO(crbug.com/1278096): Default to False when AVDs with sideloaded + # system apks are rolled. + start_parser.set_defaults(read_only=True) start_parser.add_argument( '--writable-system', action='store_true', default=False, - help='Makes system & vendor image writable after adb remount.') + help='Makes system & vendor image writable after adb remount. This will ' + 'be forced to True, if emulator has a system snapshot.') start_parser.add_argument( '--emulator-window', action='store_true', @@ -128,7 +160,6 @@ def start_cmd(args): inst = avd.AvdConfig(args.avd_config).CreateInstance() inst.Start(read_only=args.read_only, - snapshot_save=not args.read_only, window=args.emulator_window, writable_system=args.writable_system, gpu_mode=args.gpu_mode,
diff --git a/tools/android/errorprone_plugin/BUILD.gn b/tools/android/errorprone_plugin/BUILD.gn index 0c13ec0..1212b2af 100644 --- a/tools/android/errorprone_plugin/BUILD.gn +++ b/tools/android/errorprone_plugin/BUILD.gn
@@ -19,6 +19,7 @@ "src/org/chromium/tools/errorprone/plugin/NoSynchronizedMethodCheck.java", "src/org/chromium/tools/errorprone/plugin/NoSynchronizedThisCheck.java", "src/org/chromium/tools/errorprone/plugin/TestClassNameCheck.java", + "src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java", ] # Necessary to avoid dependency cycle
diff --git a/tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java b/tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java new file mode 100644 index 0000000..ac32b8f --- /dev/null +++ b/tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java
@@ -0,0 +1,92 @@ +// 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.tools.errorprone.plugin; + +import static com.google.errorprone.matchers.Matchers.anyOf; +import static com.google.errorprone.matchers.Matchers.instanceMethod; + +import com.google.auto.service.AutoService; +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.matchers.Description; +import com.google.errorprone.matchers.Matcher; +import com.google.errorprone.util.ASTHelpers; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.MethodInvocationTree; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +/** + * Checks for direct calls to blocklisted methods to make network requests. Chromium code should + * use ChromiumNetworkAdapter instead, with a NetworkTrafficAnnotationTag documenting the + * network request for static analysis. + * + * Currently, only URL#openConnection() is blocklisted by this BugChecker. + */ +@AutoService(BugChecker.class) +@BugPattern(name = "UseNetworkAnnotations", + summary = "Use wrapper network APIs with NetworkTrafficAnnotationTag", + severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM, + link = "https://bugs.chromium.org/p/chromium/issues/detail?id=1231780") +public class UseNetworkAnnotations + extends BugChecker implements BugChecker.MethodInvocationTreeMatcher { + private static final String URL_CLASS_NAME = "java.net.URL"; + private static final String OPEN_CONNECTION_METHOD_NAME = "openConnection"; + + private static final Matcher<ExpressionTree> METHOD_MATCHER = + anyOf(instanceMethod() + .onDescendantOf(URL_CLASS_NAME) + .namedAnyOf(OPEN_CONNECTION_METHOD_NAME)); + + /** + * Allow-listed prefixes, starting relative to the src/ dir. It is OK to call + * URL#openConnection() from Java code inside these directories, either because they're not + * part of clank, or because they're //net implementation details. + */ + private static final ArrayList<String> ALLOWLISTED_FILES = new ArrayList<>( + List.of("net/android/java/src/org/chromium/net/ChromiumNetworkAdapter.java", + "android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/" + + "NetworkFetcherTask.java", + "components/cronet/", "chromecast/", "clank/test/")); + + @Override + public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { + if (!METHOD_MATCHER.matches(tree, state)) { + return Description.NO_MATCH; + } + + // Find the src/ dir. This assumes the build path is inside the src/ directory, and that + // the root is actually called "src". + Path buildPath = Paths.get("").toAbsolutePath(); + Path srcDir = buildPath; + while (srcDir != null && !srcDir.endsWith("src")) { + srcDir = srcDir.getParent(); + } + if (srcDir == null) { + return buildDescription(tree) + .setMessage( + "Could not find the src/ directory for the UseNetworkAnnotations check." + + " Make sure your build path is inside src/.") + .build(); + } + + // Check whether the file is allowlisted. + Path javaFile = Paths.get(ASTHelpers.getFileName(state.getPath().getCompilationUnit())); + for (String allowed : ALLOWLISTED_FILES) { + if (javaFile.startsWith(srcDir.resolve(allowed))) { + return Description.NO_MATCH; + } + } + + return buildDescription(tree) + .setMessage("Direct use of URL#openConnection() is forbidden in Chromium. Use " + + "ChromiumNetworkAdapter#openConnection() instead.") + .build(); + } +}
diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py index c47633c..915e6329 100755 --- a/tools/binary_size/diagnose_bloat.py +++ b/tools/binary_size/diagnose_bloat.py
@@ -931,6 +931,8 @@ log_level = logging.DEBUG if args.verbose else logging.INFO logging.basicConfig(level=log_level, format='%(levelname).1s %(relativeCreated)6d %(message)s') + if args.target and args.target.endswith('_bundle'): + parser.error('Bundle targets must use _minimal_apks variants') build = _BuildHelper(args) subrepo = args.subrepo or _SRC_ROOT
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index 8c02568..417bb39e 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -12,6 +12,7 @@ import functools import gzip import itertools +import json import logging import os import posixpath @@ -63,56 +64,19 @@ _SECTION_SIZE_BLOCKLIST = ['.symtab', '.shstrtab', '.strtab'] -# Tunable constant "knobs" for CreateContainerAndSymbols(). -class SectionSizeKnobs: - def __init__(self): - # A limit on the number of symbols an address can have, before these symbols - # are compacted into shared symbols. Increasing this value causes more data - # to be stored .size files, but is also more expensive. - # Effect of max_same_name_alias_count (as of Oct 2017, with min_pss = max): - # 1: shared .text syms = 1772874 bytes, file size = 9.43MiB (645476 syms). - # 2: shared .text syms = 1065654 bytes, file size = 9.58MiB (669952 syms). - # 6: shared .text syms = 464058 bytes, file size = 10.11MiB (782693 syms). - # 10: shared .text syms = 365648 bytes, file size = 10.24MiB (813758 syms). - # 20: shared .text syms = 86202 bytes, file size = 10.38MiB (854548 syms). - # 40: shared .text syms = 48424 bytes, file size = 10.50MiB (890396 syms). - # 50: shared .text syms = 41860 bytes, file size = 10.54MiB (902304 syms). - # max: shared .text syms = 0 bytes, file size = 11.10MiB (1235449 syms). - self.max_same_name_alias_count = 40 # 50kb is basically negligable. - - # File name: Source file. - self.apk_other_files = { - 'assets/icudtl.dat': - '../../third_party/icu/android/icudtl.dat', - 'assets/snapshot_blob_32.bin': - '../../v8/snapshot_blob_32.bin', - 'assets/snapshot_blob_64.bin': - '../../v8/snapshot_blob_64.bin', - 'assets/unwind_cfi_32': - '../../base/trace_event/cfi_backtrace_android.cc', - 'assets/webapk_dex_version.txt': - '../../chrome/android/webapk/libs/runtime_library_version.gni', - 'lib/armeabi-v7a/libarcore_sdk_c_minimal.so': - '../../third_party/arcore-android-sdk/BUILD.gn', - 'lib/armeabi-v7a/libarcore_sdk_c.so': - '../../third_party/arcore-android-sdk/BUILD.gn', - 'lib/armeabi-v7a/libcrashpad_handler_trampoline.so': - '../../third_party/crashpad/BUILD.gn', - 'lib/armeabi-v7a/libyoga.so': - '../../chrome/android/feed/BUILD.gn', - 'lib/armeabi-v7a/libelements.so': - '../../chrome/android/feed/BUILD.gn', - 'lib/arm64-v8a/libarcore_sdk_c_minimal.so': - '../../third_party/arcore-android-sdk/BUILD.gn', - 'lib/arm64-v8a/libarcore_sdk_c.so': - '../../third_party/arcore-android-sdk/BUILD.gn', - 'lib/arm64-v8a/libcrashpad_handler_trampoline.so': - '../../third_party/crashpad/BUILD.gn', - 'lib/arm64-v8a/libyoga.so': - '../../chrome/android/feed/BUILD.gn', - 'lib/arm64-v8a/libelements.so': - '../../chrome/android/feed/BUILD.gn', - } +# A limit on the number of symbols an address can have, before these symbols +# are compacted into shared symbols. Increasing this value causes more data +# to be stored .size files, but is also more expensive. +# Effect as of Oct 2017, with min_pss = max: +# 1: shared .text syms = 1772874 bytes, file size = 9.43MiB (645476 syms). +# 2: shared .text syms = 1065654 bytes, file size = 9.58MiB (669952 syms). +# 6: shared .text syms = 464058 bytes, file size = 10.11MiB (782693 syms). +# 10: shared .text syms = 365648 bytes, file size = 10.24MiB (813758 syms). +# 20: shared .text syms = 86202 bytes, file size = 10.38MiB (854548 syms). +# 40: shared .text syms = 48424 bytes, file size = 10.50MiB (890396 syms). +# 50: shared .text syms = 41860 bytes, file size = 10.54MiB (902304 syms). +# max: shared .text syms = 0 bytes, file size = 11.10MiB (1235449 syms). +_MAX_SAME_NAME_ALIAS_COUNT = 40 # 50kb is basically negligible. @dataclasses.dataclass @@ -136,12 +100,24 @@ @dataclasses.dataclass class ApkSpec: - apk_path: str # Never None. + # Path the .apk file. Never None. + # This is a temp file when .apks is being analyzed. + apk_path: str + # Path to .minimal.apks (when analyzing bundles). minimal_apks_path: str = None + # Proguard mapping path. mapping_path: str = None + # Name of the apk split when .apks is being analyzed. split_name: str = None + # Path such as: out/Release/size-info/BaseName size_info_prefix: str = None + # Whether to break down classes.dex. analyze_dex: bool = True + # Dict of apk_path -> source_path, provided by json config. + path_defaults: dict = None + # Component to use for symbols when not specified by DIR_METADATA, provided by + # json config. + default_component: str = '' def _OpenMaybeGzAsText(path): @@ -352,7 +328,7 @@ return os.path.join(os.path.dirname(prefix), '{shared}', symbol_count_str) -def _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs): +def _CompactLargeAliasesIntoSharedSymbols(raw_symbols): """Converts symbols with large number of aliases into single symbols. The merged symbol's path fields are changed to common-ancestor paths in @@ -369,7 +345,7 @@ raw_symbols[dst_cursor] = symbol dst_cursor += 1 aliases = symbol.aliases - if aliases and len(aliases) > knobs.max_same_name_alias_count: + if aliases and len(aliases) > _MAX_SAME_NAME_ALIAS_COUNT: symbol.source_path = _ComputeAncestorPath( [s.source_path for s in aliases if s.source_path], len(aliases)) symbol.object_path = _ComputeAncestorPath( @@ -979,8 +955,8 @@ class _ResourceSourceMapper: - def __init__(self, size_info_prefix, knobs): - self._knobs = knobs + def __init__(self, size_info_prefix, path_defaults): + self._path_defaults = path_defaults or {} self._res_info = self._LoadResInfo(size_info_prefix) self._pattern_dollar_underscore = re.compile(r'\$+(.*?)(?:__\d)+') self._pattern_version_suffix = re.compile(r'-v\d+/') @@ -998,7 +974,7 @@ os.path.join('res', dest): source for dest, source in res_info_without_root.items() } - res_info.update(self._knobs.apk_other_files) + res_info.update(self._path_defaults) return res_info def FindSourceForPath(self, path): @@ -1054,9 +1030,10 @@ def _ParseApkOtherSymbols(*, apk_spec, native_spec, section_ranges, - resources_pathmap_path, metadata, knobs): + resources_pathmap_path, metadata): apk_so_path = native_spec and native_spec.apk_so_path - res_source_mapper = _ResourceSourceMapper(apk_spec.size_info_prefix, knobs) + res_source_mapper = _ResourceSourceMapper(apk_spec.size_info_prefix, + apk_spec.path_defaults) resource_deobfuscator = _ResourcePathDeobfuscator(resources_pathmap_path) apk_symbols = [] dex_size = 0 @@ -1215,21 +1192,19 @@ return source_mapper, ninja_elf_object_paths -def CreateContainerAndSymbols(*, - knobs, - container_name, - metadata, - apk_spec, - pak_spec, - native_spec, - source_directory, - output_directory=None, - resources_pathmap_path=None, - pak_id_map=None): +def CreateContainerSymbols(*, + container_name, + metadata, + apk_spec, + pak_spec, + native_spec, + source_directory, + output_directory=None, + resources_pathmap_path=None, + pak_id_map=None): """Creates a Container (with sections sizes) and symbols for a SizeInfo. Args: - knobs: Instance of SectionSizeKnobs. container_name: Name for the created Container. May be '' if only one Container exists. metadata: Metadata dict from CreateMetadata(). @@ -1244,12 +1219,8 @@ pak_id_map: Instance of PakIdMap, or None. Returns: - A tuple of (container, raw_symbols). - containers is a Container instance that stores metadata and section_sizes - (section_sizes maps section names to respective sizes). - raw_symbols is a list of Symbol objects. + List of symbols. """ - knobs = knobs or SectionSizeKnobs() apk_elf_result = None if apk_spec and native_spec and native_spec.apk_so_path: # Extraction takes around 1 second, so do it in parallel. @@ -1344,8 +1315,7 @@ native_spec=native_spec, section_ranges=section_ranges, resources_pathmap_path=resources_pathmap_path, - metadata=metadata, - knobs=knobs) + metadata=metadata) if apk_spec.analyze_dex: logging.info('Analyzing Dex') @@ -1418,9 +1388,12 @@ _AddSourcePathsUsingAddress(dwarf_source_mapper, raw_symbols) _NormalizePaths(raw_symbols) - dir_metadata.PopulateComponents(raw_symbols, source_directory) + default_component = apk_spec.default_component if apk_spec else '' + dir_metadata.PopulateComponents(raw_symbols, + source_directory, + default_component=default_component) logging.info('Converting excessive aliases into shared-path symbols') - _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs) + _CompactLargeAliasesIntoSharedSymbols(raw_symbols) if native_spec: logging.debug('Connecting nm aliases') @@ -1434,17 +1407,13 @@ symbol.container = container file_format.SortSymbols(raw_symbols, check_already_mostly_sorted=True) - - return container, raw_symbols + return raw_symbols def CreateSizeInfo(build_config, - container_list, raw_symbols_list, normalize_names=True): """Performs operations on all symbols and creates a SizeInfo object.""" - assert len(container_list) == len(raw_symbols_list) - all_raw_symbols = [] for raw_symbols in raw_symbols_list: file_format.CalculatePadding(raw_symbols) @@ -1457,6 +1426,8 @@ all_raw_symbols += raw_symbols + # Containers should always have at least one symbol. + container_list = [syms[0].container for syms in raw_symbols_list] return models.SizeInfo(build_config, container_list, all_raw_symbols) @@ -1610,6 +1581,7 @@ group.add_argument('--output-directory', help='Path to the root build directory.') if is_top_args: + group.add_argument('--json-config', help='Path to a supersize.json.') group.add_argument('--no-output-directory', action='store_true', help='Do not auto-detect --output-directory.') @@ -1845,6 +1817,7 @@ # Both |top_args| and |sub_args| may be modified. def _ProcessContainerArgs(top_args, sub_args, + json_config, container_name, on_config_error, apk_path=None, @@ -1885,6 +1858,12 @@ os.path.basename(apk_prefix)) apk_spec.analyze_dex = not (sub_args.native_only or sub_args.no_java or top_args.native_only or top_args.no_java) + apk_spec.path_defaults = { + k: v['source_path'] + for k, v in json_config.get('apk_files', {}).items() + } + apk_spec.default_component = json_config.get('apk_splits', {}).get( + split_name, {}).get('default_component', '') pak_spec = None apk_pak_paths = None @@ -1960,12 +1939,23 @@ return on_demand +def _ParseJsonConfig(path, on_config_error): + path = path or path_util.GetDefaultJsonConfigPath() + try: + with open(path) as f: + return json.load(f) + except Exception as e: + on_config_error(f'Error while parsing {path}: {e}') + + def _IterSubArgs(top_args, on_config_error): """Generates main paths (may be deduced) for each containers given by input. Yields: For each container, main paths and other info needed to create size_info. """ + json_config = _ParseJsonConfig(top_args.json_config, on_config_error) + main_file = _IdentifyInputFile(top_args, on_config_error) if top_args.no_output_directory: top_args.output_directory = None @@ -2011,13 +2001,14 @@ 'splits/{}-master.apk'.format(split_name)) as temp: yield _ProcessContainerArgs(top_args, sub_args, + json_config, container_name, on_config_error, apk_path=temp, split_name=split_name) else: - yield _ProcessContainerArgs(top_args, sub_args, container_name, - on_config_error) + yield _ProcessContainerArgs(top_args, sub_args, json_config, + container_name, on_config_error) def Run(top_args, on_config_error): @@ -2026,10 +2017,8 @@ if top_args.check_data_quality: start_time = time.time() - knobs = SectionSizeKnobs() build_config = {} seen_container_names = set() - container_list = [] raw_symbols_list = [] pak_id_map = pakfile.PakIdMap() @@ -2049,8 +2038,7 @@ native_spec=native_spec, source_directory=sub_args.source_directory, output_directory=sub_args.output_directory) - container, raw_symbols = CreateContainerAndSymbols( - knobs=knobs, + raw_symbols = CreateContainerSymbols( container_name=container_name, metadata=metadata, apk_spec=apk_spec, @@ -2060,12 +2048,11 @@ output_directory=sub_args.output_directory, resources_pathmap_path=resources_pathmap_path, pak_id_map=pak_id_map) + assert raw_symbols, f'Container {container_name} had no symbols.' - container_list.append(container) raw_symbols_list.append(raw_symbols) size_info = CreateSizeInfo(build_config, - container_list, raw_symbols_list, normalize_names=False)
diff --git a/tools/binary_size/libsupersize/dir_metadata.py b/tools/binary_size/libsupersize/dir_metadata.py index d3e79f99..8fba308 100644 --- a/tools/binary_size/libsupersize/dir_metadata.py +++ b/tools/binary_size/libsupersize/dir_metadata.py
@@ -92,7 +92,7 @@ return result -def PopulateComponents(raw_symbols, source_directory): +def PopulateComponents(raw_symbols, source_directory, default_component): """Populates the |component| field based on |source_path|. Symbols without a |source_path| are skipped. @@ -100,8 +100,10 @@ Args: raw_symbols: list of Symbol objects. source_directory: Directory to use as the root. + default_component: Component to use when none was found. """ context = _ComponentLookupContext(source_directory) for symbol in raw_symbols: if symbol.source_path: - symbol.component = context.ComponentForSourcePath(symbol.source_path) + found_component = context.ComponentForSourcePath(symbol.source_path) + symbol.component = found_component or default_component
diff --git a/tools/binary_size/libsupersize/docs/merging_diffs.md b/tools/binary_size/libsupersize/docs/merging_diffs.md new file mode 100644 index 0000000..979df03 --- /dev/null +++ b/tools/binary_size/libsupersize/docs/merging_diffs.md
@@ -0,0 +1,27 @@ +# Merging Size Diffs + +When looking at a diff across milestones, it can be useful to filter out the +size impacts due to toolchain changes (e.g. compiler or R8 rolls). + +You will need: +1) The `.size` files of the milestones you'd like to diff. +2) The `.sizediff` files of the commits to filter out. + +Then run: + +``` +tools/binary_size/supersize console M97.size M98.size clang_roll.sizediff +... + size_info1: Loaded from 97.size + size_info2: Loaded from 98.size + size_info3: Loaded from clang_roll.sizediff + size_info4: Loaded from clang_roll.sizediff + +>>> d = Diff(size_info1, size_info2) +>>> d2 = Diff(size_info4, size_info3) # Note reversed order. +>>> d.raw_symbols += d2.raw_symbols +>>> SaveDeltaSizeInfo(d, 'm97_m98_normalized.sizediff') +Saved locally to m97_m98_normalized.sizediff. To share, run: +> gsutil.py cp m97_m98_normalized.sizediff gs://chrome-supersize/private-oneoffs + Then view it at https://chrome-supersize.firebaseapp.com/viewer.html?load_url=https://storage.googleapis.com/chrome-supersize/private-oneoffs/m97_m98_normalized.sizediff +```
diff --git a/tools/binary_size/libsupersize/integration_test.py b/tools/binary_size/libsupersize/integration_test.py index dd37220..c90890f 100755 --- a/tools/binary_size/libsupersize/integration_test.py +++ b/tools/binary_size/libsupersize/integration_test.py
@@ -65,6 +65,11 @@ _TEST_APK_OTHER_FILE_PATH = 'assets/icudtl.dat' _TEST_APK_RES_FILE_PATH = 'res/drawable-v13/test.xml' +_TEST_CONFIG_JSON = os.path.join(_TEST_DATA_DIR, 'supersize.json') +_TEST_PATH_DEFAULTS = { + 'assets/icudtl.dat': '../../third_party/icu/android/icudtl.dat', +} + def _CompareWithGolden(name=None): def real_decorator(func): @@ -239,6 +244,7 @@ if use_apk or use_minimal_apks: native_spec.apk_so_path = _TEST_APK_SO_PATH + apk_spec.path_defaults = _TEST_PATH_DEFAULTS if output_directory: if use_apk: orig_path = _TEST_APK_PATH @@ -268,17 +274,12 @@ container_name = 'Bundle.minimal.apks/%s.apk' % split_name if split_name == 'on_demand': container_name += '?' + apk_spec.default_component = 'DEFAULT' yield container_name, apk_spec, pak_spec, native_spec - container_list = [] raw_symbols_list = [] build_config = {} - # Override for testing. Lower the bar for compacting symbols, to allow - # smaller test cases to be created. - knobs = archive.SectionSizeKnobs() - knobs.max_same_name_alias_count = 3 - with _AddMocksToPath(): pak_id_map = pakfile.PakIdMap() for container_name, apk_spec, pak_spec, native_spec in iter_specs(): @@ -287,8 +288,7 @@ native_spec=native_spec, source_directory=_TEST_SOURCE_DIR, output_directory=output_directory) - container, raw_symbols = archive.CreateContainerAndSymbols( - knobs=knobs, + raw_symbols = archive.CreateContainerSymbols( container_name=container_name, metadata=metadata, apk_spec=apk_spec, @@ -297,11 +297,10 @@ source_directory=_TEST_SOURCE_DIR, output_directory=output_directory, pak_id_map=pak_id_map) - container_list.append(container) raw_symbols_list.append(raw_symbols) IntegrationTest.cached_size_info[cache_key] = archive.CreateSizeInfo( - build_config, container_list, raw_symbols_list) + build_config, raw_symbols_list) return copy.deepcopy(IntegrationTest.cached_size_info[cache_key]) def _DoArchive(self, @@ -324,6 +323,8 @@ _TEST_SOURCE_DIR, '--tool-prefix', _TEST_TOOL_PREFIX, + '--json-config', + _TEST_CONFIG_JSON, ] if use_output_directory:
diff --git a/tools/binary_size/libsupersize/path_util.py b/tools/binary_size/libsupersize/path_util.py index 7dad64c1..b2d60ea 100644 --- a/tools/binary_size/libsupersize/path_util.py +++ b/tools/binary_size/libsupersize/path_util.py
@@ -240,3 +240,8 @@ if tool_prefix[-5:] != 'llvm-': raise ValueError('BC analyzer is only supported in LLVM.') return tool_prefix + 'bcanalyzer' + + +def GetDefaultJsonConfigPath(): + return FromToolsSrcRootRelative( + os.path.join('tools', 'binary_size', 'supersize.json'))
diff --git a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden index 2b01468..c240f6e7 100644 --- a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden +++ b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden
@@ -201,7 +201,7 @@ Section .other: has 100.0% of 695 bytes accounted for from 2 symbols. 0 bytes are unaccounted for. * Padding accounts for 136 bytes (19.6%) * 1 have source paths. Accounts for 559 bytes (80.4%). -* 0 have a component assigned. Accounts for 0 bytes (0.0%). +* 1 have a component assigned. Accounts for 559 bytes (80.4%). * 0 symbols have shared ownership. * 1 symbols are from generated sources. Accounts for 559 bytes (80.4%). <Bundle.minimal.apks/base.apk>.text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal) @@ -702,5 +702,5 @@ <Bundle.minimal.apks/base.apk>.other@0(size_without_padding=0,padding=33902635,full_name=Overhead: ELF file,object_path=,source_path=,flags={},num_aliases=1,component=) <Bundle.minimal.apks/not_on_demand.apk>.other@0(size_without_padding=560,padding=0,full_name=AndroidManifest.xml,object_path=,source_path=$APK/AndroidManifest.xml,flags={gen},num_aliases=1,component=) <Bundle.minimal.apks/not_on_demand.apk>.other@0(size_without_padding=0,padding=136,full_name=Overhead: APK file,object_path=,source_path=,flags={},num_aliases=1,component=) -<Bundle.minimal.apks/on_demand.apk?>.other@0(size_without_padding=559,padding=0,full_name=AndroidManifest.xml,object_path=,source_path=$APK/AndroidManifest.xml,flags={gen},num_aliases=1,component=) +<Bundle.minimal.apks/on_demand.apk?>.other@0(size_without_padding=559,padding=0,full_name=AndroidManifest.xml,object_path=,source_path=$APK/AndroidManifest.xml,flags={gen},num_aliases=1,component=DEFAULT) <Bundle.minimal.apks/on_demand.apk?>.other@0(size_without_padding=0,padding=136,full_name=Overhead: APK file,object_path=,source_path=,flags={},num_aliases=1,component=)
diff --git a/tools/binary_size/libsupersize/testdata/supersize.json b/tools/binary_size/libsupersize/testdata/supersize.json new file mode 100644 index 0000000..c2d72cc --- /dev/null +++ b/tools/binary_size/libsupersize/testdata/supersize.json
@@ -0,0 +1,13 @@ +{ + "apk_files": { + "assets/icudtl.dat": { + "source_path": "../../third_party/icu/android/icudtl.dat" + } + }, + "apk_splits": { + "on_demand": { + "default_component": "DEFAULT" + } + } +} +
diff --git a/tools/binary_size/supersize.json b/tools/binary_size/supersize.json new file mode 100644 index 0000000..1492a06 --- /dev/null +++ b/tools/binary_size/supersize.json
@@ -0,0 +1,79 @@ +{ + "apk_files": { + "assets/icudtl.dat": { + "source_path": "../../third_party/icu/android/icudtl.dat" + }, + "assets/snapshot_blob_32.bin": { + "source_path": "../../v8/snapshot_blob_32.bin" + }, + "assets/snapshot_blob_64.bin": { + "source_path": "../../v8/snapshot_blob_64.bin" + }, + "assets/unwind_cfi_32": { + "source_path": "../../base/trace_event/cfi_backtrace_android.cc" + }, + "assets/webapk_dex_version.txt": { + "source_path": "../../chrome/android/webapk/libs/runtime_library_version.gni" + }, + "lib/armeabi-v7a/libarcore_sdk_c_minimal.so": { + "source_path": "../../third_party/arcore-android-sdk/BUILD.gn" + }, + "lib/armeabi-v7a/libarcore_sdk_c.so": { + "source_path": "../../third_party/arcore-android-sdk/BUILD.gn" + }, + "lib/armeabi-v7a/libcrashpad_handler_trampoline.so": { + "source_path": "../../third_party/crashpad/BUILD.gn" + }, + "lib/armeabi-v7a/libyoga.so": { + "source_path": "../../chrome/android/feed/BUILD.gn" + }, + "lib/armeabi-v7a/libelements.so": { + "source_path": "../../chrome/android/feed/BUILD.gn" + }, + "lib/arm64-v8a/libarcore_sdk_c_minimal.so": { + "source_path": "../../third_party/arcore-android-sdk/BUILD.gn" + }, + "lib/arm64-v8a/libarcore_sdk_c.so": { + "source_path": "../../third_party/arcore-android-sdk/BUILD.gn" + }, + "lib/arm64-v8a/libcrashpad_handler_trampoline.so": { + "source_path": "../../third_party/crashpad/BUILD.gn" + }, + "lib/arm64-v8a/libyoga.so": { + "source_path": "../../chrome/android/feed/BUILD.gn" + }, + "lib/arm64-v8a/libelements.so": { + "source_path": "../../chrome/android/feed/BUILD.gn" + } + }, + "apk_splits": { + "autofill_assistant": { + "default_component": "UI>Browser>Autofill>Assistant" + }, + "cablev2_authenticator": { + "default_component": "Blink>WebAuthentication" + }, + "chime": { + "default_component": "UI>Notifications" + }, + "feedv2": { + "default_component": "UI>Browser>ContentSuggestions>Feed" + }, + "image_editor": { + "default_component": "UI>Browser>Sharing" + }, + "stack_unwinder": { + "default_component": "Speed>Tracing" + }, + "survey": { + "default_component": "UI>Browser>Mobile>Surveys" + }, + "vr": { + "default_component": "Internals>XR>VR" + }, + "weblayer": { + "default_component": "Internals>WebLayer" + } + } +} +
diff --git a/tools/clang/blink_gc_plugin/BadPatternFinder.cpp b/tools/clang/blink_gc_plugin/BadPatternFinder.cpp index df0f4ed..8ed7044 100644 --- a/tools/clang/blink_gc_plugin/BadPatternFinder.cpp +++ b/tools/clang/blink_gc_plugin/BadPatternFinder.cpp
@@ -4,6 +4,8 @@ #include "BadPatternFinder.h" #include <clang/AST/Decl.h> +#include "BlinkGCPluginOptions.h" +#include "Config.h" #include "DiagnosticsReporter.h" #include <algorithm> @@ -147,10 +149,42 @@ DiagnosticsReporter& diagnostics_; }; +class MemberOnStackMatcher : public MatchFinder::MatchCallback { + public: + explicit MemberOnStackMatcher(DiagnosticsReporter& diagnostics) + : diagnostics_(diagnostics) {} + + void Register(MatchFinder& match_finder) { + auto class_member_variable_matcher = + varDecl(hasType(recordDecl( + hasAnyName("::blink::Member", "::blink::WeakMember", + "::cppgc::internal::BasicMember")))) + .bind("member"); + match_finder.addDynamicMatcher(class_member_variable_matcher, this); + auto alias_member_variable_matcher = + varDecl(hasType(typeAliasTemplateDecl( + hasAnyName("::blink::Member", "::blink::WeakMember", + "::cppgc::Member", "::cppgc::WeakMember")))) + .bind("member"); + match_finder.addDynamicMatcher(alias_member_variable_matcher, this); + } + + void run(const MatchFinder::MatchResult& result) override { + auto* member = result.Nodes.getNodeAs<clang::VarDecl>("member"); + if (Config::IsIgnoreAnnotated(member)) + return; + diagnostics_.MemberOnStack(member); + } + + private: + DiagnosticsReporter& diagnostics_; +}; + } // namespace void FindBadPatterns(clang::ASTContext& ast_context, - DiagnosticsReporter& diagnostics) { + DiagnosticsReporter& diagnostics, + const BlinkGCPluginOptions& options) { MatchFinder match_finder; UniquePtrGarbageCollectedMatcher unique_ptr_gc(diagnostics); @@ -162,5 +196,10 @@ VariantGarbageCollectedMatcher variant_gc(diagnostics); variant_gc.Register(match_finder); + if (options.enable_members_on_stack_check) { + MemberOnStackMatcher member_on_stack(diagnostics); + member_on_stack.Register(match_finder); + } + match_finder.matchAST(ast_context); }
diff --git a/tools/clang/blink_gc_plugin/BadPatternFinder.h b/tools/clang/blink_gc_plugin/BadPatternFinder.h index 1220b0b..4986ac28 100644 --- a/tools/clang/blink_gc_plugin/BadPatternFinder.h +++ b/tools/clang/blink_gc_plugin/BadPatternFinder.h
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +struct BlinkGCPluginOptions; class DiagnosticsReporter; namespace clang { @@ -10,4 +11,6 @@ // Detects and reports use of banned patterns, such as applying // std::make_unique to a garbage-collected type. -void FindBadPatterns(clang::ASTContext& ast_context, DiagnosticsReporter&); +void FindBadPatterns(clang::ASTContext& ast_context, + DiagnosticsReporter&, + const BlinkGCPluginOptions&);
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp index 3b96099..dcf2916 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp +++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -35,6 +35,10 @@ options_.dump_graph = true; } else if (arg == "enable-weak-members-in-unmanaged-classes") { options_.enable_weak_members_in_unmanaged_classes = true; + } else if (arg == "enable-persistent-in-unique-ptr-check") { + options_.enable_persistent_in_unique_ptr_check = true; + } else if (arg == "enable-members-on-stack-check") { + options_.enable_members_on_stack_check = true; } else { llvm::errs() << "Unknown blink-gc-plugin argument: " << arg << "\n"; return false;
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp index d10e23a..eaf22c4 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
@@ -140,7 +140,7 @@ json_ = 0; } - FindBadPatterns(context, reporter_); + FindBadPatterns(context, reporter_, options_); } void BlinkGCPluginConsumer::ParseFunctionTemplates(TranslationUnitDecl* decl) { @@ -259,7 +259,7 @@ } { - CheckGCRootsVisitor visitor; + CheckGCRootsVisitor visitor(options_); if (visitor.ContainsGCRoots(info)) reporter_.ClassContainsGCRoots(info, visitor.gc_roots()); }
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h b/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h index a9cae8d..2887bae 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h
@@ -26,6 +26,29 @@ // TODO(sof): remove this option once safely rolled out. bool enable_weak_members_in_unmanaged_classes = false; + // Persistent<T> fields are not allowed in garbage collected classes to avoid + // memory leaks. Enabling this flag allows the plugin to check also for + // Persistent<T> in types held by unique_ptr in garbage collected classes. The + // guideline for this check is that a Persistent<T> should never be kept alive + // by a garbage collected class, which unique_ptr clearly conveys. + // + // This check is disabled by default since there are currently non-ignored + // violations of this rule in the code base, leading to compilation failures. + // TODO(chromium:1283867): Enable this checks once all violations are handled. + bool enable_persistent_in_unique_ptr_check = false; + + // On stack references to garbage collected objects should use raw pointers. + // Although using Members/WeakMembers on stack is not strictly incorrect, it + // is redundant and incurs additional costs that can mount up and become + // significant. Enabling this flag lets the plugin to check for instances of + // using Member/WeakMember on stack. These would include variable + // declarations, method arguments and return types. + // + // This check is disabled by default since there currently are violations + // of this rule in the code base, leading to compilation failures. + // TODO(chromium:1283720): Enable this checks once all violations are handled. + bool enable_members_on_stack_check = false; + std::set<std::string> ignored_classes; std::set<std::string> checked_namespaces; std::vector<std::string> ignored_directories;
diff --git a/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.cpp b/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.cpp index 92cfa97..b92225bb 100644 --- a/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.cpp +++ b/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.cpp
@@ -3,8 +3,10 @@ // found in the LICENSE file. #include "CheckGCRootsVisitor.h" +#include "BlinkGCPluginOptions.h" -CheckGCRootsVisitor::CheckGCRootsVisitor() { +CheckGCRootsVisitor::CheckGCRootsVisitor(const BlinkGCPluginOptions& options) + : should_check_unique_ptrs_(options.enable_persistent_in_unique_ptr_check) { } CheckGCRootsVisitor::Errors& CheckGCRootsVisitor::gc_roots() { @@ -43,6 +45,12 @@ visiting_set_.erase(edge->value()); } +void CheckGCRootsVisitor::VisitUniquePtr(UniquePtr* edge) { + if (!should_check_unique_ptrs_) + return; + edge->ptr()->Accept(this); +} + void CheckGCRootsVisitor::VisitPersistent(Persistent* edge) { gc_roots_.push_back(current_); }
diff --git a/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.h b/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.h index 6257d4e3..510d15b 100644 --- a/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.h +++ b/tools/clang/blink_gc_plugin/CheckGCRootsVisitor.h
@@ -11,6 +11,8 @@ #include "Edge.h" #include "RecordInfo.h" +struct BlinkGCPluginOptions; + // This visitor checks that the fields of a class and the fields of // its part objects don't define GC roots. class CheckGCRootsVisitor : public RecursiveEdgeVisitor { @@ -19,19 +21,22 @@ typedef std::set<RecordInfo*> VisitingSet; typedef std::vector<RootPath> Errors; - CheckGCRootsVisitor(); + explicit CheckGCRootsVisitor(const BlinkGCPluginOptions&); Errors& gc_roots(); bool ContainsGCRoots(RecordInfo* info); void VisitValue(Value* edge) override; + void VisitUniquePtr(UniquePtr*) override; void VisitPersistent(Persistent* edge) override; private: RootPath current_; VisitingSet visiting_set_; Errors gc_roots_; + + bool should_check_unique_ptrs_; }; #endif // TOOLS_BLINK_GC_PLUGIN_CHECK_GC_ROOTS_VISITOR_H_
diff --git a/tools/clang/blink_gc_plugin/Config.h b/tools/clang/blink_gc_plugin/Config.h index cf466de..fc84c17 100644 --- a/tools/clang/blink_gc_plugin/Config.h +++ b/tools/clang/blink_gc_plugin/Config.h
@@ -182,7 +182,7 @@ return IsGCBase(name) || IsRefCountedBase(name); } - static bool IsAnnotated(clang::Decl* decl, const std::string& anno) { + static bool IsAnnotated(const clang::Decl* decl, const std::string& anno) { clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>(); return attr && (attr->getAnnotation() == anno); } @@ -191,7 +191,7 @@ return IsAnnotated(decl, "blink_stack_allocated"); } - static bool IsIgnoreAnnotated(clang::Decl* decl) { + static bool IsIgnoreAnnotated(const clang::Decl* decl) { return IsAnnotated(decl, "blink_gc_plugin_ignore"); }
diff --git a/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp b/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp index de7853c4..a6b4e551 100644 --- a/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp +++ b/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp
@@ -137,6 +137,10 @@ "[blink-gc] Member field %0 in stack allocated class declared here (use " "raw pointer or reference instead):"; +const char kMemberOnStack[] = + "[blink-gc] Member variable %0 declared on stack here (use raw pointer or " + "reference instead):"; + const char kUniquePtrUsedWithGC[] = "[blink-gc] Disallowed use of %0 found; %1 is a garbage-collected type. " "std::unique_ptr cannot hold garbage-collected objects."; @@ -215,6 +219,8 @@ getErrorLevel(), kTraceMethodOfStackAllocatedParentNote); diag_member_in_stack_allocated_class_ = diagnostic_.getCustomDiagID(getErrorLevel(), kMemberInStackAllocated); + diag_member_on_stack_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kMemberOnStack); // Register note messages. diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( @@ -571,3 +577,8 @@ ReportDiagnostic(expr->getBeginLoc(), diag_variant_used_with_gc_) << variant << gc_type << expr->getSourceRange(); } + +void DiagnosticsReporter::MemberOnStack(const clang::VarDecl* var) { + ReportDiagnostic(var->getBeginLoc(), diag_member_on_stack_) + << var->getName() << var->getSourceRange(); +}
diff --git a/tools/clang/blink_gc_plugin/DiagnosticsReporter.h b/tools/clang/blink_gc_plugin/DiagnosticsReporter.h index 73ddcd0e..a3f9058 100644 --- a/tools/clang/blink_gc_plugin/DiagnosticsReporter.h +++ b/tools/clang/blink_gc_plugin/DiagnosticsReporter.h
@@ -88,6 +88,7 @@ void VariantUsedWithGC(const clang::Expr* expr, const clang::CXXRecordDecl* variant, const clang::CXXRecordDecl* gc_type); + void MemberOnStack(const clang::VarDecl* var); private: clang::DiagnosticBuilder ReportDiagnostic( @@ -143,6 +144,7 @@ unsigned diag_iterator_to_gc_managed_collection_note_; unsigned diag_trace_method_of_stack_allocated_parent_; unsigned diag_member_in_stack_allocated_class_; + unsigned diag_member_on_stack_; unsigned diag_unique_ptr_used_with_gc_; unsigned diag_optional_field_used_with_gc_;
diff --git a/tools/clang/blink_gc_plugin/tests/member_on_stack.cpp b/tools/clang/blink_gc_plugin/tests/member_on_stack.cpp new file mode 100644 index 0000000..cec06c5 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/member_on_stack.cpp
@@ -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. + +#include "member_on_stack.h" + +namespace blink { + +namespace { + +void FreeMethod() { + Member<HeapObject> strong; + WeakMember<HeapObject> weak; + Member<HeapObject>* ptr; + Member<HeapObject>& ref = strong; +} + +void MethodWithArg(Member<HeapObject>) {} + +void MethodWithConstArg(const Member<HeapObject>) {} + +} // namespace + +void HeapObject::Trace(Visitor* visitor) const {} + +void GCedWithMember::Trace(Visitor* v) const { + v->Trace(member_); +} + +} // namespace blink \ No newline at end of file
diff --git a/tools/clang/blink_gc_plugin/tests/member_on_stack.flags b/tools/clang/blink_gc_plugin/tests/member_on_stack.flags new file mode 100644 index 0000000..00c5036 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/member_on_stack.flags
@@ -0,0 +1 @@ +-Xclang -plugin-arg-blink-gc-plugin -Xclang enable-members-on-stack-check
diff --git a/tools/clang/blink_gc_plugin/tests/member_on_stack.h b/tools/clang/blink_gc_plugin/tests/member_on_stack.h new file mode 100644 index 0000000..65caf06 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/member_on_stack.h
@@ -0,0 +1,33 @@ +// 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 MEMBER_ON_STACK_H +#define MEMBER_ON_STACK_H + +#include "heap/stubs.h" + +namespace blink { + +class HeapObject : public GarbageCollected<HeapObject> { + public: + void Trace(Visitor*) const; + + void DoSomething() { + Member<HeapObject> strong; + WeakMember<HeapObject> weak; + Member<HeapObject>* ptr; + Member<HeapObject>& ref = strong; + } +}; + +class GCedWithMember : public GarbageCollected<GCedWithMember> { + public: + void Trace(Visitor*) const; + + Member<HeapObject> member_; +}; + +} // namespace blink + +#endif // MEMBER_ON_STACK_H \ No newline at end of file
diff --git a/tools/clang/blink_gc_plugin/tests/member_on_stack.txt b/tools/clang/blink_gc_plugin/tests/member_on_stack.txt new file mode 100644 index 0000000..8b564ab1 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/member_on_stack.txt
@@ -0,0 +1,20 @@ +In file included from member_on_stack.cpp:5: +./member_on_stack.h:17:5: warning: [blink-gc] Member variable strong declared on stack here (use raw pointer or reference instead): + Member<HeapObject> strong; + ^~~~~~~~~~~~~~~~~~~~~~~~~ +./member_on_stack.h:18:5: warning: [blink-gc] Member variable weak declared on stack here (use raw pointer or reference instead): + WeakMember<HeapObject> weak; + ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +member_on_stack.cpp:12:3: warning: [blink-gc] Member variable strong declared on stack here (use raw pointer or reference instead): + Member<HeapObject> strong; + ^~~~~~~~~~~~~~~~~~~~~~~~~ +member_on_stack.cpp:13:3: warning: [blink-gc] Member variable weak declared on stack here (use raw pointer or reference instead): + WeakMember<HeapObject> weak; + ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +member_on_stack.cpp:18:20: warning: [blink-gc] Member variable declared on stack here (use raw pointer or reference instead): +void MethodWithArg(Member<HeapObject>) {} + ^~~~~~~~~~~~~~~~~~ +member_on_stack.cpp:20:25: warning: [blink-gc] Member variable declared on stack here (use raw pointer or reference instead): +void MethodWithConstArg(const Member<HeapObject>) {} + ^~~~~~~~~~~~~~~~~~~~~~~~ +6 warnings generated.
diff --git a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.flags b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.flags new file mode 100644 index 0000000..a8f7928 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.flags
@@ -0,0 +1 @@ +-Xclang -plugin-arg-blink-gc-plugin -Xclang enable-persistent-in-unique-ptr-check
diff --git a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.h b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.h index a7be7e0..5b954c14 100644 --- a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.h +++ b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.h
@@ -24,6 +24,7 @@ private: PartObject m_part; HeapVector<PartObject> m_parts; + std::unique_ptr<PartObject> m_unique_part; Persistent<HeapVector<Member<HeapObject>>> m_objs; WeakPersistent<HeapObject> m_weakPersistent; };
diff --git a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt index 4f6c99bc..f10b7c5 100644 --- a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt +++ b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt
@@ -17,16 +17,25 @@ ./persistent_field_in_gc_managed_class.h:17:5: note: [blink-gc] Field 'm_obj' defining a GC root declared here: Persistent<HeapObject> m_obj; ^ +./persistent_field_in_gc_managed_class.h:20:1: warning: [blink-gc] Class 'HeapObject' contains GC root in field 'm_unique_part'. +class HeapObject : public GarbageCollected<HeapObject> { +^ +./persistent_field_in_gc_managed_class.h:27:5: note: [blink-gc] Field 'm_unique_part' with embedded GC root in 'HeapObject' declared here: + std::unique_ptr<PartObject> m_unique_part; + ^ +./persistent_field_in_gc_managed_class.h:17:5: note: [blink-gc] Field 'm_obj' defining a GC root declared here: + Persistent<HeapObject> m_obj; + ^ ./persistent_field_in_gc_managed_class.h:20:1: warning: [blink-gc] Class 'HeapObject' contains GC root in field 'm_objs'. class HeapObject : public GarbageCollected<HeapObject> { ^ -./persistent_field_in_gc_managed_class.h:27:5: note: [blink-gc] Field 'm_objs' defining a GC root declared here: +./persistent_field_in_gc_managed_class.h:28:5: note: [blink-gc] Field 'm_objs' defining a GC root declared here: Persistent<HeapVector<Member<HeapObject>>> m_objs; ^ ./persistent_field_in_gc_managed_class.h:20:1: warning: [blink-gc] Class 'HeapObject' contains GC root in field 'm_weakPersistent'. class HeapObject : public GarbageCollected<HeapObject> { ^ -./persistent_field_in_gc_managed_class.h:28:5: note: [blink-gc] Field 'm_weakPersistent' defining a GC root declared here: +./persistent_field_in_gc_managed_class.h:29:5: note: [blink-gc] Field 'm_weakPersistent' defining a GC root declared here: WeakPersistent<HeapObject> m_weakPersistent; ^ -4 warnings generated. +5 warnings generated.
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp index 35ee420..d908f66b 100644 --- a/tools/clang/plugins/FindBadConstructsAction.cpp +++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -57,6 +57,8 @@ options_.checked_ptr_as_trivial_member = true; } else if (args[i] == "raw-ptr-template-as-trivial-member") { options_.raw_ptr_template_as_trivial_member = true; + } else if (args[i] == "use-classify-type") { + options_.use_classify_type = true; } else { parsed = false; llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp index 49301625..d0f28a4 100644 --- a/tools/clang/plugins/FindBadConstructsConsumer.cpp +++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -384,10 +384,28 @@ for (RecordDecl::field_iterator it = record->field_begin(); it != record->field_end(); ++it) { - CountType(it->getType().getTypePtr(), - &trivial_member, - &non_trivial_member, - &templated_non_trivial_member); + if (options_.use_classify_type) { + switch (ClassifyType(it->getType().getTypePtr())) { + case TypeClassification::kTrivial: + trivial_member += 1; + break; + case TypeClassification::kNonTrivial: + non_trivial_member += 1; + break; + case TypeClassification::kTrivialTemplate: + trivial_member += 1; + break; + case TypeClassification::kNonTrivialTemplate: + templated_non_trivial_member += 1; + break; + case TypeClassification::kNonTrivialExternTemplate: + non_trivial_member += 1; + break; + } + } else { + CountType(it->getType().getTypePtr(), &trivial_member, + &non_trivial_member, &templated_non_trivial_member); + } } // Check to see if we need to ban inlined/synthesized constructors. Note @@ -671,6 +689,132 @@ } } +FindBadConstructsConsumer::TypeClassification +FindBadConstructsConsumer::ClassifyType(const Type* type) { + switch (type->getTypeClass()) { + case Type::Record: { + auto* record_decl = type->getAsCXXRecordDecl(); + // Simplifying; the whole class isn't trivial if the dtor is, but + // we use this as a signal about complexity. + // Note that if a record doesn't have a definition, it doesn't matter how + // it's counted, since the translation unit will fail to build. In that + // case, just count it as a trivial member to avoid emitting warnings that + // might be spurious. + if (!record_decl->hasDefinition() || record_decl->hasTrivialDestructor()) + return TypeClassification::kTrivial; + + const auto name = record_decl->getQualifiedNameAsString(); + + // `std::basic_string` is externed by libc++, so even though it's a + // non-trivial type wrapped by a template, we shouldn't classify it as a + // `kNonTrivialTemplate`. The `kNonTrivialExternTemplate` classification + // exists for this purpose. + // https://github.com/llvm-mirror/libcxx/blob/78d6a7767ed57b50122a161b91f59f19c9bd0d19/include/string#L4317 + if (name == "std::basic_string") + return TypeClassification::kNonTrivialExternTemplate; + + // `base::raw_ptr` is non-trivial if the `use_backup_ref_ptr` flag is + // enabled, and trivial otherwise. Since there are many existing types + // using this that we don't wish to burden with defining custom + // ctors/dtors, and we'd rather not vary on triviality by build config, + // treat this as always trivial. + if (name == "base::raw_ptr") + return TypeClassification::kTrivialTemplate; + + return TypeClassification::kNonTrivial; + } + case Type::TemplateSpecialization: { + // A "Template Specialization" is a type produced by providing arguments + // to any type template, not necessarily just a template which has + // explicitly declared specializations. This may be a regular type + // template, or a templated type alias. + // + // A great way to reason about templates is as a compile-time function + // taking compile-time arguments, and producing a regular type. In the + // context of a `TemplateSpecializationType`, we're referring to this + // particular invocation of that function. We can "desugar" that into the + // produced type, which is no longer seen as a template. + // + // Types produced by templates are of particular concern here, since they + // almost certainly have inline ctors/dtors and may result in lots of code + // being generated for types containing them. For that reason, non-trivial + // templates are weighted higher than regular non-trivial types. + auto* template_type = dyn_cast<TemplateSpecializationType>(type); + + // If this is a template type alias, just consider the underlying type + // without the context of it being a template. + // For an example: + // + // template <typename T> + // using Foo = Bar<T>; + // + // Given `Foo<Baz>`, we want to classify it simply as `Bar<Baz>` would be. + if (template_type->isTypeAlias()) + return ClassifyType(template_type->getAliasedType().getTypePtr()); + + // Otherwise, classify the type produced by the template and apply the + // corresponding template classification. For an example: + // + // template <typename T> + // struct Foo { ... }; + // + // Given `Foo<Baz>`, classify `struct Foo { ... };` with `Baz` substituted + // for `T`; + const auto classification = + ClassifyType(template_type->desugar().getTypePtr()); + if (classification == TypeClassification::kTrivial) + return TypeClassification::kTrivialTemplate; + if (classification == TypeClassification::kNonTrivial) + return TypeClassification::kNonTrivialTemplate; + + return classification; + } + case Type::SubstTemplateTypeParm: { + // `SubstTemplateTypeParmType` appears wherever a template type parameter + // is encountered, and may be desugared into the type argument given to + // the template. For example: + // + // template <typename T> + // struct Foo { + // T bar; // <-- `bar` here is a `SubstTemplateTypeParmType` + // }; + // + // or + // + // template <typename T> + // using Foo = T; // <-- `T` here is a `SubstTemplateTypeParmType` + const auto* const subst_type = dyn_cast<SubstTemplateTypeParmType>(type) + ->getReplacementType() + .getTypePtr(); + return ClassifyType(subst_type); + } + case Type::Elaborated: { + // Quote from the LLVM documentation: + // "Represents a type that was referred to using an elaborated type + // keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, or + // both. This type is used to keep track of a type name as written in the + // source code, including tag keywords and any nested-name-specifiers. The + // type itself is always "sugar", used to express what was written in the + // source code but containing no additional semantic information." + return ClassifyType( + dyn_cast<ElaboratedType>(type)->getNamedType().getTypePtr()); + } + case Type::Typedef: { + // A "typedef type" is the representation of a type named through a + // typedef (or a C++11 type alias). In this case, we don't care about the + // typedef itself, so we desugar it into the underlying type and classify + // that. + const auto* const decl = dyn_cast<TypedefType>(type)->getDecl(); + return ClassifyType(decl->getUnderlyingType().getTypePtr()); + } + default: { + // Stupid assumption: anything we see that isn't the above is a POD + // or reference type. + return TypeClassification::kTrivial; + } + } +} + void FindBadConstructsConsumer::CountType(const Type* type, int* trivial_member, int* non_trivial_member,
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.h b/tools/clang/plugins/FindBadConstructsConsumer.h index 5a78d77..72bb46b 100644 --- a/tools/clang/plugins/FindBadConstructsConsumer.h +++ b/tools/clang/plugins/FindBadConstructsConsumer.h
@@ -84,6 +84,15 @@ void CheckVirtualSpecifiers(const clang::CXXMethodDecl* method); void CheckVirtualBodies(const clang::CXXMethodDecl* method); + enum class TypeClassification { + kTrivial, + kNonTrivial, + kTrivialTemplate, + kNonTrivialTemplate, + kNonTrivialExternTemplate + }; + TypeClassification ClassifyType(const clang::Type* type); + void CountType(const clang::Type* type, int* trivial_member, int* non_trivial_member,
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h index e3e29e1..693e877 100644 --- a/tools/clang/plugins/Options.h +++ b/tools/clang/plugins/Options.h
@@ -14,6 +14,7 @@ bool check_layout_object_methods = false; bool checked_ptr_as_trivial_member = false; bool raw_ptr_template_as_trivial_member = false; + bool use_classify_type = false; }; } // namespace chrome_checker
diff --git a/tools/clang/plugins/tests/atomic_member.cpp b/tools/clang/plugins/tests/atomic_member.cpp new file mode 100644 index 0000000..748cef6 --- /dev/null +++ b/tools/clang/plugins/tests/atomic_member.cpp
@@ -0,0 +1,5 @@ +// 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 "atomic_member.h"
diff --git a/tools/clang/plugins/tests/atomic_member.flags b/tools/clang/plugins/tests/atomic_member.flags new file mode 100644 index 0000000..5b0499f --- /dev/null +++ b/tools/clang/plugins/tests/atomic_member.flags
@@ -0,0 +1 @@ +-Xclang -plugin-arg-find-bad-constructs -Xclang use-classify-type
diff --git a/tools/clang/plugins/tests/atomic_member.h b/tools/clang/plugins/tests/atomic_member.h new file mode 100644 index 0000000..a709ce5c --- /dev/null +++ b/tools/clang/plugins/tests/atomic_member.h
@@ -0,0 +1,96 @@ +// 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 TOOLS_CLANG_PLUGINS_TESTS_ATOMIC_MEMBER_H_ +#define TOOLS_CLANG_PLUGINS_TESTS_ATOMIC_MEMBER_H_ + +#include <atomic> +#include <memory> + +// The standard says that std::atomic<Integral> (where Integral is a built-in +// integral type, including raw pointers) is a standard-layout struct, and has a +// trivial destructor: +// https://eel.is/c++draft/atomics.types.generic#atomics.types.int-2 Because of +// that, we classify std::atomic<Integral> as a trivial template. + +struct NineAtomicIntAliasesOk { + std::atomic_int one; + std::atomic_int two; + std::atomic_int three; + std::atomic_int four; + std::atomic_int five; + std::atomic_int six; + std::atomic_int seven; + std::atomic_int eight; + std::atomic_int nine; +}; + +struct TenAtomicIntAliasesWarns { + std::atomic_int one; + std::atomic_int two; + std::atomic_int three; + std::atomic_int four; + std::atomic_int five; + std::atomic_int six; + std::atomic_int seven; + std::atomic_int eight; + std::atomic_int nine; + std::atomic_int ten; +}; + +struct NineAtomicIntTemplatesOk { + std::atomic<int> one; + std::atomic<int> two; + std::atomic<int> three; + std::atomic<int> four; + std::atomic<int> five; + std::atomic<int> six; + std::atomic<int> seven; + std::atomic<int> eight; + std::atomic<int> nine; +}; + +struct TenAtomicIntTemplatesWarns { + std::atomic<int> one; + std::atomic<int> two; + std::atomic<int> three; + std::atomic<int> four; + std::atomic<int> five; + std::atomic<int> six; + std::atomic<int> seven; + std::atomic<int> eight; + std::atomic<int> nine; + std::atomic<int> ten; +}; + +struct NineAtomicPtrsOk { + std::atomic<int*> one; + std::atomic<int*> two; + std::atomic<int*> three; + std::atomic<int*> four; + std::atomic<int*> five; + std::atomic<int*> six; + std::atomic<int*> seven; + std::atomic<int*> eight; + std::atomic<int*> nine; +}; + +struct TenAtomicPtrsWarns { + std::atomic<int*> one; + std::atomic<int*> two; + std::atomic<int*> three; + std::atomic<int*> four; + std::atomic<int*> five; + std::atomic<int*> six; + std::atomic<int*> seven; + std::atomic<int*> eight; + std::atomic<int*> nine; + std::atomic<int*> ten; +}; + +struct OneAtomicSharedPtrWarns { + std::atomic<std::shared_ptr<int>> one; +}; + +#endif // TOOLS_CLANG_PLUGINS_TESTS_ATOMIC_MEMBER_H_
diff --git a/tools/clang/plugins/tests/atomic_member.txt b/tools/clang/plugins/tests/atomic_member.txt new file mode 100644 index 0000000..661d3d8a --- /dev/null +++ b/tools/clang/plugins/tests/atomic_member.txt
@@ -0,0 +1,15 @@ +In file included from atomic_member.cpp:5: +./atomic_member.h:29:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +struct TenAtomicIntAliasesWarns { +^ +./atomic_member.h:54:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +struct TenAtomicIntTemplatesWarns { +^ +./atomic_member.h:79:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +struct TenAtomicPtrsWarns { +^ +./atomic_member.h:92:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +struct OneAtomicSharedPtrWarns { +^ +./atomic_member.h:92:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line destructor. +5 warnings generated.
diff --git a/tools/clang/plugins/tests/missing_ctor.flags b/tools/clang/plugins/tests/missing_ctor.flags index 8861a151d..bd23382f 100644 --- a/tools/clang/plugins/tests/missing_ctor.flags +++ b/tools/clang/plugins/tests/missing_ctor.flags
@@ -1 +1 @@ --Xclang -plugin-arg-find-bad-constructs -Xclang checked-ptr-as-trivial-member -Xclang -plugin-arg-find-bad-constructs -Xclang raw-ptr-template-as-trivial-member +-Xclang -plugin-arg-find-bad-constructs -Xclang checked-ptr-as-trivial-member -Xclang -plugin-arg-find-bad-constructs -Xclang raw-ptr-template-as-trivial-member -Xclang -plugin-arg-find-bad-constructs -Xclang use-classify-type
diff --git a/tools/clang/plugins/tests/missing_ctor.h b/tools/clang/plugins/tests/missing_ctor.h index 0d24cac..92958be 100644 --- a/tools/clang/plugins/tests/missing_ctor.h +++ b/tools/clang/plugins/tests/missing_ctor.h
@@ -24,6 +24,14 @@ MyVector(MyVector&&); }; +template <class T> +struct TrivialTemplate { + TrivialTemplate(); +}; + +template <typename T> +using AliasTemplate = T; + // Note: this should warn for an implicit copy constructor too, but currently // doesn't, due to a plugin bug. class MissingCtorsArentOKInHeader { @@ -127,6 +135,126 @@ std::string four_; }; +class TrivialTemplateDoesNotWarn { + public: + TrivialTemplateDoesNotWarn() = default; + ~TrivialTemplateDoesNotWarn() = default; + + private: + TrivialTemplate<int> foo_; +}; + +class NineTrivialTemplatesDoesNotWarn { + public: + NineTrivialTemplatesDoesNotWarn() = default; + ~NineTrivialTemplatesDoesNotWarn() = default; + + private: + TrivialTemplate<int> one_; + TrivialTemplate<int> two_; + TrivialTemplate<int> three_; + TrivialTemplate<int> four_; + TrivialTemplate<int> five_; + TrivialTemplate<int> six_; + TrivialTemplate<int> seven_; + TrivialTemplate<int> eight_; + TrivialTemplate<int> nine_; +}; + +class TenTrivialTemplatesWarns { + public: + TenTrivialTemplatesWarns() = default; + ~TenTrivialTemplatesWarns() = default; + + private: + TrivialTemplate<int> one_; + TrivialTemplate<int> two_; + TrivialTemplate<int> three_; + TrivialTemplate<int> four_; + TrivialTemplate<int> five_; + TrivialTemplate<int> six_; + TrivialTemplate<int> seven_; + TrivialTemplate<int> eight_; + TrivialTemplate<int> nine_; + TrivialTemplate<int> ten_; +}; + +class TrivialAliasTemplateDoesNotWarn { + public: + TrivialAliasTemplateDoesNotWarn() = default; + ~TrivialAliasTemplateDoesNotWarn() = default; + + private: + AliasTemplate<int> one_; +}; + +class NineTrivialAliasTemplatesDoesNotWarn { + public: + NineTrivialAliasTemplatesDoesNotWarn() = default; + ~NineTrivialAliasTemplatesDoesNotWarn() = default; + + private: + AliasTemplate<int> one_; + AliasTemplate<int> two_; + AliasTemplate<int> three_; + AliasTemplate<int> four_; + AliasTemplate<int> five_; + AliasTemplate<int> six_; + AliasTemplate<int> seven_; + AliasTemplate<int> eight_; + AliasTemplate<int> nine_; +}; + +class TenTrivialAliasTemplatesWarns { + public: + TenTrivialAliasTemplatesWarns() = default; + ~TenTrivialAliasTemplatesWarns() = default; + + private: + AliasTemplate<int> one_; + AliasTemplate<int> two_; + AliasTemplate<int> three_; + AliasTemplate<int> four_; + AliasTemplate<int> five_; + AliasTemplate<int> six_; + AliasTemplate<int> seven_; + AliasTemplate<int> eight_; + AliasTemplate<int> nine_; + AliasTemplate<int> ten_; +}; + +class NonTrivialAliasTemplateDoesNotWarn { + public: + NonTrivialAliasTemplateDoesNotWarn() = default; + ~NonTrivialAliasTemplateDoesNotWarn() = default; + + private: + AliasTemplate<std::string> one_; +}; + +class ThreeNonTrivialAliasTemplatesDoesNotWarn { + public: + ThreeNonTrivialAliasTemplatesDoesNotWarn() = default; + ~ThreeNonTrivialAliasTemplatesDoesNotWarn() = default; + + private: + AliasTemplate<std::string> one_; + AliasTemplate<std::string> two_; + AliasTemplate<std::string> three_; +}; + +class FourNonTrivialAliasTemplatesWarns { + public: + FourNonTrivialAliasTemplatesWarns() = default; + ~FourNonTrivialAliasTemplatesWarns() = default; + + private: + AliasTemplate<std::string> one_; + AliasTemplate<std::string> two_; + AliasTemplate<std::string> three_; + AliasTemplate<std::string> four_; +}; + class CheckedPtrDoesNotWarn { public: CheckedPtrDoesNotWarn() = default;
diff --git a/tools/clang/plugins/tests/missing_ctor.txt b/tools/clang/plugins/tests/missing_ctor.txt index fd76530e..fc64f5f 100644 --- a/tools/clang/plugins/tests/missing_ctor.txt +++ b/tools/clang/plugins/tests/missing_ctor.txt
@@ -1,24 +1,39 @@ In file included from missing_ctor.cpp:5: -./missing_ctor.h:29:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +./missing_ctor.h:37:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. class MissingCtorsArentOKInHeader { ^ -./missing_ctor.h:29:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line destructor. -./missing_ctor.h:55:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor.h:37:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line destructor. +./missing_ctor.h:63:3: warning: [chromium-style] Complex constructor has an inlined body. ExplicitlyDefaultedInlineAlsoWarns() = default; ^ -./missing_ctor.h:57:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor.h:65:3: warning: [chromium-style] Complex constructor has an inlined body. ExplicitlyDefaultedInlineAlsoWarns( ^ -./missing_ctor.h:56:3: warning: [chromium-style] Complex destructor has an inline body. +./missing_ctor.h:64:3: warning: [chromium-style] Complex destructor has an inline body. ~ExplicitlyDefaultedInlineAlsoWarns() = default; ^ -./missing_ctor.h:120:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor.h:128:3: warning: [chromium-style] Complex constructor has an inlined body. FourStringsWarns() = default; ^ -./missing_ctor.h:158:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor.h:129:3: warning: [chromium-style] Complex destructor has an inline body. + ~FourStringsWarns() = default; + ^ +./missing_ctor.h:166:3: warning: [chromium-style] Complex constructor has an inlined body. + TenTrivialTemplatesWarns() = default; + ^ +./missing_ctor.h:210:3: warning: [chromium-style] Complex constructor has an inlined body. + TenTrivialAliasTemplatesWarns() = default; + ^ +./missing_ctor.h:248:3: warning: [chromium-style] Complex constructor has an inlined body. + FourNonTrivialAliasTemplatesWarns() = default; + ^ +./missing_ctor.h:249:3: warning: [chromium-style] Complex destructor has an inline body. + ~FourNonTrivialAliasTemplatesWarns() = default; + ^ +./missing_ctor.h:286:3: warning: [chromium-style] Complex constructor has an inlined body. TenCheckedPtrWarns() = default; ^ -./missing_ctor.h:202:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor.h:330:3: warning: [chromium-style] Complex constructor has an inlined body. TenRawPtrWarns() = default; ^ -8 warnings generated. +13 warnings generated.
diff --git a/tools/clang/plugins/tests/missing_ctor_dllexport.h b/tools/clang/plugins/tests/missing_ctor_dllexport.h index 13ad524..43ffcc9 100644 --- a/tools/clang/plugins/tests/missing_ctor_dllexport.h +++ b/tools/clang/plugins/tests/missing_ctor_dllexport.h
@@ -9,6 +9,7 @@ MyString(); MyString(const MyString&); MyString(MyString&&); + ~MyString(); }; template <class T> @@ -16,6 +17,7 @@ MyVector(); MyVector(const MyVector&); MyVector(MyVector&&); + ~MyVector(); }; // For now, this should only warn on the missing constructor, not on the missing
diff --git a/tools/clang/plugins/tests/missing_ctor_dllexport.txt b/tools/clang/plugins/tests/missing_ctor_dllexport.txt index 403a118..a100d1f 100644 --- a/tools/clang/plugins/tests/missing_ctor_dllexport.txt +++ b/tools/clang/plugins/tests/missing_ctor_dllexport.txt
@@ -1,14 +1,18 @@ In file included from missing_ctor_dllexport.cpp:5: -./missing_ctor_dllexport.h:23:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. +./missing_ctor_dllexport.h:25:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line constructor. class __declspec(dllexport) MissingCtorsArentOKInHeader { ^ -./missing_ctor_dllexport.h:47:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor_dllexport.h:25:1: warning: [chromium-style] Complex class/struct needs an explicit out-of-line destructor. +./missing_ctor_dllexport.h:49:3: warning: [chromium-style] Complex constructor has an inlined body. ExplicitlyDefaultedInlineAlsoWarns() = default; ^ -./missing_ctor_dllexport.h:49:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor_dllexport.h:51:3: warning: [chromium-style] Complex constructor has an inlined body. ExplicitlyDefaultedInlineAlsoWarns( ^ -./missing_ctor_dllexport.h:51:3: warning: [chromium-style] Complex constructor has an inlined body. +./missing_ctor_dllexport.h:53:3: warning: [chromium-style] Complex constructor has an inlined body. ExplicitlyDefaultedInlineAlsoWarns(ExplicitlyDefaultedInlineAlsoWarns&&) = ^ -4 warnings generated. +./missing_ctor_dllexport.h:50:3: warning: [chromium-style] Complex destructor has an inline body. + ~ExplicitlyDefaultedInlineAlsoWarns() = default; + ^ +6 warnings generated.
diff --git a/tools/clang/plugins/tests/system/atomic b/tools/clang/plugins/tests/system/atomic new file mode 100644 index 0000000..cbc37ea --- /dev/null +++ b/tools/clang/plugins/tests/system/atomic
@@ -0,0 +1,44 @@ +// 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 TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_ATOMIC_ +#define TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_ATOMIC_ + +namespace std { + +// Faux-implementation of std::atomic. +// The standard requires that the following conditions are met for `T`: +// std::is_copy_constructible<T>::value == true +// std::is_move_constructible<T>::value == true +// std::is_copy_assignable<T>::value == true +// std::is_move_assignable<T>::value == true +// std::is_trivially_copyable<T>::value == true +// +// An exception is made to the last condition for +// std::atomic<std::shared_ptr<T>> and std::atomic<std::weak_ptr<T>>, by +// defining partial-specializations in <memory> +// +// The standard also says that std::atomic<Integral> (where `Integral` is a +// built-in integral type, including raw pointers) is a standard-layout struct, +// and has a trivial destructor: +// https://eel.is/c++draft/atomics.types.generic#atomics.types.int-2 +template <typename T> +struct atomic { + T i; + + atomic(); + ~atomic() = default; + + // std::atomic is never copyable or moveable + atomic(const atomic&) = delete; + atomic(atomic&&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(atomic&&) = delete; +}; + +using atomic_int = std::atomic<int>; + +} // namespace std + +#endif // TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_ATOMIC_
diff --git a/tools/clang/plugins/tests/system/memory b/tools/clang/plugins/tests/system/memory new file mode 100644 index 0000000..65f8521 --- /dev/null +++ b/tools/clang/plugins/tests/system/memory
@@ -0,0 +1,42 @@ +// 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 TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_MEMORY_ +#define TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_MEMORY_ + +#include <atomic> + +namespace std { + +template <typename T> +struct shared_ptr { + shared_ptr(); + ~shared_ptr(); + shared_ptr(const shared_ptr&); + shared_ptr(shared_ptr&&); + shared_ptr& operator=(const shared_ptr&); + shared_ptr& operator=(shared_ptr&&); + + private: + T* ptr_ = nullptr; +}; + +// The STL has this specialization defined through <memory>. +// Normally template parameters to std::atomic must be trivially copyable, +// but exceptions are made for std::shared_ptr and std::weak_ptr. +template <typename T> +struct atomic<shared_ptr<T> > { + shared_ptr<T> i; + + atomic(); + ~atomic(); + atomic(const atomic&) = delete; + atomic(atomic&&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(atomic&&) = delete; +}; + +} // namespace std + +#endif // TOOLS_CLANG_PLUGINS_TESTS_SYSTEM_MEMORY_
diff --git a/tools/clang/plugins/tests/system/string b/tools/clang/plugins/tests/system/string index c733851e..a0c247fd 100644 --- a/tools/clang/plugins/tests/system/string +++ b/tools/clang/plugins/tests/system/string
@@ -8,7 +8,11 @@ namespace std { template<typename CharType> -class basic_string { +struct basic_string { + basic_string(); + basic_string(const basic_string&); + basic_string(basic_string&&); + ~basic_string(); }; using string = basic_string<char>;
diff --git a/tools/clang/plugins/tests/system/vector b/tools/clang/plugins/tests/system/vector index e786000..ded0c28 100644 --- a/tools/clang/plugins/tests/system/vector +++ b/tools/clang/plugins/tests/system/vector
@@ -8,7 +8,11 @@ namespace std { template<typename T> -class vector { +struct vector { + vector(); + vector(const vector&); + vector(vector&&); + ~vector(); }; } // namespace std
diff --git a/tools/clang/plugins/tests/trivial_ctor.cpp b/tools/clang/plugins/tests/trivial_ctor.cpp deleted file mode 100644 index c632fafe7..0000000 --- a/tools/clang/plugins/tests/trivial_ctor.cpp +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "trivial_ctor.h" - -// Due to https://bugs.chromium.org/p/chromium/issues/detail?id=663463, we treat -// templated classes/structs as non-trivial, even if they really are trivial. -// Thus, classes that have such a class/struct as a member get flagged as being -// themselves non-trivial, even if (like |MySpinLock|) they are. Special-case -// [std::]atomic_int. -class TrivialTemplateOK { - private: - MySpinLock lock_; -}; - -int main() { - MySpinLock lock; - TrivialTemplateOK one; - return 0; -}
diff --git a/tools/clang/plugins/tests/trivial_ctor.h b/tools/clang/plugins/tests/trivial_ctor.h deleted file mode 100644 index 2fa3003d..0000000 --- a/tools/clang/plugins/tests/trivial_ctor.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef TRIVIAL_CTOR_H_ -#define TRIVIAL_CTOR_H_ - -// Mocked for testing: -namespace std { - -template<typename T> -struct atomic { - T i; -}; - -typedef atomic<int> atomic_int; - -} // namespace std - -struct MySpinLock { - MySpinLock(); - ~MySpinLock(); - MySpinLock(const MySpinLock&); - MySpinLock(MySpinLock&&); - std::atomic_int lock_; -}; - -#endif // TRIVIAL_CTOR_H_
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index d86fc210..5718772 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -1279,6 +1279,9 @@ if sys.platform != 'darwin': CopyFile(os.path.join(build_phase2_dir, 'lib', target_spec, asan_so), fuchsia_lib_dst_dir) + CopyFile( + os.path.join(build_phase2_dir, 'lib', target_spec, + asan_preinit_a), fuchsia_lib_dst_dir) # Run tests. if (not args.build_mac_arm and
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 0f9ebc18..4b55f6f 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. CLANG_REVISION = 'llvmorg-14-init-12719-gc4b45eeb' -CLANG_SUB_REVISION = 1 +CLANG_SUB_REVISION = 2 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) RELEASE_VERSION = '14.0.0'
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py index 8f57960b..8c0c24e 100755 --- a/tools/code_coverage/coverage.py +++ b/tools/code_coverage/coverage.py
@@ -862,7 +862,7 @@ LLVM_PROFILE_FILE_PATH_SUBSTITUTION, '--child-processes=%d' % cpu_count, '--disable-breakpad', '--no-show-results', '--skip-failing-tests', - '--target=%s' % os.path.basename(BUILD_DIR), '--time-out-ms=30000' + '--target=%s' % os.path.basename(BUILD_DIR), '--timeout-ms=30000' ] if arguments.strip(): command_list.append(arguments)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 246aeff..b9c4463 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -210,8 +210,6 @@ 'ToTWin64(dll)': 'clang_tot_shared_release_dcheck', 'ToTWin64PGO': 'clang_tot_official_pgo', 'ToTWinASanLibfuzzer': 'libfuzzer_windows_asan_clang_tot_release_bot', - 'ToTWinCFI': 'clang_tot_win_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_x86', - 'ToTWinCFI64': 'clang_tot_win_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on', 'ToTWindowsCoverage': 'clang_tot_coverage_minimal_symbols_release', 'ToTiOS': 'ios_clang_tot_xctest', 'ToTiOSDevice': 'ios_clang_device_tot_xctest', @@ -325,9 +323,10 @@ 'fuchsia-fyi-arm64-dbg': 'debug_bot_fuchsia_arm64', 'fuchsia-fyi-arm64-femu': 'release_bot_fuchsia_arm64', 'fuchsia-fyi-arm64-rel': 'release_bot_fuchsia_arm64', + 'fuchsia-fyi-x64-asan': 'asan_bot_fuchsia', 'fuchsia-fyi-x64-dbg': 'debug_bot_fuchsia', 'fuchsia-fyi-x64-rel': 'release_bot_fuchsia', - 'fuchsia-fyi-x64-asan': 'asan_bot_fuchsia', + 'fuchsia-fyi-x64-wst': 'fuchsia_workstation_bot', 'ios14-beta-simulator': 'ios_simulator_debug_static_bot_xctest', 'ios14-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_arm64', 'ios15-beta-simulator': 'ios_simulator_debug_static_bot_xctest', @@ -464,19 +463,13 @@ 'chromium.gpu.fyi': { # These all use the 'trybot' mixins to ensure that dcheck is on. 'ANGLE GPU Android Release (Nexus 5X)': 'gpu_tests_android_release_trybot_arm64', - 'Android FYI Release (Nexus 5)': 'gpu_tests_android_release_trybot_reclient', - 'Android FYI Release (Nexus 5X)': 'gpu_tests_android_release_trybot_arm64_reclient', - 'Android FYI Release (Nexus 9)': 'gpu_tests_android_release_trybot_arm64_reclient', - 'Android FYI Release (NVIDIA Shield TV)': 'gpu_tests_android_release_trybot_arm64', - 'Android FYI Release (Pixel 2)': 'gpu_tests_android_release_trybot_reclient', - 'Android FYI Release (Pixel 4)': 'gpu_tests_android_release_trybot_reclient', - 'Android FYI SkiaRenderer GL (Nexus 5X)': 'gpu_tests_android_release_trybot_arm64_reclient', - 'Android FYI SkiaRenderer Vulkan (Pixel 2)': 'gpu_tests_android_release_trybot_reclient', 'ChromeOS FYI Release (amd64-generic)': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols', 'ChromeOS FYI Release (kevin)': 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off_no_symbols', + 'GPU FYI Android arm Builder': 'gpu_tests_android_release_trybot_reclient', + 'GPU FYI Android arm64 Builder': 'gpu_tests_android_release_trybot_arm64_reclient', 'GPU FYI Lacros x64 Builder': 'gpu_tests_ozone_linux_non_x11_release_trybot', - 'GPU FYI Linux Builder': 'gpu_fyi_tests_release_trybot', - 'GPU FYI Linux Builder (dbg)': 'gpu_fyi_tests_debug_trybot', + 'GPU FYI Linux Builder': 'gpu_fyi_tests_release_trybot_reclient', + 'GPU FYI Linux Builder (dbg)': 'gpu_fyi_tests_debug_trybot_reclient', 'GPU FYI Mac Builder': 'gpu_fyi_tests_release_trybot', 'GPU FYI Mac Builder (asan)': 'gpu_fyi_tests_release_trybot_asan', 'GPU FYI Mac Builder (dbg)': 'gpu_fyi_tests_debug_trybot', @@ -728,11 +721,6 @@ 'Windows deterministic': 'release_bot_x86_minimal_symbols', }, - 'infra': { - 'linux-bootstrap': 'release_bot', - 'win-bootstrap': 'release_bot', - }, - 'internal.chrome.fyi': { 'chromeos-amd64-generic-lacros-internal-rel': 'chromeos_amd64-generic_lacros_rel', 'linux-autofill-captured-sites-rel': 'release_bot', @@ -849,7 +837,6 @@ 'android-binary-size': 'android_binary_size', 'android_blink_rel': 'android_release_trybot', 'android_cfi_rel_ng': 'android_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_goma', - 'android_clang_dbg_recipe': 'android_clang_asan_debug_trybot_compile_only_fastbuild', 'android_compile_dbg': 'android_debug_trybot_compile_only', 'android_compile_x64_dbg': 'android_debug_trybot_compile_only_x64', 'android_compile_x86_dbg': 'android_debug_trybot_compile_only_x86', @@ -1206,7 +1193,6 @@ 'win10_chromium_x64_rel_ng': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', 'win10_chromium_x64_rel_ng_exp': 'release_trybot', 'win10_chromium_x64_rel_ng_rts': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', - 'win10_chromium_x64_20h2_fyi_rel_ng': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', 'win10-rel-orchestrator': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', 'win-annotator-rel': 'release_trybot', 'win-asan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release', @@ -1230,11 +1216,6 @@ 'devtools_frontend_linux_blink_rel': 'release_trybot_blink', }, - 'tryserver.infra': { - 'linux-bootstrap': 'release_trybot', - 'win-bootstrap': 'release_trybot', - }, - 'tryserver.v8': { 'v8_linux_blink_rel': 'release_trybot_blink', 'v8_linux_chromium_gn_rel': 'release_trybot', @@ -1283,11 +1264,6 @@ 'android', 'clang', 'asan', 'debug_bot_reclient', 'strip_debug_info', ], - 'android_clang_asan_debug_trybot_compile_only_fastbuild': [ - 'android', 'clang', 'asan', 'debug_bot', 'compile_only', - 'android_fastbuild', - ], - 'android_clang_asan_release_bot': [ 'android', 'clang', 'asan', 'release_bot', 'strip_debug_info', 'minimal_symbols', ], @@ -2016,16 +1992,6 @@ 'clang_tot', 'cfi_full', 'cfi_icall', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', ], - 'clang_tot_win_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on': [ - 'clang_tot', 'cfi_full', 'cfi_diag', 'thin_lto', 'release', 'static', - 'dcheck_always_on', 'win_linker_timing', - ], - - 'clang_tot_win_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_x86': [ - 'clang_tot', 'cfi_full', 'cfi_diag', 'thin_lto', 'release', 'static', - 'dcheck_always_on', 'x86', 'win_linker_timing', - ], - 'clang_tot_ubsan_no_recover_hack_static_release': [ 'clang_tot', 'ubsan_no_recover_hack', 'static', 'release', ], @@ -2226,10 +2192,18 @@ 'official_optimize_goma_trybot', 'fuchsia', ], + 'fuchsia_workstation_bot': [ + 'release_bot', 'fuchsia', 'fuchsia_include_workstation_image', + ], + 'gpu_fyi_tests_debug_trybot': [ 'gpu_fyi_tests', 'debug_bot', 'disable_nacl', ], + 'gpu_fyi_tests_debug_trybot_reclient': [ + 'gpu_fyi_tests', 'debug_bot_reclient', 'disable_nacl', + ], + 'gpu_fyi_tests_dx12vk_debug_trybot': [ 'gpu_fyi_tests', 'dx12vk', 'debug_bot', 'disable_nacl', ], @@ -2254,6 +2228,10 @@ 'gpu_fyi_tests', 'release_trybot_minimal_symbols', 'fuchsia', 'disable_nacl', ], + 'gpu_fyi_tests_release_trybot_reclient': [ + 'gpu_fyi_tests', 'release_trybot_minimal_symbols_reclient', 'disable_nacl', + ], + 'gpu_fyi_tests_release_trybot_tsan': [ 'gpu_fyi_tests', 'release_trybot_minimal_symbols', 'tsan', 'disable_nacl', ], @@ -2761,7 +2739,7 @@ ], 'official_goma_fuchsia_arm64_perf': [ - 'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_all_images', 'arm64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator' + 'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_sd_images', 'arm64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator' ], 'official_goma_linux_pgo': [ @@ -3045,10 +3023,6 @@ 'release_trybot_minimal_symbols_reclient', ], - 'release_trybot_minimal_symbols_reclient': [ - 'release_trybot_minimal_symbols_reclient', - ], - 'release_trybot_minimal_symbols_tsan': [ 'release_trybot_minimal_symbols', 'tsan' ], @@ -3367,7 +3341,7 @@ 'mixins': ['cronet_common'], 'gn_args': ('use_partition_alloc=false enable_reporting=true ' 'use_hashed_jni_names=true ' - 'default_min_sdk_version=16 ' + 'default_min_sdk_version=19 ' 'clang_use_default_sample_profile=false ' 'media_use_ffmpeg = false' 'use_thin_lto=false ' # https://crbug.com/1136963 @@ -3524,10 +3498,14 @@ 'gn_args': 'fuchsia_code_coverage=true', }, - 'fuchsia_include_all_images': { + 'fuchsia_include_sd_images': { 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images-internal/astro-release/","//third_party/fuchsia-sdk/images-internal/sherlock-release/"]', }, + 'fuchsia_include_workstation_image': { + 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images/qemu-x64-release/"]', + }, + 'full_symbols': { 'gn_args': 'symbol_level=2', }, @@ -3927,11 +3905,6 @@ 'blink_disable_generated_code_formatting'], }, - 'release_trybot_minimal_symbols_reclient': { - 'mixins': ['release_bot_reclient', 'minimal_symbols', 'dcheck_always_on', - 'blink_disable_generated_code_formatting'], - }, - 'resource_allowlisting': { 'gn_args': 'enable_resource_allowlist_generation=true', },
diff --git a/tools/mb/mb_config_expectations/chromium.android.json b/tools/mb/mb_config_expectations/chromium.android.json index 9e8e168..5b86ecb 100644 --- a/tools/mb/mb_config_expectations/chromium.android.json +++ b/tools/mb/mb_config_expectations/chromium.android.json
@@ -179,7 +179,7 @@ "gn_args": { "arm_use_neon": false, "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -208,7 +208,7 @@ "arm_use_neon": false, "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -236,7 +236,7 @@ "android-cronet-arm64-dbg": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -263,7 +263,7 @@ "gn_args": { "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -293,7 +293,7 @@ "arm_use_neon": false, "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -323,7 +323,7 @@ "gn_args": { "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -351,7 +351,7 @@ "android-cronet-x86-dbg": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -378,7 +378,7 @@ "gn_args": { "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true,
diff --git a/tools/mb/mb_config_expectations/chromium.clang.json b/tools/mb/mb_config_expectations/chromium.clang.json index 5b0fc913..1ba885c 100644 --- a/tools/mb/mb_config_expectations/chromium.clang.json +++ b/tools/mb/mb_config_expectations/chromium.clang.json
@@ -424,35 +424,6 @@ "use_libfuzzer": true } }, - "ToTWinCFI": { - "gn_args": { - "dcheck_always_on": true, - "is_cfi": true, - "is_clang": true, - "is_component_build": false, - "is_debug": false, - "llvm_force_head_revision": true, - "target_cpu": "x86", - "use_cfi_cast": true, - "use_cfi_diag": true, - "use_thin_lto": true, - "win_linker_timing": true - } - }, - "ToTWinCFI64": { - "gn_args": { - "dcheck_always_on": true, - "is_cfi": true, - "is_clang": true, - "is_component_build": false, - "is_debug": false, - "llvm_force_head_revision": true, - "use_cfi_cast": true, - "use_cfi_diag": true, - "use_thin_lto": true, - "win_linker_timing": true - } - }, "ToTWinOfficial": { "gn_args": { "is_chrome_branded": true,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 2f9fe80..2320959e 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -542,6 +542,18 @@ "use_goma": true } }, + "fuchsia-fyi-x64-wst": { + "gn_args": { + "dcheck_always_on": false, + "fuchsia_additional_boot_images": [ + "//third_party/fuchsia-sdk/images/qemu-x64-release/" + ], + "is_component_build": false, + "is_debug": false, + "target_os": "fuchsia", + "use_goma": true + } + }, "ios-asan": { "gn_args": { "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json index eaeda23b..c88bf19 100644 --- a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
@@ -14,129 +14,6 @@ "use_static_angle": true } }, - "Android FYI Release (NVIDIA Shield TV)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_cpu": "arm64", - "target_os": "android", - "use_goma": true, - "use_static_angle": true - } - }, - "Android FYI Release (Nexus 5)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI Release (Nexus 5X)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_cpu": "arm64", - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI Release (Nexus 9)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_cpu": "arm64", - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI Release (Pixel 2)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI Release (Pixel 4)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI SkiaRenderer GL (Nexus 5X)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_cpu": "arm64", - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, - "Android FYI SkiaRenderer Vulkan (Pixel 2)": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 1, - "target_os": "android", - "use_rbe": true, - "use_remoteexec": true, - "use_static_angle": true - } - }, "ChromeOS FYI Release (amd64-generic)": { "args_file": "//build/args/chromeos/amd64-generic-vm.gni", "gn_args": { @@ -167,6 +44,37 @@ "use_goma": true } }, + "GPU FYI Android arm Builder": { + "gn_args": { + "blink_enable_generated_code_formatting": false, + "dcheck_always_on": true, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "symbol_level": 1, + "target_os": "android", + "use_rbe": true, + "use_remoteexec": true, + "use_static_angle": true + } + }, + "GPU FYI Android arm64 Builder": { + "gn_args": { + "blink_enable_generated_code_formatting": false, + "dcheck_always_on": true, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "symbol_level": 1, + "target_cpu": "arm64", + "target_os": "android", + "use_rbe": true, + "use_remoteexec": true, + "use_static_angle": true + } + }, "GPU FYI Lacros x64 Builder": { "gn_args": { "blink_enable_generated_code_formatting": false, @@ -196,7 +104,8 @@ "is_gpu_fyi_bot": true, "proprietary_codecs": true, "symbol_level": 1, - "use_goma": true + "use_rbe": true, + "use_remoteexec": true } }, "GPU FYI Linux Builder (dbg)": { @@ -210,7 +119,8 @@ "is_gpu_fyi_bot": true, "proprietary_codecs": true, "symbol_level": 1, - "use_goma": true + "use_rbe": true, + "use_remoteexec": true } }, "GPU FYI Mac Builder": {
diff --git a/tools/mb/mb_config_expectations/infra.json b/tools/mb/mb_config_expectations/infra.json deleted file mode 100644 index 70eb3c2..0000000 --- a/tools/mb/mb_config_expectations/infra.json +++ /dev/null
@@ -1,18 +0,0 @@ -{ - "linux-bootstrap": { - "gn_args": { - "dcheck_always_on": false, - "is_component_build": false, - "is_debug": false, - "use_goma": true - } - }, - "win-bootstrap": { - "gn_args": { - "dcheck_always_on": false, - "is_component_build": false, - "is_debug": false, - "use_goma": true - } - } -} \ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json index 1eedbfab..add2398 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -99,7 +99,7 @@ "gn_args": { "arm_use_neon": false, "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -126,7 +126,7 @@ "android-cronet-arm64-dbg": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -153,7 +153,7 @@ "gn_args": { "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -183,7 +183,7 @@ "arm_use_neon": false, "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -214,7 +214,7 @@ "arm_use_neon": false, "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -244,7 +244,7 @@ "arm_use_neon": false, "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -274,7 +274,7 @@ "blink_enable_generated_code_formatting": false, "clang_use_default_sample_profile": false, "dcheck_always_on": true, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -302,7 +302,7 @@ "android-cronet-x86-dbg": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -328,7 +328,7 @@ "android-cronet-x86-dbg-10-tests": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -354,7 +354,7 @@ "android-cronet-x86-dbg-11-tests": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -380,7 +380,7 @@ "android-cronet-x86-dbg-oreo-tests": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -406,7 +406,7 @@ "android-cronet-x86-dbg-pie-tests": { "gn_args": { "clang_use_default_sample_profile": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -433,7 +433,7 @@ "gn_args": { "clang_use_default_sample_profile": false, "dcheck_always_on": false, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true, @@ -1063,21 +1063,6 @@ "use_thin_lto": true } }, - "android_clang_dbg_recipe": { - "gn_args": { - "disable_android_lint": true, - "ffmpeg_branding": "Chrome", - "is_asan": true, - "is_clang": true, - "is_component_build": true, - "is_debug": true, - "proprietary_codecs": true, - "symbol_level": 0, - "target_os": "android", - "use_errorprone_java_compiler": false, - "use_goma": true - } - }, "android_compile_dbg": { "gn_args": { "ffmpeg_branding": "Chrome", @@ -1132,7 +1117,7 @@ "blink_enable_generated_code_formatting": false, "clang_use_default_sample_profile": false, "dcheck_always_on": true, - "default_min_sdk_version": 16, + "default_min_sdk_version": 19, "disable_file_support": true, "enable_jdk_library_desugaring": false, "enable_reporting": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.win.json b/tools/mb/mb_config_expectations/tryserver.chromium.win.json index cfaa268..f5a90f8 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.win.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
@@ -284,21 +284,6 @@ "use_goma": true } }, - "win10_chromium_x64_20h2_fyi_rel_ng": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", - "dcheck_always_on": true, - "enable_resource_allowlist_generation": false, - "ffmpeg_branding": "Chrome", - "is_component_build": false, - "is_debug": false, - "proprietary_codecs": true, - "symbol_level": 0, - "use_clang_coverage": true, - "use_goma": true - } - }, "win10_chromium_x64_dbg_ng": { "gn_args": { "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/tryserver.infra.json b/tools/mb/mb_config_expectations/tryserver.infra.json deleted file mode 100644 index ab3155bb..0000000 --- a/tools/mb/mb_config_expectations/tryserver.infra.json +++ /dev/null
@@ -1,22 +0,0 @@ -{ - "linux-bootstrap": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "is_component_build": false, - "is_debug": false, - "symbol_level": 0, - "use_goma": true - } - }, - "win-bootstrap": { - "gn_args": { - "blink_enable_generated_code_formatting": false, - "dcheck_always_on": true, - "is_component_build": false, - "is_debug": false, - "symbol_level": 0, - "use_goma": true - } - } -} \ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5aa659b..32b5430 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4373,6 +4373,15 @@ <int value="7" label="Failed With Unknown Reason"/> </enum> +<enum name="ArcRightClickConversionResult"> + <summary> + Describes whether the right click was converted to long press or not + </summary> + <int value="0" label="DISABLED"/> + <int value="1" label="CONVERTED"/> + <int value="2" label="NOT_CONVERTED"/> +</enum> + <enum name="ArcSdkVersionUpgradeType"> <summary>Defines the types of ARC SDK version upgrade</summary> <int value="0" label="NO_UPGRADE"/> @@ -8684,6 +8693,13 @@ <int value="7" label="Not connectable"/> </enum> +<enum name="BluetoothConnectToServiceError"> + <int value="0" label="Unknown"/> + <int value="1" label="Failed to accept connection"/> + <int value="2" label="Invalid UUID"/> + <int value="3" label="Socket is not listening"/> +</enum> + <enum name="BluetoothDeviceConnectErrorCode"> <int value="0" label="Authorization Cancelled"/> <int value="1" label="Authorization Failed"/> @@ -8782,6 +8798,12 @@ <int value="8" label="Unknown or unhandler error"/> </enum> +<enum name="BluetoothSocketErrorReason"> + <int value="0" label="System Error"/> + <int value="1" label="IO Pending"/> + <int value="2" label="Disconnected"/> +</enum> + <enum name="BluetoothSocketServiceHash"> <obsolete> No longer used by active histograms in M73. @@ -21044,6 +21066,14 @@ <int value="1" label="New key accelerator is used"/> </enum> +<enum name="DeskModelAddOrUpdateEntryStatus"> + <int value="0" label="Successfully added or updated"/> + <int value="1" label="Generic error"/> + <int value="2" label="Invalid argument (e.g. wrong ID format)"/> + <int value="3" label="Exceeed maximum number of templates"/> + <int value="4" label="Desk template is too large"/> +</enum> + <enum name="DesksCreationRemovalSource"> <int value="0" label="Button pressed"/> <int value="1" label="Keyboard shortcut"/> @@ -28166,7 +28196,7 @@ <int value="927" label="ChromadToCloudMigrationEnabled"/> <int value="928" label="CopyPreventionSettings"/> <int value="929" label="ReportDeviceAudioStatusCheckingRateMs"/> - <int value="930" label="FullscreenNotificationUrlExemptList"/> + <int value="930" label="KeepFullscreenWithoutNotificationUrlAllowList"/> <int value="931" label="OnPrintEnterpriseConnector"/> <int value="932" label="UserAgentReduction"/> <int value="933" label="OriginAgentClusterDefaultEnabled"/> @@ -28175,6 +28205,7 @@ <int value="936" label="PhoneHubCameraRollAllowed"/> <int value="937" label="EcheAllowed"/> <int value="938" label="DeviceKeylockerForStorageEncryptEnabled"/> + <int value="939" label="ReportCRDSessions"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -31155,6 +31186,7 @@ <int value="1607" label="ACCESSIBILITY_PRIVATE_UPDATEDICTATIONBUBBLE"/> <int value="1608" label="TERMINALPRIVATE_GETOSINFO"/> <int value="1609" label="OS_TELEMETRY_GETMEMORYINFO"/> + <int value="1610" label="AUTOTESTPRIVATE_COULDALLOWCROSTINI"/> </enum> <enum name="ExtensionIconState"> @@ -36603,6 +36635,7 @@ <int value="4099" label="LayerXYWithCanvasTarget"/> <int value="4100" label="LayerXYWithFrameTarget"/> <int value="4101" label="LayerXYWithSVGTarget"/> + <int value="4102" label="HTMLObjectElementFallback"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -48215,6 +48248,21 @@ <int value="3" label="Only Lacros browser"/> </enum> +<enum name="LacrosLaunchModeAndSource"> + <int value="0" label="Default or user set, only Ash browser"/> + <int value="1" label="Default or user set, Ash and Lacros browser available"/> + <int value="2" label="Default or user set, Lacros browser is primary"/> + <int value="3" label="Default or user set, only Lacros browser"/> + <int value="4" label="User forced, only Ash browser"/> + <int value="5" label="User forced, Ash and Lacros browser available"/> + <int value="6" label="User forced, Lacros browser is primary"/> + <int value="7" label="User forced, only Lacros browser"/> + <int value="8" label="Policy forced, only Ash browser"/> + <int value="9" label="Policy forced, Ash and Lacros browser available"/> + <int value="10" label="Policy forced, Lacros browser is primary"/> + <int value="11" label="Policy forced, only Lacros browser"/> +</enum> + <enum name="LanguageDetectionModelState"> <int value="0" label="Unknown"/> <int value="1" label="Model File Invalid"/> @@ -49499,7 +49547,7 @@ <int value="0" label="Success"/> <int value="1" label="Rejected in JavaScript (deprecated)"/> <int value="2" label="Blocklisted"/> - <int value="3" label="Unable to invoke JavaScript (deprecated)"/> + <int value="3" label="Unable to invoke JavaScript"/> <int value="4" label="Web layer task timeout (deprecated)"/> <int value="5" label="Dispatched timeout (deprecated)"/> <int value="6" label="Selection empty"/> @@ -51156,6 +51204,8 @@ <int value="-1645071473" label="ChromeColors:disabled"/> <int value="-1644308778" label="WASAPIRawAudioCapture:disabled"/> <int value="-1643933608" label="SyncAutofillWalletOfferData:enabled"/> + <int value="-1643227464" + label="AutofillEnableUpdateVirtualCardEnrollment:disabled"/> <int value="-1641832607" label="DragToPinTabs:enabled"/> <int value="-1641656402" label="RTCDisallowPlanBOutsideDeprecationTrial:disabled"/> @@ -51351,6 +51401,7 @@ <int value="-1514611301" label="enable-data-reduction-proxy-bypass-warnings"/> <int value="-1512656386" label="disable-new-audio-rendering-mixing-strategy"/> <int value="-1512555526" label="PaintPreviewShowOnStartup:enabled"/> + <int value="-1511549741" label="verbose-logging-in-nacl"/> <int value="-1510844027" label="ScanAppStickySettings:enabled"/> <int value="-1510839574" label="disable-sync-synced-notifications"/> <int value="-1510524610" @@ -51679,6 +51730,8 @@ <int value="-1291963295" label="ComputePressure:disabled"/> <int value="-1290471006" label="EnableHistoryFaviconsGoogleServerQuery:enabled"/> + <int value="-1290446351" + label="ExperimentalAccessibilityDictationExtension:disabled"/> <int value="-1290053302" label="OfflinePagesInDownloadHomeOpenInCct:disabled"/> <int value="-1289678848" label="SystemDownloadManager:enabled"/> @@ -52948,6 +53001,8 @@ <int value="-351830087" label="AssistantConsentSimplifiedText:enabled"/> <int value="-351552989" label="disable-hosted-apps-in-windows"/> <int value="-351127770" label="enable-offline-pages-as-bookmarks"/> + <int value="-350336634" + label="ExperimentalAccessibilityDictationExtension:enabled"/> <int value="-349437334" label="UseDdljsonApi:disabled"/> <int value="-349380607" label="AndroidNightMode:disabled"/> <int value="-349057743" label="extensions-on-chrome-urls"/> @@ -53444,6 +53499,8 @@ <int value="10405060" label="BluetoothSessionizedMetrics:disabled"/> <int value="10458238" label="disable-print-preview-simplify"/> <int value="11698808" label="enable-dom-distiller-button-animation"/> + <int value="11924259" + label="AutofillEnableUpdateVirtualCardEnrollment:enabled"/> <int value="12016364" label="OmniboxBubbleUrlSuggestions:enabled"/> <int value="15614295" label="Portals:enabled"/> <int value="19629326" label="OmniboxExperimentalKeywordMode:enabled"/> @@ -92083,6 +92140,12 @@ <int value="6" label="Tabbed"/> </enum> +<enum name="WebAppIconsDownloadedResult"> + <int value="0" label="Completed"/> + <int value="1" label="PrimaryPageChanged"/> + <int value="2" label="AbortedDueToFailure"/> +</enum> + <enum name="WebAppInstallIphResult"> <int value="0" label="Installed"/> <int value="1" label="Clicked Install icon then canceled install"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index ecf1861..e8427d1b 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -528,6 +528,9 @@ <histogram name="Android.ChildProcessLauncher.OnServiceConnectedTimedOutResult" enum="OnServiceConnectedTimedOutResult" expires_after="2022-01-02"> + <obsolete> + Deprecated as of 01/2022 + </obsolete> <owner>boliu@chromium.org</owner> <owner>src/base/android/OWNERS</owner> <summary> @@ -4807,7 +4810,8 @@ Records the number of seconds any WebView was visible (the view itself was visible, and was attached to the view hierarchy of a visible window) with a particular URL scheme in the primary main frame. Updated with every Metrics - upload. + upload. Note that the seconds are logged as the count for the scheme enum + values. </summary> </histogram> @@ -4820,7 +4824,8 @@ Records the number of seconds each WebView was visible (the view itself was visible, and was attached to the view hierarchy of a visible window) with a particular URL scheme in the primary main frame. Updated with every Metrics - upload. + upload. Note that the seconds are logged as the count for the scheme enum + values. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index a12fe01..d0a2492 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -2279,7 +2279,7 @@ <histogram name="Apps.FileHandler.Registration.Linux.RecreateShortcut.Result" enum="FileHandlerRegistrationLinuxRecreateShortcutResult" - expires_after="M100"> + expires_after="M110"> <owner>estade@chromium.org</owner> <owner>desktop-pwas-team@google.com</owner> <summary> @@ -2289,7 +2289,7 @@ </histogram> <histogram name="Apps.FileHandler.Registration.Linux.Result" - enum="FileHandlerRegistrationLinuxResult" expires_after="M100"> + enum="FileHandlerRegistrationLinuxResult" expires_after="M110"> <owner>estade@chromium.org</owner> <owner>desktop-pwas-team@google.com</owner> <summary> @@ -2299,7 +2299,7 @@ </histogram> <histogram name="Apps.FileHandler.Registration.Win.Result" - enum="FileHandlerRegistrationWinResult" expires_after="M100"> + enum="FileHandlerRegistrationWinResult" expires_after="M110"> <owner>estade@chromium.org</owner> <owner>desktop-pwas-team@google.com</owner> <summary> @@ -2308,7 +2308,7 @@ </histogram> <histogram name="Apps.FileHandler.Unregistration.Linux.Result" - enum="FileHandlerRegistrationLinuxResult" expires_after="M100"> + enum="FileHandlerRegistrationLinuxResult" expires_after="M110"> <owner>estade@chromium.org</owner> <owner>desktop-pwas-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index 162d9a2..c8d57a5a 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -77,14 +77,14 @@ </variants> <histogram name="Arc.AbiMigration.BootTime" units="ms" - expires_after="2022-04-03"> + expires_after="2022-08-03"> <owner>vraheja@chromium.org</owner> <owner>arc-core@google.com</owner> <summary>Time taken for ARC to boot during an Abi Migration event.</summary> </histogram> <histogram name="Arc.AbiMigration.DowngradeDelay" units="ms" - expires_after="2022-04-03"> + expires_after="2022-08-03"> <owner>vraheja@chromium.org</owner> <owner>arc-core@google.com</owner> <summary> @@ -94,7 +94,7 @@ </histogram> <histogram name="Arc.AbiMigration.Event" enum="ArcCorePriAbiMigEvent" - expires_after="2022-04-24"> + expires_after="2022-08-24"> <owner>vraheja@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -103,7 +103,7 @@ </histogram> <histogram name="Arc.AbiMigration.FailedAttempts" units="units" - expires_after="2022-04-24"> + expires_after="2022-08-24"> <owner>vraheja@chromium.org</owner> <owner>arc-core@google.com</owner> <summary> @@ -278,7 +278,7 @@ </histogram> <histogram name="Arc.AppShortcutSearchResult.ShortcutStatus" - enum="ArcAppShortcutStatus" expires_after="2022-04-24"> + enum="ArcAppShortcutStatus" expires_after="2022-07-24"> <owner>batoon@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -289,7 +289,7 @@ </histogram> <histogram name="Arc.AppShortcutsRequest.ShortcutStatus" - enum="ArcAppShortcutStatus" expires_after="2022-04-24"> + enum="ArcAppShortcutStatus" expires_after="2022-07-24"> <owner>batoon@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -432,7 +432,7 @@ </histogram> <histogram name="Arc.Auth.MainAccountHashMigration.Status" - enum="ArcMainAccountHashMigrationStatus" expires_after="2022-05-01"> + enum="ArcMainAccountHashMigrationStatus" expires_after="2022-08-01"> <owner>vsomani@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -472,7 +472,7 @@ </histogram> <histogram name="Arc.Auth.RequestAccountInfoResult.Primary" - enum="ArcAuthCodeStatus" expires_after="2022-06-01"> + enum="ArcAuthCodeStatus" expires_after="2022-08-01"> <owner>anastasiian@google.com</owner> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> @@ -484,7 +484,7 @@ </histogram> <histogram name="Arc.Auth.RequestAccountInfoResult.Secondary" - enum="ArcAuthCodeStatus" expires_after="2022-06-01"> + enum="ArcAuthCodeStatus" expires_after="2022-08-01"> <owner>anastasiian@google.com</owner> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> @@ -635,6 +635,16 @@ </summary> </histogram> +<histogram name="Arc.CompatMode.RightClickConversion" + enum="ArcRightClickConversionResult" expires_after="2022-06-30"> + <owner>yhanada@google.com</owner> + <owner>arc-framework@google.com</owner> + <summary> + The number of times right click events on ARC++ apps are converted to + simulated long press. + </summary> +</histogram> + <histogram name="Arc.ComplianceReportSinceUpdateNotificationTime" units="ms" expires_after="M85"> <owner>alexchau@google.com</owner> @@ -1165,6 +1175,17 @@ </summary> </histogram> +<histogram name="Arc.NearbyShare.FileStreamComplete.TimeDelta" units="ms" + expires_after="2022-07-01"> + <owner>alanding@google.com</owner> + <owner>arc-app-dev@google.com</owner> + <summary> + Time taken by ARC Nearby Share to transfer file streams from ARC's virtual + file system in ContentProviders to Chrome's native file system. The time is + only recorded when file stream completes successfully. + </summary> +</histogram> + <histogram name="Arc.NearbyShare.FileStreamFailure" enum="PlatformFileError" expires_after="2022-03-23"> <owner>ttefera@google.com</owner> @@ -1258,7 +1279,7 @@ </histogram> <histogram name="Arc.OptInNetworkErrorAction" enum="ArcOptInNetworkErrorAction" - expires_after="2022-05-01"> + expires_after="2022-08-01"> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1474,7 +1495,7 @@ </histogram> <histogram name="Arc.Provisioning.CheckInError{ArcUserTypes}" - enum="ArcProvisioningCheckInError" expires_after="2022-05-01"> + enum="ArcProvisioningCheckInError" expires_after="2022-08-01"> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1491,7 +1512,7 @@ </histogram> <histogram name="Arc.Provisioning.CloudFlowError{ArcUserTypes}" - enum="ArcProvisioningCloudFlowError" expires_after="2022-05-01"> + enum="ArcProvisioningCloudFlowError" expires_after="2022-08-01"> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1529,7 +1550,7 @@ </histogram> <histogram name="Arc.Provisioning.SignInError{ArcUserTypes}" - enum="ArcProvisioningSignInError" expires_after="2022-05-01"> + enum="ArcProvisioningSignInError" expires_after="2022-08-01"> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1546,7 +1567,7 @@ </histogram> <histogram name="Arc.Provisioning.Status{ArcUserTypes}" - enum="ArcProvisioningStatus" expires_after="2022-05-01"> + enum="ArcProvisioningStatus" expires_after="2022-08-01"> <owner>mhasank@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1562,7 +1583,7 @@ </histogram> <histogram name="Arc.Provisioning.TimeDelta.Failure{ArcUserTypes}" units="ms" - expires_after="2022-01-09"> + expires_after="2022-08-09"> <owner>alexchau@google.com</owner> <owner>phweiss@google.com</owner> <summary> @@ -1575,7 +1596,7 @@ </histogram> <histogram name="Arc.Provisioning.TimeDelta.Success{ArcUserTypes}" units="ms" - expires_after="2022-01-09"> + expires_after="2022-08-09"> <owner>alexchau@google.com</owner> <owner>phweiss@google.com</owner> <summary> @@ -1588,7 +1609,7 @@ </histogram> <histogram name="Arc.Reauthorization.Result{ArcUserTypes}" - enum="ArcProvisioningStatus" expires_after="2022-07-04"> + enum="ArcProvisioningStatus" expires_after="2022-08-04"> <owner>mhasank@google.com</owner> <owner>arc-core@gmail.com</owner> <summary> @@ -1835,7 +1856,7 @@ </histogram> <histogram name="Arc.Supervision.Transition.Result" - enum="ArcSupervisionTransitionResult" expires_after="2022-04-03"> + enum="ArcSupervisionTransitionResult" expires_after="2022-08-03"> <owner>giovax@chromium.org</owner> <owner>arc-commercial@google.com</owner> <summary> @@ -1845,7 +1866,7 @@ </histogram> <histogram name="Arc.Supervision.Transition.Screen.Success.TimeDelta" - units="ms" expires_after="2022-05-01"> + units="ms" expires_after="2022-08-01"> <owner>mhasank@chromium.org</owner> <owner>arc-commercial@google.com</owner> <summary> @@ -1855,7 +1876,7 @@ </histogram> <histogram name="Arc.Supervision.Transition.Screen.Successful" - enum="BooleanSuccess" expires_after="2022-05-01"> + enum="BooleanSuccess" expires_after="2022-08-01"> <owner>mhasank@chromium.org</owner> <owner>arc-commercial@google.com</owner> <summary> @@ -1864,7 +1885,7 @@ </histogram> <histogram name="Arc.SystemHealth.Upgrade.PackagesDeleted" - enum="BooleanDeletedOrNot" expires_after="2022-06-10"> + enum="BooleanDeletedOrNot" expires_after="2022-08-10"> <owner>mhasank@chromium.org</owner> <owner>arc-core@google.com</owner> <summary> @@ -1873,7 +1894,7 @@ </histogram> <histogram name="Arc.SystemHealth.Upgrade.TimeDelta" units="ms" - expires_after="2022-06-10"> + expires_after="2022-08-10"> <owner>mhasank@chromium.org</owner> <owner>arc-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 4ecf094c..dbbaebd 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -633,18 +633,19 @@ </histogram> <histogram name="Ash.Clipboard.ConsecutiveCopies" units="times" - expires_after="2021-09-01"> - <owner>newcomer@chromium.org</owner> + expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The number of consecutive copies in the user session, recorded when a paste - occurs. + occurs. Warning: This histogram was expired from 2021-09-01 to 2022-01-05; + data may be missing. </summary> </histogram> <histogram name="Ash.Clipboard.ConsecutivePastes" units="times" - expires_after="2022-04-10"> - <owner>newcomer@chromium.org</owner> + expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The number of consecutive pastes in the user session, recorded when a copy @@ -653,21 +654,22 @@ </histogram> <histogram name="Ash.ClipboardHistory.ConsecutivePastes" units="times" - expires_after="2022-01-02"> - <owner>andrewxu@chromium.org</owner> + expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The number of consecutive pastes from the clipboard history menu. The count is reset after a copy or a paste that is not through the clipboard history menu (such as pressing ctrl-v accelerator or clicking at a context menu - option). + option). Warning: This histogram was expired from 2022-01-02 to 2022-01-05; + data may be missing. </summary> </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatDeleted" - enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The format of the ClipboardHistoryItemView that was deleted from the Clipboard History menu. Logged on ClipboardHistoryItemView::ButtonPressed(). @@ -675,9 +677,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatPasted" - enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The format of the ClipboardHistoryItemView that was pasted from the Clipboard History menu. Logged on ClipboardHistoryItemView::ButtonPressed(). @@ -685,9 +687,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatShown" - enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + enum="ClipboardHistoryDisplayFormat" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The format of the view used to display clipboard data. Logged when the view is created. @@ -695,9 +697,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.MenuOptionSelected" - units="index" expires_after="2022-04-03"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + units="index" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The command ID index within the Clipboard History contextual menu that was selected by the user. Recorded when the menu item is selected. @@ -705,9 +707,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.NumberOfItemsShown" - units="Items Shown" expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + units="Items Shown" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of clipboard history items shown in the clipboard history contextual menu. Recorded when the clipboard history contextual menu model @@ -716,8 +718,8 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.ShowMenu" - enum="ClipboardHistoryTriggerType" expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> + enum="ClipboardHistoryTriggerType" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> It records how many times users trigger the clipboard history menu through @@ -726,8 +728,8 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.ShowPlaceholderString" - enum="ClipboardHistoryPlaceholderStringType" expires_after="2022-04-10"> - <owner>newcomer@chromium.org</owner> + enum="ClipboardHistoryPlaceholderStringType" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The number of placeholder strings shown to users in lieu of actual data, @@ -737,9 +739,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ContextMenu.UserJourneyTime" units="ms" - expires_after="2022-04-10"> - <owner>andrewxu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The length of the user journey of the context menu version of clipboard history. Measured as time from starting to construct the menu, to time of @@ -755,8 +757,8 @@ recreated as to some metrics may not be logging correctly. Replaced by Ash.ClipboardHistory.Nudges.OnboardingNudge.ToFeatureOpenTime. </obsolete> - <owner>yulunwu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of seconds between the user being shown the clipboard history contextual nudge and the opening the clipboard history menu. The sum over @@ -772,8 +774,8 @@ recreated as to some metrics may not be logging correctly. Replaced by Ash.ClipboardHistory.Nudges.OnboardingNudge.ToFeaturePasteTime. </obsolete> - <owner>yulunwu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of seconds between the user being shown the clipboard history contextual nudge and the user pasting with the clipboard history feature. @@ -788,8 +790,8 @@ Replaced 04/2021 by Ash.ClipboardHistory.Nudges.OnboardingNudge.ShownCount as of http://crrev.com/2761780. </obsolete> - <owner>yulunwu@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of times the clipboard history contextual nudge has been shown. This number will be used as the baseline against the sum of the @@ -798,9 +800,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.ControlToVDelay" units="ms" - expires_after="2022-04-10"> - <owner>gzadina@google.com</owner> - <owner>newcomer@chromium.org</owner> + expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The time between a user pressing control and V when pasting via keyboard. Recorded in AcceleratorHistory when a V is pressed. Only recorded for the @@ -814,7 +816,7 @@ <histogram name="Ash.ClipboardHistory.ImageModelRequest.Lifetime" units="ms" expires_after="2022-04-24"> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The lifetime of the ClipboardImageModelRequest object. Logged in the dtor of @@ -824,7 +826,7 @@ <histogram name="Ash.ClipboardHistory.ImageModelRequest.Runtime" units="ms" expires_after="2022-04-24"> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The runtime of a request in a ClipboardImageModelRequest. Logged from when @@ -834,7 +836,7 @@ <histogram name="Ash.ClipboardHistory.ImageModelRequest.StopReason" enum="RequestStopReason" expires_after="2022-04-24"> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> The reason a ClipboardImageModelRequest is stopped. Logged when a request is @@ -843,9 +845,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.Nudges.{NudgeType}.ShownCount" - enum="BooleanHit" expires_after="2022-04-01"> - <owner>anasalazar@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + enum="BooleanHit" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of times the clipboard history {NudgeType} has been shown. This number will be used as the baseline against the number of emits of the @@ -861,9 +863,9 @@ </histogram> <histogram name="Ash.ClipboardHistory.Nudges.{NudgeType}.ToFeature{Action}Time" - units="seconds" expires_after="2022-04-01"> - <owner>anasalazar@chromium.org</owner> - <owner>multipaste@chromium.org</owner> + units="seconds" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of seconds between the user being shown the clipboard history {NudgeType} and {Action}. The number of emits to this histogram will also be @@ -884,14 +886,15 @@ </histogram> <histogram name="Ash.ClipboardHistory.Operation" - enum="ClipboardHistoryOperation" expires_after="2022-01-02"> - <owner>newcomer@chromium.org</owner> + enum="ClipboardHistoryOperation" expires_after="2022-04-24"> + <owner>ckincaid@chromium.org</owner> <owner>multipaste@google.com</owner> <summary> Different operations detected by ClipboardHistory. Debounced, so different than Clipboard.Read, Clipboard.Write. Any clipboard copy detected here will result in a new entry in ClipboardHistory. Recorded after a clipboard read - or write is debounced in ClipboardHistory. + or write is debounced in ClipboardHistory. Warning: This histogram was + expired from 2022-01-02 to 2022-01-05; data may be missing. </summary> </histogram> @@ -901,8 +904,8 @@ Replaced 04/2021 by Ash.ClipboardHistory.Nudges.ZeroStateNudge.ShownCount as of http://crrev.com/2761780. </obsolete> - <owner>anasalazar@chromium.org</owner> - <owner>newcomer@chromium.org</owner> + <owner>ckincaid@chromium.org</owner> + <owner>multipaste@google.com</owner> <summary> The number of times the clipboard history zero state contextual nudge has been shown. This number will be used as the baseline against the sum of the @@ -1276,6 +1279,17 @@ </summary> </histogram> +<histogram name="Ash.DeskTemplate.AddOrUpdateTemplateStatus" + enum="DeskModelAddOrUpdateEntryStatus" expires_after="2022-11-11"> + <owner>yzd@google.com</owner> + <owner>janetmac@chromium.com</owner> + <summary> + Emitted when a desk template is added or updated to indicate result of this + operation. i.e. whether this operation is successful or failed with any + particular reason. + </summary> +</histogram> + <histogram name="Ash.DeskTemplate.DeleteTemplate" enum="BooleanHit" expires_after="2022-11-11"> <owner>avynn@google.com</owner> @@ -1714,6 +1728,20 @@ </summary> </histogram> +<histogram name="Ash.Lacros.Launch.ModeAndSource" + enum="LacrosLaunchModeAndSource" expires_after="2022-12-01"> + <owner>skuhne@chromium.org</owner> + <owner>lacros-team@google.com</owner> + <summary> + The Lacros operation mode and the origin of the setting. This will record if + Ash is the only browser, both browsers are running side by side or if Lacros + is the only browser as well as if the setting was set by the user, enforced + by a policy or enforced by the user (overriding any given policy). It will + be emitted shortly before Lacros gets started the first time from the system + (Ash). + </summary> +</histogram> + <histogram name="Ash.Login.Lock.AuthMethod.Switched" enum="AuthMethodSwitchType" expires_after="2022-06-29"> <owner>rsorokin@chromium.org</owner> @@ -2966,6 +2994,11 @@ <histogram name="Ash.Smoothness.MaxPercentDroppedFrames_1sWindow" units="%" expires_after="2022-09-30"> + <obsolete> + Deprecated 12/2021 as of http://crrev.com/c/3345730 becaue we are interested + in dropped frame of current sliding window instead of max and would only + track the uniform version. + </obsolete> <owner>xiyuan@chromium.org</owner> <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> @@ -2982,6 +3015,11 @@ <histogram name="Ash.Smoothness.MaxPercentDroppedFrames_1sWindow.Uniform" units="%" expires_after="2022-09-30"> + <obsolete> + Replaced 12/2021 by Ash.Smoothness.PercentDroppedFrames_1sWindow as of + http://crrev.com/c/3345730 becaue we are interested in dropped frame of + current sliding window instead of max. + </obsolete> <owner>xiyuan@chromium.org</owner> <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> @@ -2991,6 +3029,20 @@ </summary> </histogram> +<histogram name="Ash.Smoothness.PercentDroppedFrames_1sWindow" units="%" + expires_after="2022-12-15"> + <owner>xiyuan@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> + <summary> + Tracks the percent of dropped frames in a 1 second sliding window. + + PercentDroppedFrames is measured by tracking the number of frames which were + not displayed on screen out of the total number of frames expected to be + produced and displayed. In other words, the lower this number is, the + smoother experience. + </summary> +</histogram> + <histogram name="Ash.SplitView.DeviceOrientation.{DeviceUIMode}" enum="DeviceOrientation" expires_after="2022-08-11"> <owner>cattalyya@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bluetooth/OWNERS b/tools/metrics/histograms/metadata/bluetooth/OWNERS index 141539e..9542e147 100644 --- a/tools/metrics/histograms/metadata/bluetooth/OWNERS +++ b/tools/metrics/histograms/metadata/bluetooth/OWNERS
@@ -3,4 +3,5 @@ # Prefer sending CLs to the owners listed below. # Use chromium-metrics-reviews@google.com as a backup. khorimoto@chromium.org -reillyg@chromium.org \ No newline at end of file +nohle@chromium.org +reillyg@chromium.org
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml index 90e1090..78ebb77 100644 --- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml +++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -189,8 +189,94 @@ </histogram> <histogram + name="Bluetooth.ChromeOS.FastPair.AccountKey.Failure.{FastPairPairingProtocol}" + enum="FastPairAccountKeyFailure" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Breaks down why a account key write attempt to a device failed (see + 'Bluetooth.ChromeOS.FastPair.AccountKey.Result'). Suffixed by FastPair + pairing protocol type. Emitted on the OnWriteAccountKey event in the Fast + Pair flow. + </summary> + <token key="FastPairPairingProtocol"> + <variant name="InitialPairingProtocol" summary="initial pairing protocol"/> + <variant name="RetroactivePairingProtocol" + summary="retroactive pairing protocol"/> + </token> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.AccountKey.Write.GattErrorReason" + enum="BluetoothDeviceConnectErrorCode" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Breaks down why a written attempt to the account-key Gatt characteristic of + a device failed if it was a result of a Gatt error. Emitted following a + OnWriteRequest error in the FastPairGattServiceClient. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result" + enum="BooleanSuccess" expires_after="2022-06-20"> + <obsolete> + Removed 2022/01/06 to add dimmensions for different pairing scenarios. See + `Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result.{FastPairPairingProtocol}` + </obsolete> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records success or failure of writing to the account-key Gatt characteristic + of the device during the pairing protocol. Emitted following the write + account key request in the FastPairPairer. + </summary> +</histogram> + +<histogram + name="Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result.{FastPairPairingProtocol}" + enum="BooleanSuccess" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records success or failure of writing an account key to a device. Emitted on + the OnPairFailure event and the OnDevicePaired event in the Fast Pair flow. + </summary> + <token key="FastPairPairingProtocol"> + <variant name="InitialPairingProtocol" summary="initial pairing protocol"/> + <variant name="RetroactivePairingProtocol" + summary="retroactive pairing protocol"/> + <variant name="SubsequentPairingProtocol" + summary="subsequent pairing protocol"/> + </token> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.AccountKey.Write.TotalTime" + units="ms" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total time it takes to write the account key gatt characteristic + of a device. Time is calculated as the difference between when the write to + characteristic occurs and when the OnAccountKeyWrite event is fired in the + GattServiceClient during the pairing protocol. Emitted when the + OnAccountKeyWrite event fires. If the account key write fails, then no value + is logged to this metric. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.AccountKeyFailure.{FastPairPairingProtocol}" enum="FastPairAccountKeyFailure" expires_after="2022-09-20"> + <obsolete> + Renamed to + 'Bluetooth.ChromeOS.FastPair.AccountKey.Failure.{FastPairPairingProtocol}' + for consistency among metrics related to AccountKey. Removed 2022/01/05. + </obsolete> <owner>shanefitz@google.com</owner> <owner>julietlevesque@google.com</owner> <owner>chromeos-cross-device-eng@google.com</owner> @@ -210,6 +296,11 @@ <histogram name="Bluetooth.ChromeOS.FastPair.AccountKeyWrite.Result.{FastPairPairingProtocol}" enum="BooleanSuccess" expires_after="2022-09-20"> + <obsolete> + Renamed to + 'Bluetooth.ChromeOS.FastPair.AccountKey.Write.Result.{FastPairPairingProtocol}' + for consistency among metrics related to AccountKey. Removed 2022/01/05. + </obsolete> <owner>shanefitz@google.com</owner> <owner>julietlevesque@google.com</owner> <owner>chromeos-cross-device-eng@google.com</owner> @@ -226,6 +317,17 @@ </token> </histogram> +<histogram name="Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Result" + enum="BooleanSuccess" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the success or failure of fetching device metadata from the + repository. This metric is emitted when the metadata is fetched. + </summary> +</histogram> + <histogram name="Bluetooth.ChromeOS.FastPair.EngagementFunnel.Steps.{FastPairPairingProtocol}" enum="FastPairEngagementFlowEvent" expires_after="2022-09-20"> @@ -261,6 +363,26 @@ </summary> </histogram> +<histogram name="Bluetooth.ChromeOS.FastPair.FastPairDataEncryptor.CreateTime" + units="ms" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total time it takes for a successful async creation of a + FastPairDataEncryptor (see + 'Bluetooth.ChromeOS.FastPair.FastPairDataEncryptor.CreateResult'). The time + is calculated as the difference between the start of the call to create the + data encryptor, and when the callback is invoked. If the creation is + unsuccessful, then no value is logged to this metric. Emitted in the + FastPairHandshake on the OnDataEncryptorCreateAsync callback call. This + metric helps us understand how much time in the flow is being sunk into the + creation of the data encryptor, who's construction is responsible for + creating the secret key using ECDH (see + 'Bluetooth.ChromeOS.FastPair.KeyGenerationResult'). + </summary> +</histogram> + <histogram name="Bluetooth.ChromeOS.FastPair.GattConnection.ErrorReason" enum="BluetoothDeviceConnectErrorCode" expires_after="2022-09-20"> <owner>shanefitz@google.com</owner> @@ -375,6 +497,72 @@ </histogram> <histogram + name="Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.ErrorReason" + enum="BluetoothSocketErrorReason" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the error reason that caused the failure of creating a RFCOMM + channel (creating the MessageStream). This metric is emitted after the + channel is failed to be created in the MessageStreamLookup in the + OnConnectError callback. + </summary> +</histogram> + +<histogram + name="Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.Result" + enum="BooleanSuccess" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the success or failure of attempted to create an RFCOMM channel to + the device (creating the MessageStream). The metric is emitted in the + success/failure callbacks. + </summary> +</histogram> + +<histogram + name="Bluetooth.ChromeOS.FastPair.MessageStream.ConnectToService.TotalConnectTime" + units="ms" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total time it takes to create a successful RFCOMM channel + connection to the device. This metric is emitted after the channel is + successfully created, and it is not emitted on failure. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.MessageStream.Receive.ErrorReason" + enum="BluetoothConnectToServiceError" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the error reason that caused the failure of receiving data from a + socket in the Fast Pair MessageStream opened to the device. This metric is + emitted following an error to receive data from a socket, and no metric is + emitted on success. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.MessageStream.Receive.Result" + enum="BooleanSuccess" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the success or failure of receiving data from a socket in the Fast + Pair MessageStream opened to the device. This metric is emitted after the + socket is attempted to be receive to in the MessageStream, either + ReceiveDataSuccess or ReceiveDataError callbacks. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.PairFailure.{FastPairPairingProtocol}" enum="FastPairPairFailure" expires_after="2022-09-20"> <owner>shanefitz@google.com</owner> @@ -430,6 +618,80 @@ </summary> </histogram> +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Result" + enum="BooleanSuccess" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the success or failure of decrypting the response from the passkey + characteristic. Emitted in the pairing protocol flow after the response + bytes have been attempted to be decrypted. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Time" units="ms" + expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total time it takes to decrypt a successful response from the + passkey characteristic. Emitted in the pairing protocol flow after the + response bytes have been successfully decrypted. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.NotifyTime" units="ms" + expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total time it takes to be notified of the Passkey Gatt + characteristic of the device changing during the pairing protocol. The time + is calculated as the difference between when the WritePasskey is sent to the + device, and when we are notified of a response. If the write passkey attempt + fails or takes longer than 5 seconds, no value is logged to this metric. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Write.GattErrorReason" + enum="GattErrorCode" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Breaks down why a written attempt to the Passkey Gatt characteristic of a + device failed if it was a result of a Gatt error. Emitted following a + OnPasskeyRequest error in the FastPairGattServiceClient. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Write.PairFailure" + enum="FastPairPairFailure" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Breaks down why a written attempt to the Passkey Gatt characteristic of a + device failed (see 'Bluetooth.ChromeOS.FastPair.Passkey.Result'). Emitted on + the OnWritePasskey event in the FastPairPairer. + </summary> +</histogram> + +<histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Write.Result" + enum="BooleanSuccess" expires_after="2022-06-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records success or failure of writing to the Passkey Gatt characteristic of + the device during the pairing protocol. Emitted following the passkey + request in the FastPairPairer. + </summary> +</histogram> + <histogram name="Bluetooth.ChromeOS.FastPair.RetroactiveEngagementFunnel.Steps" enum="FastPairRetroactiveEngagementFlowEvent" expires_after="2022-09-20"> <owner>shanefitz@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos/OWNERS b/tools/metrics/histograms/metadata/chromeos/OWNERS index 65dc988..08dc06a4 100644 --- a/tools/metrics/histograms/metadata/chromeos/OWNERS +++ b/tools/metrics/histograms/metadata/chromeos/OWNERS
@@ -4,5 +4,6 @@ # Use chromium-metrics-reviews@google.com as a backup. jorgelo@chromium.org khorimoto@chromium.org +nohle@chromium.org tsergeant@chromium.org zentaro@chromium.org
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml index ce3a5ba..4646d4f 100644 --- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml +++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -580,6 +580,11 @@ <histogram name="Cryptohome.TimeToPerformOOPMountCleanup" units="ms" expires_after="2022-01-02"> + <obsolete> + All mounts are now performed out-of-process, so this histogram is not needed + anymore, as there is nothing to compare this number to. Obsolete as of + 2022-01-06. + </obsolete> <owner>jorgelo@chromium.org</owner> <owner>betuls@chromium.org</owner> <summary> @@ -590,7 +595,12 @@ </histogram> <histogram name="Cryptohome.TimeToPerformOOPMountOperation" units="ms" - expires_after="2022-05-01"> + expires_after="2022-01-06"> + <obsolete> + All mounts are now performed out-of-process, so this histogram is not needed + anymore, as there is nothing to compare this number to. Obsolete as of + 2022-01-06. + </obsolete> <owner>jorgelo@chromium.org</owner> <owner>betuls@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml index 92a064e..2eead81 100644 --- a/tools/metrics/histograms/metadata/enterprise/histograms.xml +++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -868,6 +868,24 @@ </token> </histogram> +<histogram name="Enterprise.DeviceTrust.RotateSigningKey.{Nonce}.UploadCode" + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2022-07-01"> + <owner>hmare@google.com</owner> + <owner>rogerta@chromium.org</owner> + <owner>seblalancette@chromium.org</owner> + <summary> + HTTP status code of the key upload request recorded when a device attempts + to rotate its device trust signing key. {Nonce} + </summary> + <token key="Nonce"> + <variant name="NoNonce" + summary="This occurs right after the device is enrolled with CBCM."/> + <variant name="WithNonce" + summary="This occurs when a device receives a command from the admin + console."/> + </token> +</histogram> + <histogram name="Enterprise.DeviceTrust.SignalsDecorator.Latency.{Variant}" units="ms" expires_after="2022-07-01"> <owner>hmare@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index f886d8189..36313687 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -3818,6 +3818,16 @@ </summary> </histogram> +<histogram name="Extensions.UninstallBookmarkApp" enum="Boolean" + expires_after="2022-12-01"> + <owner>phillis@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + Tracks whether bookmark app uninstalling succeeded or not. This is emitted + whenever a bookmark app (which is deprecated) gets uninstalled. + </summary> +</histogram> + <histogram name="Extensions.UninstallDialogAction" enum="ExtensionUninstallDialogAction" expires_after="2021-12-01"> <obsolete> @@ -4247,7 +4257,7 @@ The amount of time between starting the provisional load and having completed the onload handler in the main frame of the chrome://extensions page. This corresponds to the - WebContentsObserver::DocumentOnLoadCompletedInMainFrame method. + WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame method. {ExtensionWebUiPageType} </summary> <token key="ExtensionWebUiPageType" variants="ExtensionWebUiPageType">
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index 155c6447..4d065cd 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -261,7 +261,7 @@ </histogram> <histogram name="GPU.ANGLE.D3D11CreateDeviceError" enum="Hresult" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -273,7 +273,7 @@ </histogram> <histogram name="GPU.ANGLE.D3D11FeatureLevel" enum="D3DFeatureLevel" - expires_after="2022-06-26"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -287,7 +287,7 @@ </histogram> <histogram name="GPU.ANGLE.D3D11InitializeResult" enum="D3D11InitializeResult" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -298,7 +298,7 @@ </histogram> <histogram name="GPU.ANGLE.D3D9InitializeResult" enum="D3D9InitializeResult" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -308,7 +308,7 @@ </summary> </histogram> -<histogram name="GPU.ANGLE.D3DCompileMS" units="ms" expires_after="2022-06-19"> +<histogram name="GPU.ANGLE.D3DCompileMS" units="ms" expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -319,7 +319,7 @@ </histogram> <histogram name="GPU.ANGLE.DisplayInitializeMS" units="ms" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -366,7 +366,7 @@ </histogram> <histogram name="GPU.ANGLE.ProgramCache.LoadBinarySuccess" - enum="BooleanSuccess" expires_after="2022-01-02"> + enum="BooleanSuccess" expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -377,7 +377,7 @@ </histogram> <histogram name="GPU.ANGLE.ProgramCache.ProgramBinarySizeBytes" units="bytes" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -387,7 +387,7 @@ </histogram> <histogram name="GPU.ANGLE.SupportsDXGI1_2" enum="BooleanSupported" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -599,7 +599,7 @@ </histogram> <histogram name="GPU.D3DShaderModel" enum="ShaderModel" - expires_after="2022-06-12"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -920,7 +920,7 @@ </summary> </histogram> -<histogram name="GPU.DoLinkProgramTime" units="ms" expires_after="2022-01-02"> +<histogram name="GPU.DoLinkProgramTime" units="ms" expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -1210,7 +1210,7 @@ </histogram> <histogram name="GPU.InitializeOneOffMediumTime" units="ms" - expires_after="2022-07-03"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -1292,6 +1292,10 @@ <histogram name="Gpu.Metal.ReadWriteTextureSupport" enum="MetalReadWriteTextureSupportTier" expires_after="2022-05-31"> + <obsolete> + Code producing this histogram has been reverted while we investigate + crashes. Since 2022-01-06. + </obsolete> <owner>cwallez@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> @@ -1430,7 +1434,7 @@ </histogram> <histogram name="GPU.PassthroughDoLinkProgramTime" units="ms" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary> @@ -1526,7 +1530,7 @@ </histogram> <histogram name="GPU.ProgramCache.CacheHit" enum="BooleanSuccess" - expires_after="2022-01-02"> + expires_after="2022-06-01"> <owner>jonahr@google.com</owner> <owner>angle-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index da0b1ac..0eaf060f 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -2225,11 +2225,14 @@ <affected-histogram name="CloudPrint.UrlFetcherUploadSize"/> </histogram_suffixes> +<!-- TODO(https://crbug.com/1275800): convert this to patterned histograms --> + <histogram_suffixes name="ComponentUpdater.AndroidComponentLoader.ComponentName" separator="."> <owner>hazems@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <owner>src/components/component_updater/android/OWNERS</owner> + <suffix name="ClientSidePhishing" label=""/> <suffix name="OriginTrials" label=""/> <suffix name="TrustTokenKeyCommitments" label=""/> <suffix name="WebViewAppsPackageNamesAllowlist" label=""/> @@ -13429,6 +13432,10 @@ <suffix name="Malloc.BRPQuarantinedCount" label="Number of slots quarantined by BRP, recorded when USE_BACKUP_REF_PTR build flag is enabled."/> + <suffix name="Malloc.SyscallsPerMinute" + label="Number of system calls made per minute, averaged during the last + memory dump interval. Only collected when PartitionAlloc is + malloc()."/> <suffix name="NumberOfAdSubframes" label=""/> <suffix name="NumberOfArrayBufferContents" label=""/> <suffix name="NumberOfAudioHandler" label=""/>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index d1898a9..65ce1df 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3534,7 +3534,7 @@ </histogram> <histogram name="Media.Notification.Cast.ArtworkPresent" enum="Boolean" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <owner>media-dev@chromium.org</owner> @@ -3546,7 +3546,7 @@ </histogram> <histogram name="Media.Notification.Cast.Count" units="count" - expires_after="2022-06-26"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <owner>media-dev@chromium.org</owner> @@ -3557,7 +3557,7 @@ </histogram> <histogram name="Media.Notification.Cast.MetadataPresent" - enum="MediaNotificationMetadata" expires_after="2022-02-01"> + enum="MediaNotificationMetadata" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <owner>media-dev@chromium.org</owner> @@ -3571,7 +3571,7 @@ <histogram name="Media.Notification.Cast.StartStop" enum="GlobalMediaControlsCastActionAndEntryPoint" - expires_after="2022-06-05"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <owner>media-dev@chromium.org</owner> @@ -3582,7 +3582,7 @@ </histogram> <histogram name="Media.Notification.Cast.UserAction" enum="MediaSessionAction" - expires_after="2022-06-19"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <owner>media-dev@chromium.org</owner> @@ -6091,7 +6091,7 @@ </histogram> <histogram name="MediaRouter.Route.CreationOutcome" - enum="MediaRouterCreateRouteOutcome" expires_after="2022-02-01"> + enum="MediaRouterCreateRouteOutcome" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6101,7 +6101,7 @@ </histogram> <histogram name="MediaRouter.Sink.SelectedType" enum="MediaSinkType" - expires_after="2022-06-12"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6112,7 +6112,7 @@ </histogram> <histogram name="MediaRouter.Sink.SelectedType.CastAndDialPresent.{Ui}" - enum="MediaSinkType" expires_after="2022-02-01"> + enum="MediaSinkType" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6127,7 +6127,7 @@ </histogram> <histogram name="MediaRouter.Sink.SelectedType.{Ui}" enum="MediaSinkType" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6141,7 +6141,7 @@ </histogram> <histogram name="MediaRouter.Source.CastingSource" - enum="MediaRouterSourceTypes" expires_after="2022-06-05"> + enum="MediaRouterSourceTypes" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6152,6 +6152,9 @@ <histogram name="MediaRouter.Source.LocalFileFormat" enum="MediaContainers" expires_after="2022-02-01"> + <obsolete> + Unused after 2022-01. + </obsolete> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6163,6 +6166,9 @@ <histogram name="MediaRouter.Source.LocalFileSize" units="MB" expires_after="2022-02-01"> + <obsolete> + Unused after 2022-01. + </obsolete> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6174,7 +6180,7 @@ </histogram> <histogram name="MediaRouter.Ui.Action.CloseLatency" units="ms" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6185,7 +6191,7 @@ </histogram> <histogram name="MediaRouter.Ui.Action.StartLocal.Latency" units="ms" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6196,14 +6202,14 @@ </histogram> <histogram name="MediaRouter.Ui.Action.StartLocalPosition" - enum="MediaRouterSinkPositionLabel" expires_after="2022-06-26"> + enum="MediaRouterSinkPositionLabel" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary>The index of the sink that was selected in the sink list.</summary> </histogram> <histogram name="MediaRouter.Ui.Action.StartLocalSessionSuccessful" - enum="BooleanSuccess" expires_after="2022-02-01"> + enum="BooleanSuccess" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6212,14 +6218,14 @@ </histogram> <histogram name="MediaRouter.Ui.Action.StopRoute" enum="MediaRouteType" - expires_after="2022-06-12"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary>The number of times a user stops different types of routes.</summary> </histogram> <histogram name="MediaRouter.Ui.Device.Count" units="units" - expires_after="2022-06-12"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6231,7 +6237,7 @@ </histogram> <histogram name="MediaRouter.Ui.Device.Count.{Ui}.{Trigger}.{Mrp}.{State}" - units="units" expires_after="2022-02-01"> + units="units" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6260,7 +6266,7 @@ <histogram name="MediaRouter.Ui.Dialog.ActivationLocationAndCastMode" enum="MediaRouterDialogActivationLocationAndCastMode" - expires_after="2022-06-05"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6270,7 +6276,7 @@ </histogram> <histogram name="MediaRouter.Ui.Dialog.IconStateAtOpen" - enum="MediaRouterIconState" expires_after="2022-06-26"> + enum="MediaRouterIconState" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6280,7 +6286,7 @@ </histogram> <histogram name="MediaRouter.Ui.Dialog.LoadedWithData" units="ms" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6290,7 +6296,7 @@ </histogram> <histogram name="MediaRouter.Ui.Dialog.Paint" units="ms" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6300,7 +6306,7 @@ </histogram> <histogram name="MediaRouter.Ui.FirstAction" enum="MediaRouterUserAction" - expires_after="2022-07-03"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6309,7 +6315,7 @@ </histogram> <histogram name="MediaRouter.Ui.IconStateAtInit" enum="MediaRouterIconState" - expires_after="2022-02-01"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6321,7 +6327,7 @@ </histogram> <histogram name="MediaRouter.Ui.Navigate.SourceSelection" - enum="MediaRouterSourceTypes" expires_after="2022-02-01"> + enum="MediaRouterSourceTypes" expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> @@ -6330,7 +6336,7 @@ </histogram> <histogram name="MediaRouter.WiredDisplay.AvailableDevicesCount" units="units" - expires_after="2022-07-03"> + expires_after="2023-01-03"> <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml index d8fe1e4..454f215 100644 --- a/tools/metrics/histograms/metadata/navigation/histograms.xml +++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -226,7 +226,7 @@ <histogram name="BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame.MethodHash" - enum="MojoInterfaceName" expires_after="2021-10-04"> + enum="MojoInterfaceName" expires_after="2023-01-06"> <owner>hbolaria@chromium.org</owner> <owner>altimin@chromium.org</owner> <owner>bfcache-dev@chromium.org</owner> @@ -244,7 +244,7 @@ <histogram name="BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame.TimeUntilIPCReceived" - units="ms" expires_after="2021-10-04"> + units="ms" expires_after="2023-01-06"> <owner>hbolaria@chromium.org</owner> <owner>altimin@chromium.org</owner> <owner>bfcache-dev@chromium.org</owner> @@ -1146,7 +1146,7 @@ </histogram> <histogram name="Navigation.Prerender.ActivationCommitDeferTime" units="ms" - expires_after="2022-01-01"> + expires_after="2022-07-01"> <owner>sreejakshetty@chromium.org</owner> <owner>altimin@chromium.org</owner> <summary> @@ -1323,7 +1323,7 @@ </histogram> <histogram name="Navigation.TimeToActivatePrerender{TriggerType}" units="ms" - expires_after="2022-01-31"> + expires_after="2022-07-01"> <owner>sreejakshetty@chromium.org</owner> <owner>altimin@chromium.org</owner> <owner>asamidoi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 090be2f2..e638586 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -613,17 +613,18 @@ </histogram> <histogram name="Net.Cors.AccessCheckResult" enum="CorsAccessCheckResult" - expires_after="M98"> + expires_after="M102"> <owner>toyoshim@chromium.org</owner> <owner>yhirano@chromium.org</owner> <summary> The distribution of CORS access check results. This reports whenever CORS - AccessCheck runs. + AccessCheck runs. This is recorded when a CORS enabled request receives a + response and completes CORS checks. </summary> </histogram> <histogram name="Net.Cors.AccessCheckResult.NotSecureRequestor" - enum="CorsAccessCheckResult" expires_after="M98"> + enum="CorsAccessCheckResult" expires_after="M102"> <owner>carlosil@chromium.org</owner> <owner>estark@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml index 276d6af..0e095b0 100644 --- a/tools/metrics/histograms/metadata/network/histograms.xml +++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -162,6 +162,26 @@ <token key="NetworkType" variants="AshNetworkType"/> </histogram> +<histogram name="Network.Ash.{TechnologyType}.EnabledState.{Operation}.Result" + enum="BooleanSuccess" expires_after="2022-11-01"> + <owner>hsuregan@chromium.org</owner> + <owner>cros-connectivity@google.com</owner> + <summary> + Tracks the rate of success of performing the {Operation} operation on the + shill associated {TechnologyType} technology type. + </summary> + <token key="TechnologyType"> + <variant name="Cellular"/> + <variant name="Ethernet"/> + <variant name="VPN"/> + <variant name="WiFi"/> + </token> + <token key="Operation"> + <variant name="Disable"/> + <variant name="Enable"/> + </token> +</histogram> + <histogram name="Network.Cellular.Activation.StatusAtLogin" enum="NetworkCellularActivationState" expires_after="2021-08-29"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index e49ce81..f455d43 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -56,7 +56,8 @@ </histogram> <histogram name="NewTabPage.BackgroundService.Collections.RequestLatency" - units="ms" expires_after="2022-01-01"> + units="ms" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -67,7 +68,8 @@ </histogram> <histogram name="NewTabPage.BackgroundService.Images.RequestLatency" units="ms" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -725,7 +727,7 @@ </histogram> <histogram name="NewTabPage.CustomizeChromeBackgroundAction" - enum="NTPCustomizeChromeBackgroundAction" expires_after="2022-01-01"> + enum="NTPCustomizeChromeBackgroundAction" expires_after="2022-07-01"> <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> @@ -761,7 +763,8 @@ </histogram> <histogram name="NewTabPage.CustomizeLocalImageBackgroundAction" - enum="NTPCustomizeLocalImageBackgroundAction" expires_after="2022-01-01"> + enum="NTPCustomizeLocalImageBackgroundAction" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -907,7 +910,8 @@ </histogram> <histogram name="NewTabPage.LogoDownloadOutcome" - enum="NewTabPageLogoDownloadOutcome" expires_after="2022-01-01"> + enum="NewTabPageLogoDownloadOutcome" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -918,7 +922,8 @@ </histogram> <histogram name="NewTabPage.LogoDownloadTime" units="ms" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -931,7 +936,8 @@ </histogram> <histogram name="NewTabPage.LogoImageDownloaded" enum="BooleanFromHTTPCache" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -942,7 +948,8 @@ </histogram> <histogram name="NewTabPage.LogoShown" enum="NewTabPageLogoShown" - expires_after="2022-07-03"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -954,7 +961,8 @@ </histogram> <histogram name="NewTabPage.LogoShownTime2" units="ms" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -986,7 +994,8 @@ </histogram> <histogram name="NewTabPage.Modules.DataRequest" enum="NtpModules" - expires_after="2022-06-19"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -999,8 +1008,8 @@ </histogram> <histogram name="NewTabPage.Modules.Disabled{Interaction}" enum="NtpModules" - expires_after="2022-01-01"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1018,7 +1027,8 @@ </histogram> <histogram name="NewTabPage.Modules.Dismissed" units="count" - expires_after="2022-06-30"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>mahmadi@chromium.org</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1031,8 +1041,8 @@ </histogram> <histogram base="true" name="NewTabPage.Modules.EnabledOnNTPLoad" - enum="BooleanEnabled" expires_after="2022-06-12"> - <owner>danielms@google.com</owner> + enum="BooleanEnabled" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1044,8 +1054,8 @@ </histogram> <histogram name="NewTabPage.Modules.Enabled{Interaction}" enum="NtpModules" - expires_after="2022-01-01"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1062,8 +1072,8 @@ </histogram> <histogram name="NewTabPage.Modules.Hover" enum="NtpModules" - expires_after="2022-06-12"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1075,7 +1085,8 @@ </histogram> <histogram name="NewTabPage.Modules.Impression" units="ms" - expires_after="2022-05-15"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1089,8 +1100,8 @@ </histogram> <histogram name="NewTabPage.Modules.ImpressionRatio" units="perdecage" - expires_after="2022-05-08"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1109,8 +1120,8 @@ </histogram> <histogram name="NewTabPage.Modules.LoadDuration" units="ms" - expires_after="2022-05-08"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary> @@ -1119,7 +1130,8 @@ </histogram> <histogram name="NewTabPage.Modules.Loaded" units="ms" - expires_after="2022-05-15"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1130,7 +1142,8 @@ </histogram> <histogram name="NewTabPage.Modules.Restored" units="count" - expires_after="2022-06-30"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>mahmadi@chromium.org</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1143,7 +1156,8 @@ </histogram> <histogram name="NewTabPage.Modules.ShownTime" units="ms" - expires_after="2022-05-08"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1154,7 +1168,8 @@ </histogram> <histogram name="NewTabPage.Modules.Usage" units="count" - expires_after="2022-06-05"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1166,7 +1181,8 @@ </histogram> <histogram name="NewTabPage.Modules.VisibleOnNTPLoad" enum="BooleanVisible" - expires_after="2022-06-05"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1276,7 +1292,8 @@ </histogram> <histogram name="NewTabPage.OneGoogleBar.ShownTime" units="ms" - expires_after="2022-01-16"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1464,7 +1481,8 @@ </histogram> <histogram name="NewTabPage.Promos.RequestLatency2" units="ms" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1475,7 +1493,8 @@ </histogram> <histogram name="NewTabPage.Promos.ShownTime" units="ms" - expires_after="2022-01-16"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1502,7 +1521,8 @@ </histogram> <histogram name="NewTabPage.RecipeTasks.RecipeClick" units="index" - expires_after="2022-04-24"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1513,7 +1533,8 @@ </histogram> <histogram name="NewTabPage.RecipeTasks.RecipeDownloadCount" units="recipes" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1526,7 +1547,8 @@ </histogram> <histogram name="NewTabPage.RecipeTasks.RelatedSearchClick" units="index" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1703,7 +1725,8 @@ </histogram> <histogram name="NewTabPage.ShoppingTasks.ProductClick" units="index" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1714,7 +1737,8 @@ </histogram> <histogram name="NewTabPage.ShoppingTasks.ProductDownloadCount" - units="products" expires_after="2022-01-01"> + units="products" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1727,7 +1751,8 @@ </histogram> <histogram name="NewTabPage.ShoppingTasks.RelatedSearchClick" units="index" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -1738,7 +1763,8 @@ </histogram> <histogram name="NewTabPage.ShoppingTasks.RelatedSearchDownloadCount" - units="count" expires_after="2022-02-20"> + units="count" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -2048,9 +2074,11 @@ </histogram> <histogram name="NewTabPage.TileType" enum="NTPTileVisualType" - expires_after="2022-06-12"> - <owner>dbeam@chromium.org</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> + <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> <summary> The visual type of each most visited tile displayed on the new tab page, e.g. actual thumbnail or placeholder thumbnail. This is recorded for each @@ -2059,9 +2087,11 @@ </histogram> <histogram name="NewTabPage.TileTypeClicked" enum="NTPTileVisualType" - expires_after="2022-06-12"> - <owner>dbeam@chromium.org</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> + <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> <summary> The visual type of the most visited item that the user clicked on, e.g. actual thumbnail or placeholder thumbnail. @@ -2124,7 +2154,8 @@ </histogram> <histogram name="NewTabPage.URLState" enum="NewTabURLState" - expires_after="2022-01-01"> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -2182,8 +2213,8 @@ </histogram> <histogram name="NewTabPage.VoiceErrors" enum="NewTabPageVoiceError" - expires_after="2022-01-01"> - <owner>danielms@google.com</owner> + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 588cfbe..1b462a8 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -487,6 +487,40 @@ </summary> </histogram> +<histogram name="Ads.InterestGroup.Auction.First6AuctionsBitsPerPage" + units="bitfield" expires_after="2022-03-31"> + <owner>caraitto@chromium.org</owner> + <owner>pauljensen@chromium.org</owner> + <owner>privacy-sandbox-dev@chromium.org</owner> + <summary> + The outcome of the first 6 auctions reported as bits, tracked per-page, + reported at page unload (if at least 1 auction completed). A 1 indicates + auction success, 0 indicates auction failure. The most significant bit + corresponds to the least recent auction. An extra leading 1 is prepended -- + this allows reporting metrics when fewer than 6 auctions occurred during the + page's lifetime. Therefore, the max value is 0b1111111 (7 bits, represents 6 + successful auctions), and the min value is 0b10 (represents a page that had + 1 failed auction), and every value in between is valid. + + See https://github.com/WICG/turtledove/blob/main/FLEDGE.md for the latest + version of the FLEDGE explainer. + </summary> +</histogram> + +<histogram name="Ads.InterestGroup.Auction.NumAuctionsPerPage" units="auctions" + expires_after="2022-03-31"> + <owner>caraitto@chromium.org</owner> + <owner>pauljensen@chromium.org</owner> + <owner>privacy-sandbox-dev@chromium.org</owner> + <summary> + The number of auctions (runAdAuction() calls) per-page, from page load to + unload, reported at unload (if at least 1 auction completed). + + See https://github.com/WICG/turtledove/blob/main/FLEDGE.md for the latest + version of the FLEDGE explainer. + </summary> +</histogram> + <histogram name="Ads.InterestGroup.Auction.NumInterestGroups" units="groups" expires_after="2022-06-26"> <owner>mmenke@chromium.org</owner> @@ -520,6 +554,21 @@ </summary> </histogram> +<histogram name="Ads.InterestGroup.Auction.PercentAuctionsSuccessfulPerPage" + units="%" expires_after="2022-03-31"> + <owner>caraitto@chromium.org</owner> + <owner>pauljensen@chromium.org</owner> + <owner>privacy-sandbox-dev@chromium.org</owner> + <summary> + The percentage of auctions (runAdAuction() calls) per-page that succeed, + from page load to unload, reported at unload (if at least 1 auction + completed), rounded down to the nearest percent. + + See https://github.com/WICG/turtledove/blob/main/FLEDGE.md for the latest + version of the FLEDGE explainer. + </summary> +</histogram> + <histogram name="Ads.InterestGroup.Auction.Result" enum="AuctionResult" expires_after="2022-06-26"> <owner>mmenke@chromium.org</owner> @@ -533,6 +582,20 @@ </summary> </histogram> +<histogram name="Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage" + units="ms" expires_after="2022-03-31"> + <owner>caraitto@chromium.org</owner> + <owner>pauljensen@chromium.org</owner> + <owner>privacy-sandbox-dev@chromium.org</owner> + <summary> + The duration between runAdAuction() calls, collected on a per-page basis, + reported on each auction. + + See https://github.com/WICG/turtledove/blob/main/FLEDGE.md for the latest + version of the FLEDGE explainer. + </summary> +</histogram> + <histogram name="Ads.Media.Duration" units="ms" expires_after="2022-06-26"> <owner>johnidel@chromium.org</owner> <owner>dalecurtis@chromium.org</owner> @@ -2376,6 +2439,9 @@ <histogram name="Cast.Sender.CastMediaType" enum="MediaContainers" expires_after="2022-02-01"> + <obsolete> + No longer collected as of 2022-01. + </obsolete> <owner>takumif@chromium.org</owner> <owner>mfoltz@chromium.org</owner> <owner>openscreen-eng@google.com</owner> @@ -4777,6 +4843,24 @@ </summary> </histogram> +<histogram name="DirectSockets.TCPNetworkFailures" enum="NetErrorCodes" + expires_after="2022-06-07"> + <owner>ericwilligers@chromium.org</owner> + <owner>greengrape@google.com</owner> + <summary> + How often tcp socket opening finishes with a network failure. + </summary> +</histogram> + +<histogram name="DirectSockets.UDPNetworkFailures" enum="NetErrorCodes" + expires_after="2022-06-07"> + <owner>ericwilligers@chromium.org</owner> + <owner>greengrape@google.com</owner> + <summary> + How often udp socket opening finishes with a network failure. + </summary> +</histogram> + <histogram name="Discarding.DiscardCandidatesCount" units="tabs" expires_after="2022-05-01"> <owner>chrisha@chromium.org</owner> @@ -9676,6 +9760,9 @@ <histogram name="NQE.ConnectivityMonitor.NetworkChangeEvent" enum="NQE.ConnectivityMonitor.NetworkChangeType" expires_after="2021-08-29"> + <obsolete> + Removed January 2022. + </obsolete> <owner>rockot@google.com</owner> <owner>zhongyi@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index d97d7f5..294b4c2 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -131,7 +131,7 @@ </histogram> <histogram base="true" name="PageLoad.Bytes" units="units" - expires_after="2022-01-05"> + expires_after="2023-01-05"> <owner>jkarlin@chromium.org</owner> <owner>johnidel@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/phonehub/histograms.xml b/tools/metrics/histograms/metadata/phonehub/histograms.xml index 779d074..840c0c7 100644 --- a/tools/metrics/histograms/metadata/phonehub/histograms.xml +++ b/tools/metrics/histograms/metadata/phonehub/histograms.xml
@@ -311,6 +311,16 @@ </summary> </histogram> +<histogram name="PhoneHub.NotificationMessageLength" units="characters" + expires_after="2022-12-31"> + <owner>benjshen@chromium.org</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + The message length of a mirrored PhoneHub notification, not including the + title, logged each time a notification is added or updated. + </summary> +</histogram> + <histogram name="PhoneHub.NotificationOptIn" enum="PhoneHubInterstitialScreenEvent" expires_after="2022-10-31"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index d6ae77a..c20814ae 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -276,7 +276,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.BypassedByUser.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -309,7 +309,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.FailedToGetToken.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -320,7 +320,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.FailedToGetVerdict.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -331,7 +331,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.FileEncrypted.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>rogerta@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -342,7 +342,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.FileTooLarge.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -373,7 +373,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.TooManyRequests.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -384,7 +384,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.Unknown.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -394,7 +394,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Download.UnsupportedFileType.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -405,7 +405,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.BytesPerSeconds" - units="bytes" expires_after="2022-02-01"> + units="bytes" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -417,7 +417,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.CancelledByUser.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -439,7 +439,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.FailedToGetToken.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -450,7 +450,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.FailedToGetVerdict.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -461,7 +461,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.FileEncrypted.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>rogerta@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -472,7 +472,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.FileTooLarge.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -483,7 +483,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.Success.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -494,7 +494,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.Timeout.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -505,7 +505,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.TooManyRequests.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -516,7 +516,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.DragAndDrop.Unknown.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -528,7 +528,7 @@ <histogram name="SafeBrowsing.DeepScan.DragAndDrop.UnsupportedFileType.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -550,7 +550,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.CancelledByUser.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -571,7 +571,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.FailedToGetToken.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -582,7 +582,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.FailedToGetVerdict.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -593,7 +593,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.FileTooLarge.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -604,7 +604,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.Success.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -614,7 +614,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.Timeout.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -624,7 +624,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.TooManyRequests.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -635,7 +635,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.Unknown.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -645,7 +645,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.UnsupportedFileType.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -773,7 +773,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.BytesPerSeconds" units="bytes" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -784,7 +784,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.CancelledByUser.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -805,7 +805,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.FailedToGetToken.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -816,7 +816,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.FailedToGetVerdict.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -827,7 +827,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.FileEncrypted.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>rogerta@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -838,7 +838,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.FileTooLarge.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -849,7 +849,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.Success.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -859,7 +859,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.Timeout.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -869,7 +869,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.TooManyRequests.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -880,7 +880,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.Unknown.Duration" units="ms" - expires_after="2022-02-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -890,7 +890,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Upload.UnsupportedFileType.Duration" - units="ms" expires_after="2022-02-01"> + units="ms" expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml index b001eed3..9993dd4 100644 --- a/tools/metrics/histograms/metadata/search/histograms.xml +++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1270,7 +1270,7 @@ </histogram> <histogram name="Search.iOS.SelectDefaultSearchEngine" - enum="OmniboxSearchEngineType" expires_after="2022-02-04"> + enum="OmniboxSearchEngineType" expires_after="2023-01-04"> <owner>sczs@chromium.org</owner> <owner>gambard@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml index b9569bde..da2af34 100644 --- a/tools/metrics/histograms/metadata/service/histograms.xml +++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -389,7 +389,7 @@ </histogram> <histogram name="ServiceWorker.FetchEvent.QueuingTime" units="ms" - expires_after="2022-02-06"> + expires_after="2022-08-06"> <owner>asamidoi@chromium.org</owner> <owner>wanderview@chromium.org</owner> <owner>chrome-worker@google.com</owner> @@ -1261,7 +1261,7 @@ </histogram> <histogram name="ServiceWorker.Storage.DeleteAndStartOverResult" - enum="ServiceWorkerDeleteAndStartOverResult" expires_after="M100"> + enum="ServiceWorkerDeleteAndStartOverResult" expires_after="M110"> <owner>bashi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index b8189a9c..40fc591 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -769,8 +769,8 @@ </histogram> <histogram name="Startup.IncognitoForcedStart" enum="IncognitoForcedStart" - expires_after="M100"> - <owner>rhalavati@chromium.org</owner> + expires_after="M110"> + <owner>sideyilmaz@chromium.org</owner> <owner>chrome-incognito@google.com</owner> <summary> Records whether Incognito switch was present in commmand line switches and
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml index 8b1415b..7105f3c 100644 --- a/tools/metrics/histograms/metadata/uma/histograms.xml +++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -793,6 +793,10 @@ <histogram name="UMA.StructuredMetrics.ClientInitializationSuccessful" enum="BooleanSuccess" expires_after="M97"> + <obsolete> + Expired in M97 and removed from code in Jan 2022 for M99. This was reporting + 100% success on all channels as of Jan 2022. + </obsolete> <owner>jongahn@chromium.org</owner> <owner>tby@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml index d726b7b..970f1cc 100644 --- a/tools/metrics/histograms/metadata/webapps/histograms.xml +++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -226,6 +226,78 @@ </summary> </histogram> +<histogram name="WebApp.Icon.DownloadedHttpStatusCodeOnCreate" + enum="HttpResponseCode" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The HTTP status code returned for a list of icons when installing single + WebApp. Recorded when WebAppInstallTask finishes downloading icons for + non-sync installs. Icon download attempts with identical codes produce only + one event for this histogram. + </summary> +</histogram> + +<histogram name="WebApp.Icon.DownloadedHttpStatusCodeOnSync" + enum="HttpResponseCode" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The HTTP status code returned for a list of icons when installing single + WebApp. Recorded when WebAppInstallTask finishes downloading icons for web + apps from sync. Icon download attempts with identical codes produce only one + event for this histogram. + </summary> +</histogram> + +<histogram name="WebApp.Icon.DownloadedHttpStatusCodeOnUpdate" + enum="HttpResponseCode" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The HTTP status code returned for a list of icons when updating single + WebApp. Recorded when ManifestUpdateTask finishes downloading icons for + update. Icon download attempts with identical codes produce only one event + for this histogram. + </summary> +</histogram> + +<histogram name="WebApp.Icon.DownloadedResultOnCreate" + enum="WebAppIconsDownloadedResult" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The overall result returned by WebAppIconDownloader. Recorded when + WebAppInstallTask finishes downloading icons for non-sync installs. + </summary> +</histogram> + +<histogram name="WebApp.Icon.DownloadedResultOnSync" + enum="WebAppIconsDownloadedResult" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The overall result returned by WebAppIconDownloader. Recorded when + WebAppInstallTask finishes downloading icons for web aps from sync. + </summary> +</histogram> + +<histogram name="WebApp.Icon.DownloadedResultOnUpdate" + enum="WebAppIconsDownloadedResult" expires_after="2024-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The overall result returned by WebAppIconDownloader. Recorded when + ManifestUpdateTask finishes downloading icons. + </summary> +</histogram> + <histogram name="WebApp.Icon.HttpStatusCodeClassOnCreate" enum="HttpStatusCodeClass" expires_after="2024-01-01"> <owner>alancutter@chromium.org</owner> @@ -233,10 +305,7 @@ <owner>loyso@chromium.org</owner> <summary> The HTTP status code class returned for each icon loaded during a WebApp's - creation. See corresponding - Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate histogram for legacy - extension-based system. Recorded when WebAppDataRetriever starts downloading - icons. + creation. Recorded when WebAppInstallTask finishes downloading icons. </summary> </histogram> @@ -247,9 +316,7 @@ <owner>loyso@chromium.org</owner> <summary> The HTTP status code class returned for each icon loaded when syncing a - WebApp. See Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnSync histogram - for legacy extension-based system. Recorded when WebAppDataRetriever starts - downloading icons. + WebApp. Recorded when WebAppInstallTask finishes downloading icons on sync. </summary> </histogram> @@ -260,7 +327,7 @@ <owner>loyso@chromium.org</owner> <summary> The HTTP status code class returned for each icon loaded when updating a - WebApp. Recorded when WebAppDataRetriever starts downloading icons. + WebApp. Recorded when ManifestUpdateTask finishes downloading icons. </summary> </histogram>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 577ed58..f6db04a4 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -9330,7 +9330,7 @@ <summary> Metrics that reflect the accuracy of the predictions used by the Loading Predictor. This event will be recorded once per page load on - DocumentOnLoadCompletedInMainFrame(). + DocumentOnLoadCompletedInPrimaryMainFrame(). </summary> <metric name="CorrectSubresourceOriginPreconnectsInitiated"> <summary>
diff --git a/tools/traffic_annotation/auditor/safe_list.txt b/tools/traffic_annotation/auditor/safe_list.txt index 816700b1..2a40844da 100644 --- a/tools/traffic_annotation/auditor/safe_list.txt +++ b/tools/traffic_annotation/auditor/safe_list.txt
@@ -15,7 +15,6 @@ test_annotation,net/tools/quic/quic_http_proxy_backend_stream.cc # TODO(crbug.com/995852): Fix Android-specific annotations. missing,android_webview/browser/network_service/aw_proxy_config_monitor.cc -missing,chrome/android/features/tab_ui/java/src/or/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestions.java missing,chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsServerFetcher.java missing,chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java missing,chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java @@ -26,7 +25,6 @@ missing,chrome/browser/android/feedback/connectivity_checker.cc missing,chrome/browser/android/webapk/webapk_installer.cc missing,chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceProxy.java -missing,chrome/browser/endpoint_fetcher/endpoint_fetcher.cc missing,chrome/browser/page_annotations/android/java/src/org/chromium/chrome/browser/page_annotations/PageAnnotationsServiceProxy.java missing,chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/StorePersistedTabData.java missing,net/proxy_resolution/proxy_config_service_android.cc
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 1422aa2..8b127ee3 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -345,6 +345,7 @@ <item id="fedcm" added_in_milestone="98" content_hash_code="02f3cbfc" os_list="linux,windows,chromeos,android" file_path="content/browser/webid/idp_network_request_manager.cc" /> <item id="minidump_uploader_android" added_in_milestone="98" content_hash_code="0327544e" os_list="android" file_path="components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/util/HttpURLConnectionFactoryImpl.java" /> <item id="chrome_variations_android" added_in_milestone="98" content_hash_code="04eeb61f" os_list="android" file_path="components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java" /> + <item id="fwupd_firmware_update" added_in_milestone="99" content_hash_code="0002c968" os_list="chromeos" file_path="ash/components/fwupd/firmware_update_manager.cc" /> <item id="wallpaper_google_photos_count" added_in_milestone="99" content_hash_code="073c3f10" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" /> <item id="wallpaper_backdrop_collection_names" added_in_milestone="99" content_hash_code="06379fce" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" /> <item id="wallpaper_backdrop_images_info" added_in_milestone="99" content_hash_code="0010428c" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" />
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 308838f..22e449c 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -63,6 +63,7 @@ <traffic_annotation unique_id="customization_wallpaper_downloader"/> <traffic_annotation unique_id="edu_account_login_profile_image_fetcher"/> <traffic_annotation unique_id="fast_pair_footprints_request"/> + <traffic_annotation unique_id="fwupd_firmware_update"/> <traffic_annotation unique_id="gaia_reauth_token_fetcher"/> <traffic_annotation unique_id="ime_url_downloader"/> <traffic_annotation unique_id="image_downloader"/>
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 5ff9c807..2297086 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -148,6 +148,15 @@ ::features::kExperimentalAccessibilityDictationCommands); } +const base::Feature kExperimentalAccessibilityDictationExtension{ + "ExperimentalAccessibilityDictationExtension", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool IsExperimentalAccessibilityDictationExtensionEnabled() { + return base::FeatureList::IsEnabled( + ::features::kExperimentalAccessibilityDictationExtension); +} + const base::Feature kEnhancedNetworkVoices{"EnhancedNetworkVoices", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index 44c579b..d6823b0 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -118,6 +118,13 @@ // text editing commands is enabled. AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationCommandsEnabled(); +// Enables the accessibility Dictation extension. +AX_BASE_EXPORT extern const base::Feature + kExperimentalAccessibilityDictationExtension; + +// Returns true if experimental accessibility dictation extension is enabled. +AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationExtensionEnabled(); + // Enables high-quality, network-based voices in Select-to-speak. AX_BASE_EXPORT extern const base::Feature kEnhancedNetworkVoices;
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc index de7f1a42..906ac88b 100644 --- a/ui/accessibility/accessibility_switches.cc +++ b/ui/accessibility/accessibility_switches.cc
@@ -13,11 +13,6 @@ const char kEnableExperimentalAccessibilityAutoclick[] = "enable-experimental-accessibility-autoclick"; -// Enables the experimental dictation extension on Chrome OS that hasn't -// launched yet. -const char kEnableExperimentalAccessibilityDictationExtension[] = - "enable-experimental-accessibility-dictation-extension"; - // Enables support for visually debugging the accessibility labels // feature, which provides images descriptions for screen reader users. const char kEnableExperimentalAccessibilityLabelsDebugging[] = @@ -46,11 +41,6 @@ const char kEnableExperimentalAccessibilitySwitchAccessMultistepAutomation[] = "enable-experimental-accessibility-switch-access-multistep-automation"; -bool IsExperimentalAccessibilityDictationExtensionEnabled() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kEnableExperimentalAccessibilityDictationExtension); -} - bool IsExperimentalAccessibilityLanguageDetectionEnabled() { return base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kEnableExperimentalAccessibilityLanguageDetection);
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h index 7ae00e9..7c90a96 100644 --- a/ui/accessibility/accessibility_switches.h +++ b/ui/accessibility/accessibility_switches.h
@@ -13,8 +13,6 @@ AX_BASE_EXPORT extern const char kEnableExperimentalAccessibilityAutoclick[]; AX_BASE_EXPORT extern const char - kEnableExperimentalAccessibilityDictationExtension[]; -AX_BASE_EXPORT extern const char kEnableExperimentalAccessibilityLabelsDebugging[]; AX_BASE_EXPORT extern const char kEnableExperimentalAccessibilityLanguageDetection[]; @@ -25,9 +23,6 @@ AX_BASE_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccessMultistepAutomation[]; -// Returns true if experimental accessibility dictation extension is enabled. -AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationExtensionEnabled(); - // Returns true if experimental accessibility language detection is enabled. AX_BASE_EXPORT bool IsExperimentalAccessibilityLanguageDetectionEnabled();
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 8776c85..a767903 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -68,7 +68,9 @@ base::LazyInstance<UniqueIdMap>::Leaky g_unique_id_map = LAZY_INSTANCE_INITIALIZER; -#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() +// TODO(fxbug.dev/91030): Remove the !defined(OS_FUCHSIA) condition once fuchsia +// has native accessibility. +#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() && !defined(OS_FUCHSIA) // static AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { AXPlatformNodeBase* node = new AXPlatformNodeBase(); @@ -2370,7 +2372,7 @@ details_roles_set.insert("comment"); break; } - FALLTHROUGH; + [[fallthrough]]; } default: // Use * to indicate some other role.
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm index e1da773..83402fd 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.mm +++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -653,6 +653,7 @@ // These attributes are required on all accessibility objects. NSArray* const kAllRoleAttributes = @[ + NSAccessibilityDOMClassList, NSAccessibilityDOMIdentifierAttribute, NSAccessibilityChildrenAttribute, NSAccessibilityParentAttribute, @@ -1023,6 +1024,23 @@ return [elements count] ? elements : nil; } +- (NSArray*)AXDOMClassList { + if (![self instanceActive]) + return nil; + + NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + + std::string classes; + if (_node->GetStringAttribute(ax::mojom::StringAttribute::kClassName, + &classes)) { + std::vector<std::string> split_classes = base::SplitString( + classes, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (const auto& className : split_classes) + [ret addObject:(base::SysUTF8ToNSString(className))]; + } + return ret; +} + - (NSString*)AXDOMIdentifier { if (![self instanceActive]) return nil;
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 0159b8e..dfa3cc1 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -299,7 +299,7 @@ break; } } - FALLTHROUGH; + [[fallthrough]]; case TextUnit_Document: SetStart(start()->CreatePositionAtStartOfContent()->AsLeafTextPosition()); SetEnd(start()->CreatePositionAtEndOfContent());
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index ddf9a441..bf2d893 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -1848,7 +1848,7 @@ if (DescendantHasComment(this)) return AnnotationType_Comment; - FALLTHROUGH; + [[fallthrough]]; } default: return AnnotationType_Unknown; @@ -5872,7 +5872,7 @@ if (!HasState(ax::mojom::State::kFocusable) || GetBoolAttribute(ax::mojom::BoolAttribute::kNonAtomicTextFieldRoot)) break; // Not used with activedescendant, so preserve editable state. - FALLTHROUGH; // Will clear editable state. + [[fallthrough]]; // Will clear editable state. case ax::mojom::Role::kMenuListPopup: case ax::mojom::Role::kMenuListOption: ia2_state &= ~(IA2_STATE_EDITABLE);
diff --git a/ui/accessibility/platform/ax_private_attributes_mac.h b/ui/accessibility/platform/ax_private_attributes_mac.h index d341a715..30b59fb1 100644 --- a/ui/accessibility/platform/ax_private_attributes_mac.h +++ b/ui/accessibility/platform/ax_private_attributes_mac.h
@@ -38,6 +38,8 @@ @"AXAutocompleteValue"; AX_EXPORT constexpr NSString* const NSAccessibilityDetailsElementsAttribute = @"AXDetailsElements"; +AX_EXPORT constexpr NSString* const NSAccessibilityDOMClassList = + @"AXDOMClassList"; AX_EXPORT constexpr NSString* const NSAccessibilityDOMIdentifierAttribute = @"AXDOMIdentifier"; AX_EXPORT constexpr NSString* const NSAccessibilityHasPopupAttribute =
diff --git a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.cc b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.cc index 4457bdb..9ee083a 100644 --- a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.cc +++ b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.cc
@@ -10,13 +10,15 @@ AXPlatformNodeFuchsia::~AXPlatformNodeFuchsia() = default; -gfx::NativeViewAccessible AXPlatformNodeFuchsia::GetNativeViewAccessible() { - return nullptr; +// static +AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { + AXPlatformNodeFuchsia* node = new AXPlatformNodeFuchsia(); + node->Init(delegate); + return node; } -void AXPlatformNodeFuchsia::NotifyAccessibilityEvent( - ax::mojom::Event event_type) { - NOTIMPLEMENTED(); +gfx::NativeViewAccessible AXPlatformNodeFuchsia::GetNativeViewAccessible() { + return nullptr; } void AXPlatformNodeFuchsia::PerformAction(const AXActionData& data) {
diff --git a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h index 6543ec8..1a06960 100644 --- a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h +++ b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h
@@ -23,7 +23,6 @@ // AXPlatformNode overrides. gfx::NativeViewAccessible GetNativeViewAccessible() override; - void NotifyAccessibilityEvent(ax::mojom::Event event_type) override; // Requests that the delegate perform the specified action. void PerformAction(const AXActionData& data);
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider.cc b/ui/accessibility/platform/fuchsia/semantic_provider.cc index dd0a9776..07e486c 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider.cc +++ b/ui/accessibility/platform/fuchsia/semantic_provider.cc
@@ -200,8 +200,10 @@ fuchsia::accessibility::semantics::Action action, fuchsia::accessibility::semantics::SemanticListener:: OnAccessibilityActionRequestedCallback callback) { - if (delegate_->OnAccessibilityAction(node_id, action)) + if (delegate_->OnAccessibilityAction(node_id, action)) { callback(true); + return; + } // The action was not handled. callback(false); @@ -303,4 +305,4 @@ TryToCommit(); } -} // namespace ui \ No newline at end of file +} // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_test.cc b/ui/accessibility/platform/fuchsia/semantic_provider_test.cc index ba5e469..ccded33 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider_test.cc +++ b/ui/accessibility/platform/fuchsia/semantic_provider_test.cc
@@ -127,6 +127,10 @@ fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree> semantic_tree_request) final { semantic_listener_ = listener.Bind(); + semantic_listener_.set_error_handler([](zx_status_t status) { + // The test should fail if an error occurs. + ADD_FAILURE(); + }); semantic_tree_binding_.Bind(std::move(semantic_tree_request)); } @@ -438,4 +442,4 @@ } } // namespace -} // namespace ui \ No newline at end of file +} // namespace ui
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm index d60b7815b..70ea63c 100644 --- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm +++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
@@ -49,6 +49,7 @@ NSAccessibilityAutocompleteValueAttribute, NSAccessibilityColumnHeaderUIElementsAttribute, NSAccessibilityDetailsElementsAttribute, + NSAccessibilityDOMClassList, NSAccessibilityHasPopupAttribute, NSAccessibilityInvalidAttribute, NSAccessibilityMathFractionNumeratorAttribute,
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index b0d8d3b9..fcba980a 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -703,7 +703,7 @@ case ax::mojom::Role::kSection: if (HasStringAttribute(ax::mojom::StringAttribute::kName)) return u"region"; - FALLTHROUGH; + [[fallthrough]]; default: return {};
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 6916cd4..0e42331 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -244,7 +244,6 @@ "java/src/org/chromium/ui/LayoutInflaterUtils.java", "java/src/org/chromium/ui/OverscrollRefreshHandler.java", "java/src/org/chromium/ui/UiSwitches.java", - "java/src/org/chromium/ui/VSyncMonitor.java", "java/src/org/chromium/ui/ViewProvider.java", "java/src/org/chromium/ui/base/ActivityAndroidPermissionDelegate.java", "java/src/org/chromium/ui/base/ActivityIntentRequestTrackerDelegate.java",
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index 5e21334..af68f2326 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -124,6 +124,7 @@ <color name="white_alpha_32" tools:ignore="UnusedResources">#51FFFFFF</color> <color name="white_alpha_38" tools:ignore="UnusedResources">#61FFFFFF</color> <color name="white_alpha_50">#80FFFFFF</color> + <color name="white_alpha_60">#99FFFFFF</color> <color name="white_alpha_70">#B3FFFFFF</color> <color name="modern_yellow_300">#FDD663</color> <color name="modern_yellow_500">#FBBC04</color>
diff --git a/ui/android/java/res/values/dimens.xml b/ui/android/java/res/values/dimens.xml index 2c0d5b4..0d9d625 100644 --- a/ui/android/java/res/values/dimens.xml +++ b/ui/android/java/res/values/dimens.xml
@@ -102,6 +102,7 @@ <dimen name="default_elevation_3">6dp</dimen> <dimen name="default_elevation_4">8dp</dimen> <dimen name="default_elevation_5">12dp</dimen> + <dimen name="default_elevation_6">67dp</dimen> <!-- TODO(crbug.com/1236215): Remove once dynamic color is ready for all cards --> <dimen name="card_elevation">@dimen/default_elevation_1</dimen>
diff --git a/ui/android/java/res/values/semantic_colors_adaptive.xml b/ui/android/java/res/values/semantic_colors_adaptive.xml index 91864bd..080a127 100644 --- a/ui/android/java/res/values/semantic_colors_adaptive.xml +++ b/ui/android/java/res/values/semantic_colors_adaptive.xml
@@ -44,12 +44,12 @@ <!-- TODO(https://crbug.com/1210689): These all need to ultimately be removed because they do not work with dynamic colors. --> - <color name="default_bg_color_elev_1_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_1</color> - <color name="default_bg_color_elev_2_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_2</color> - <color name="default_bg_color_elev_3_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_3</color> - <color name="default_bg_color_elev_4_baseline">@color/default_bg_color_light_elev_4</color> - <color name="default_bg_color_elev_5_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_5</color> - <color name="default_bg_color_elev_6_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_6</color> + <color name="default_bg_color_elev_1_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_1_baseline</color> + <color name="default_bg_color_elev_2_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_2_baseline</color> + <color name="default_bg_color_elev_3_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_3_baseline</color> + <color name="default_bg_color_elev_4_baseline">@color/default_bg_color_light_elev_4_baseline</color> + <color name="default_bg_color_elev_5_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_5_baseline</color> + <color name="default_bg_color_elev_6_baseline" tools:ignore="UnusedResources">@color/default_bg_color_light_elev_6_baseline</color> <color name="legacy_bg_color_elev_1">@color/legacy_bg_color_light_elev_1</color> <color name="legacy_bg_color_elev_4">@color/legacy_bg_color_light_elev_4</color> @@ -113,7 +113,7 @@ file. These reference non-color palette colors which is currently blocked by PRESUBMIT scripts. --> <color name="menu_action_bar_bg_color">@color/menu_action_bar_bg_color_light</color> - <color name="menu_action_bar_bg_color_light">@color/default_bg_color_light_elev_1</color> + <color name="menu_action_bar_bg_color_light">@color/default_bg_color_light_elev_1_baseline</color> <color name="menu_action_bar_bg_color_dark">@color/default_bg_color_dark_elev_6</color> <color name="menu_item_bg_color">@color/menu_item_bg_color_light</color> <color name="menu_item_bg_color_light">@color/default_bg_color_light</color>
diff --git a/ui/android/java/res/values/semantic_colors_non_adaptive.xml b/ui/android/java/res/values/semantic_colors_non_adaptive.xml index efda394d..17ea20c8 100644 --- a/ui/android/java/res/values/semantic_colors_non_adaptive.xml +++ b/ui/android/java/res/values/semantic_colors_non_adaptive.xml
@@ -60,12 +60,12 @@ <color name="default_bg_color_dark">@color/modern_grey_900</color> <color name="default_bg_color_secondary_light">@color/baseline_neutral_0_with_neutral_600_alpha_5_with_primary_600_2</color> <color name="default_bg_color_secondary_dark">@color/baseline_neutral_900_with_neutral_200_alpha_5_with_primary_200_alpha_2</color> - <color name="default_bg_color_light_elev_1" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_5_with_primary_600_2</color> - <color name="default_bg_color_light_elev_2" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_8_with_primary_600_2</color> - <color name="default_bg_color_light_elev_3" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_11_with_primary_600_2</color> - <color name="default_bg_color_light_elev_4" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_12_with_primary_600_2</color> - <color name="default_bg_color_light_elev_5" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_14_with_primary_600_2</color> - <color name="default_bg_color_light_elev_6" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_20_with_primary_600_2</color> + <color name="default_bg_color_light_elev_1_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_5_with_primary_600_2</color> + <color name="default_bg_color_light_elev_2_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_8_with_primary_600_2</color> + <color name="default_bg_color_light_elev_3_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_11_with_primary_600_2</color> + <color name="default_bg_color_light_elev_4_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_12_with_primary_600_2</color> + <color name="default_bg_color_light_elev_5_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_14_with_primary_600_2</color> + <color name="default_bg_color_light_elev_6_baseline" tools:ignore="UnusedResources">@color/baseline_neutral_0_with_neutral_600_alpha_20_with_primary_600_2</color> <color name="legacy_bg_color_light_elev_1">@color/modern_white</color> <color name="legacy_bg_color_light_elev_4">@color/modern_white</color> <color name="default_bg_color_dark_elev_1" tools:ignore="UnusedResources">@color/baseline_neutral_900_with_neutral_200_alpha_5_with_primary_200_alpha_2</color>
diff --git a/ui/android/java/src/org/chromium/ui/VSyncMonitor.java b/ui/android/java/src/org/chromium/ui/VSyncMonitor.java deleted file mode 100644 index 761d96c..0000000 --- a/ui/android/java/src/org/chromium/ui/VSyncMonitor.java +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.ui; - -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.view.Choreographer; - -import org.chromium.base.TraceEvent; - -/** - * Notifies clients of the default displays's vertical sync pulses. - */ -public class VSyncMonitor { - private static final long NANOSECONDS_PER_SECOND = 1000000000; - private static final long NANOSECONDS_PER_MICROSECOND = 1000; - - private static final ThreadLocal<Boolean> sInsideVSync = new ThreadLocal<Boolean>() { - @Override - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; - - // Conservative guess about vsync's consecutivity. - // If true, next tick is guaranteed to be consecutive. - private boolean mConsecutiveVSync; - - /** - * VSync listener class - */ - public interface Listener { - /** - * Called very soon after the start of the display's vertical sync period. - * @param monitor The VSyncMonitor that triggered the signal. - * @param vsyncTimeMicros Absolute frame time in microseconds. - */ - public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros); - } - - private Listener mListener; - - // Display refresh rate as reported by the system. - private long mRefreshPeriodNano; - private boolean mUseEstimatedRefreshRate; - - private boolean mHaveRequestInFlight; - - private final Choreographer mChoreographer; - private final Choreographer.FrameCallback mVSyncFrameCallback; - private long mGoodStartingPointNano; - - // If the monitor is activated after having been idle, we synthesize the first vsync to reduce - // latency. - private final Handler mHandler = new Handler(); - - /** - * Constructs a VSyncMonitor - * @param context The application context. - * @param listener The listener receiving VSync notifications. - */ - public VSyncMonitor(Context context, VSyncMonitor.Listener listener, float refreshRate) { - mListener = listener; - updateRefreshRate(refreshRate); - - mChoreographer = Choreographer.getInstance(); - mVSyncFrameCallback = new Choreographer.FrameCallback() { - @Override - public void doFrame(long frameTimeNanos) { - TraceEvent.begin("VSync"); - if (mUseEstimatedRefreshRate && mConsecutiveVSync) { - // Display.getRefreshRate() is unreliable on some platforms. - // Adjust refresh period- initial value is based on Display.getRefreshRate() - // after that it asymptotically approaches the real value. - long lastRefreshDurationNano = frameTimeNanos - mGoodStartingPointNano; - float lastRefreshDurationWeight = 0.1f; - mRefreshPeriodNano += (long) (lastRefreshDurationWeight - * (lastRefreshDurationNano - mRefreshPeriodNano)); - } - mGoodStartingPointNano = frameTimeNanos; - onVSyncCallback(frameTimeNanos, getCurrentNanoTime()); - TraceEvent.end("VSync"); - } - }; - mGoodStartingPointNano = getCurrentNanoTime(); - } - - public void updateRefreshRate(float refreshRate) { - mUseEstimatedRefreshRate = refreshRate < 30; - if (refreshRate <= 0) refreshRate = 60; - mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate); - } - - /** - * Returns the time interval between two consecutive vsync pulses in microseconds. - */ - public long getVSyncPeriodInMicroseconds() { - return mRefreshPeriodNano / NANOSECONDS_PER_MICROSECOND; - } - - /** - * Request to be notified of the closest display vsync events. This should - * always be called on the same thread used to create the VSyncMonitor. - * Listener.onVSync() will be called soon after the upcoming vsync pulses. - */ - public void requestUpdate() { - assert mHandler.getLooper() == Looper.myLooper(); - postCallback(); - } - - /** - * @return true if any onVSync handler is executing on the current thread. - * If onVSync handler introduces invalidations, View#invalidate() should be - * called. If View#postInvalidateOnAnimation is called instead, the - * corresponding onDraw will be delayed by one frame. The embedder of - * VSyncMonitor should check this value if it wants to post an invalidation. - */ - public static boolean isInsideVSync() { - return VSyncMonitor.sInsideVSync.get(); - } - - private long getCurrentNanoTime() { - return System.nanoTime(); - } - - private void onVSyncCallback(long frameTimeNanos, long currentTimeNanos) { - assert mHaveRequestInFlight; - VSyncMonitor.sInsideVSync.set(true); - mHaveRequestInFlight = false; - try { - if (mListener != null) { - mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSECOND); - } - } finally { - VSyncMonitor.sInsideVSync.set(false); - } - } - - private void postCallback() { - if (mHaveRequestInFlight) return; - mHaveRequestInFlight = true; - mConsecutiveVSync = VSyncMonitor.sInsideVSync.get(); - mChoreographer.postFrameCallback(mVSyncFrameCallback); - } -}
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java index a9e361d..aa0cf85 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
@@ -51,9 +51,11 @@ // Never remove the primary display. if (sdkDisplayId == mMainSdkDisplayId) return; - DisplayAndroid displayAndroid = mIdMap.get(sdkDisplayId); + PhysicalDisplayAndroid displayAndroid = + (PhysicalDisplayAndroid) mIdMap.get(sdkDisplayId); if (displayAndroid == null) return; + displayAndroid.onDisplayRemoved(); if (mNativePointer != 0) { DisplayAndroidManagerJni.get().removeDisplay( mNativePointer, DisplayAndroidManager.this, sdkDisplayId);
diff --git a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java index b6ee8055..b2f2685 100644 --- a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java +++ b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java
@@ -5,16 +5,24 @@ package org.chromium.ui.display; import android.annotation.TargetApi; +import android.content.ComponentCallbacks; +import android.content.Context; +import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Point; +import android.graphics.Rect; import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; +import android.view.WindowManager; import org.chromium.base.CommandLine; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.compat.ApiHelperForM; import org.chromium.base.compat.ApiHelperForO; +import org.chromium.base.compat.ApiHelperForR; +import org.chromium.base.compat.ApiHelperForS; import java.util.Arrays; import java.util.List; @@ -25,6 +33,9 @@ /* package */ class PhysicalDisplayAndroid extends DisplayAndroid { private static final String TAG = "DisplayAndroid"; + // The behavior of observing window configuration changes using ComponentCallbacks is new in S. + private static final boolean USE_CONFIGURATION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S; + // When this object exists, a positive value means that the forced DIP scale is set and // the zero means it is not. The non existing object (i.e. null reference) means that // the existence and value of the forced DIP scale has not yet been determined. @@ -122,13 +133,59 @@ } } + private final Context mWindowContext; + private final ComponentCallbacks mComponentCallbacks; + /* package */ PhysicalDisplayAndroid(Display display) { super(display.getDisplayId()); + if (USE_CONFIGURATION) { + Context appContext = ContextUtils.getApplicationContext(); + mWindowContext = ApiHelperForS.createWindowContext( + appContext, display, WindowManager.LayoutParams.TYPE_APPLICATION, null); + assert display.getDisplayId() + == ApiHelperForR.getDisplay(mWindowContext).getDisplayId(); + mComponentCallbacks = new ComponentCallbacks() { + @Override + public void onLowMemory() {} + + @Override + public void onConfigurationChanged(Configuration newConfig) { + updateFromConfiguration(); + } + }; + mWindowContext.registerComponentCallbacks(mComponentCallbacks); + updateFromConfiguration(); + } else { + mWindowContext = null; + mComponentCallbacks = null; + } + } + + private void updateFromConfiguration() { + Point size = new Point(); + WindowManager windowManager = mWindowContext.getSystemService(WindowManager.class); + Rect rect = ApiHelperForR.getMaximumWindowMetricsBounds(windowManager); + size.set(rect.width(), rect.height()); + DisplayMetrics displayMetrics = mWindowContext.getResources().getDisplayMetrics(); + updateCommon(size, displayMetrics.density, ApiHelperForR.getDisplay(mWindowContext)); + } + + /* package */ void onDisplayRemoved() { + if (USE_CONFIGURATION) { + mWindowContext.unregisterComponentCallbacks(mComponentCallbacks); + } } @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) /* package */ void updateFromDisplay(Display display) { + if (USE_CONFIGURATION) { + assert display.getDisplayId() + == ApiHelperForR.getDisplay(mWindowContext).getDisplayId(); + // Needed to update non-configuration info such as refresh rate. + updateFromConfiguration(); + return; + } Point size = new Point(); DisplayMetrics displayMetrics = new DisplayMetrics(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { @@ -138,7 +195,11 @@ display.getSize(size); display.getMetrics(displayMetrics); } - if (hasForcedDIPScale()) displayMetrics.density = sForcedDIPScale.floatValue(); + updateCommon(size, displayMetrics.density, display); + } + + private void updateCommon(Point size, float density, Display display) { + if (hasForcedDIPScale()) density = sForcedDIPScale.floatValue(); boolean isWideColorGamut = false; // Although this API was added in Android O, it was buggy. // Restrict to Android Q, where it was fixed. @@ -161,8 +222,8 @@ assert supportedModes.size() > 0; } - super.update(size, displayMetrics.density, bitsPerPixel(pixelFormatId), - bitsPerComponent(pixelFormatId), display.getRotation(), isWideColorGamut, null, - display.getRefreshRate(), currentMode, supportedModes); + super.update(size, density, bitsPerPixel(pixelFormatId), bitsPerComponent(pixelFormatId), + display.getRotation(), isWideColorGamut, null, display.getRefreshRate(), + currentMode, supportedModes); } }
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java index bb0e6154..0510c1a6 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java
@@ -15,6 +15,7 @@ import org.chromium.ui.modelutil.PropertyModel.ReadableIntPropertyKey; import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; import java.lang.annotation.Retention; @@ -82,6 +83,9 @@ /** The title of the dialog. */ public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>(); + /** The maximum number of lines that the title can take. */ + public static final WritableIntPropertyKey TITLE_MAX_LINES = new WritableIntPropertyKey(); + /** The title icon of the dialog. */ public static final WritableObjectPropertyKey<Drawable> TITLE_ICON = new WritableObjectPropertyKey<>(); @@ -161,7 +165,7 @@ public static final WritableBooleanPropertyKey FOCUS_DIALOG = new WritableBooleanPropertyKey(); public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {CONTROLLER, CONTENT_DESCRIPTION, - TITLE, TITLE_ICON, MESSAGE, CUSTOM_VIEW, POSITIVE_BUTTON_TEXT, + TITLE, TITLE_MAX_LINES, TITLE_ICON, MESSAGE, CUSTOM_VIEW, POSITIVE_BUTTON_TEXT, POSITIVE_BUTTON_CONTENT_DESCRIPTION, POSITIVE_BUTTON_DISABLED, NEGATIVE_BUTTON_TEXT, NEGATIVE_BUTTON_CONTENT_DESCRIPTION, NEGATIVE_BUTTON_DISABLED, CANCEL_ON_TOUCH_OUTSIDE, FILTER_TOUCH_FOR_SECURITY, TOUCH_FILTERED_CALLBACK, TITLE_SCROLLABLE, BUTTON_STYLES,
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc index c4045d9..2d7373a 100644 --- a/ui/aura/test/aura_test_helper.cc +++ b/ui/aura/test/aura_test_helper.cc
@@ -27,6 +27,7 @@ #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/test/test_context_factories.h" #include "ui/display/screen.h" +#include "ui/events/platform/platform_event_source.h" #include "ui/wm/core/default_activation_client.h" #include "ui/wm/core/default_screen_position_client.h" @@ -156,6 +157,9 @@ ui::ShutdownInputMethodForTesting(); + if (ui::PlatformEventSource::GetInstance()) + ui::PlatformEventSource::GetInstance()->StopProcessingEventsForTesting(); + // Destroy all owned objects to prevent tests from depending on their state // after this returns. screen_position_client_.reset();
diff --git a/ui/aura_extra/BUILD.gn b/ui/aura_extra/BUILD.gn index 1620f85..708e4a4 100644 --- a/ui/aura_extra/BUILD.gn +++ b/ui/aura_extra/BUILD.gn
@@ -9,6 +9,8 @@ "aura_extra_export.h", "image_window_delegate.cc", "image_window_delegate.h", + "window_position_in_root_monitor.cc", + "window_position_in_root_monitor.h", ] defines = [ "AURA_EXTRA_IMPLEMENTATION" ] @@ -34,18 +36,6 @@ } } -source_set("window_position_in_root_monitor") { - sources = [ - "window_position_in_root_monitor.cc", - "window_position_in_root_monitor.h", - ] - - deps = [ - "//base", - "//ui/aura", - ] -} - source_set("tests") { testonly = true @@ -53,7 +43,6 @@ deps = [ ":aura_extra", - ":window_position_in_root_monitor", "//base", "//base/test:test_support", "//testing/gtest",
diff --git a/ui/aura_extra/window_position_in_root_monitor.h b/ui/aura_extra/window_position_in_root_monitor.h index f595ccf..dcfca644 100644 --- a/ui/aura_extra/window_position_in_root_monitor.h +++ b/ui/aura_extra/window_position_in_root_monitor.h
@@ -9,13 +9,15 @@ #include "base/callback.h" #include "ui/aura/window_observer.h" +#include "ui/aura_extra/aura_extra_export.h" namespace aura_extra { // WindowPositionInRootMonitor notifies a callback any time the position of a // window, relative to the root, changes. Changes are only sent when attached // to a valid root. -class WindowPositionInRootMonitor : public aura::WindowObserver { +class AURA_EXTRA_EXPORT WindowPositionInRootMonitor + : public aura::WindowObserver { public: WindowPositionInRootMonitor(aura::Window* window, base::RepeatingClosure callback);
diff --git a/ui/chromeos/styles/cros_colors.json5 b/ui/chromeos/styles/cros_colors.json5 index 9c13bfb..dc4a65a 100644 --- a/ui/chromeos/styles/cros_colors.json5 +++ b/ui/chromeos/styles/cros_colors.json5
@@ -238,6 +238,11 @@ button_ripple_color_primary: { light: "$white", dark: "$black" }, /* button-primary:hover */ button_background_color_primary_hover: "rgba($black_rgb, 0.08)", + /* the _preblended variant can be used directly as hover background color + because it's already blended on top of the background color, the above + _hover variable is still required because it's being used on google3 side */ + button_background_color_primary_hover_preblended: + "blend($button_background_color_primary_hover, $button_background_color_primary)", /* button-primary:active */ button_active_shadow_color_ambient_primary: { light: "rgba($google_blue_500_rgb, 0.15)", @@ -314,6 +319,9 @@ light: "rgba($black_rgb, 0.05)", dark: "rgba($white_rgb, 0.1)", }, + /* when icon button is pressed, we layer the $ripple_color on top of the + hover color (which is also $ripple_color) */ + icon_button_pressed_color: "blend($ripple_color, $ripple_color)", /* menu */ menu_label_color: {
diff --git a/ui/events/gesture_event_details.cc b/ui/events/gesture_event_details.cc index 4423a943..85bf95f 100644 --- a/ui/events/gesture_event_details.cc +++ b/ui/events/gesture_event_details.cc
@@ -85,7 +85,7 @@ // allowed as an exception. if (other.type() == ui::ET_GESTURE_PINCH_BEGIN) break; - FALLTHROUGH; + [[fallthrough]]; case ui::ET_GESTURE_SCROLL_UPDATE: case ui::ET_SCROLL_FLING_START: case ui::ET_GESTURE_SWIPE:
diff --git a/ui/events/gestures/motion_event_aura.cc b/ui/events/gestures/motion_event_aura.cc index 2ac4017..ce7f3467 100644 --- a/ui/events/gestures/motion_event_aura.cc +++ b/ui/events/gestures/motion_event_aura.cc
@@ -100,7 +100,7 @@ case ET_TOUCH_PRESSED: if (!AddTouch(touch)) return false; - FALLTHROUGH; + [[fallthrough]]; case ET_TOUCH_RELEASED: case ET_TOUCH_CANCELLED: // Removing these touch points needs to be postponed until after the
diff --git a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc index 9d53891a..e8e291c 100644 --- a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc +++ b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.cc
@@ -172,7 +172,8 @@ auto stroke_it = strokes_.find(tracking_id); if (stroke_it == strokes_.end()) { - LOG(DFATAL) << "No stroke found, continue."; + // TODO(crbug.com/1256926): Work out why this is hit on long presses. + DVLOG(1) << "No stroke found, continue."; continue; }
diff --git a/ui/events/platform/platform_event_source.cc b/ui/events/platform/platform_event_source.cc index b3dc00c..9b77c43 100644 --- a/ui/events/platform/platform_event_source.cc +++ b/ui/events/platform/platform_event_source.cc
@@ -64,6 +64,8 @@ OnDispatcherListChanged(); } +void PlatformEventSource::StopProcessingEventsForTesting() {} + std::unique_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher( PlatformEventDispatcher* dispatcher) { CHECK(dispatcher);
diff --git a/ui/events/platform/platform_event_source.h b/ui/events/platform/platform_event_source.h index ca6560fb..ca7307c 100644 --- a/ui/events/platform/platform_event_source.h +++ b/ui/events/platform/platform_event_source.h
@@ -72,6 +72,9 @@ void AddPlatformEventObserver(PlatformEventObserver* observer); void RemovePlatformEventObserver(PlatformEventObserver* observer); + // This method will synchronously stop event processing. + virtual void StopProcessingEventsForTesting(); + // Creates PlatformEventSource and sets it as a thread-local singleton. static std::unique_ptr<PlatformEventSource> CreateDefault();
diff --git a/ui/file_manager/file_manager/BUILD.gn b/ui/file_manager/file_manager/BUILD.gn index 3d9ab6a..bfccfbbc 100644 --- a/ui/file_manager/file_manager/BUILD.gn +++ b/ui/file_manager/file_manager/BUILD.gn
@@ -65,57 +65,30 @@ "foreground/css/tree.css", # Images: - "foreground/images/common/check_no_box.png", - "foreground/images/common/2x/check_no_box.png", "foreground/images/common/dragger.svg", "foreground/images/common/ic_close.svg", "foreground/images/common/ic_selected.svg", - "foreground/images/files/ui/2x/person_add.png", - "foreground/images/files/ui/2x/search.png", - "foreground/images/files/ui/2x/service_drive.png", "foreground/images/files/ui/arrow_right.svg", "foreground/images/files/ui/back.svg", "foreground/images/files/ui/state_banner_icon.svg", "foreground/images/files/ui/warning_banner_icon.svg", - "foreground/images/files/ui/cloud_import_syncing.png", - "foreground/images/files/ui/2x/cloud_import_syncing.png", + "foreground/images/files/ui/cloud_import_syncing.svg", "foreground/images/files/ui/delete.svg", "foreground/images/files/ui/delete_ng.svg", "foreground/images/files/ui/drive_logo.svg", "foreground/images/files/ui/drive_offline_icon.svg", "foreground/images/files/ui/photos_logo.svg", "foreground/images/files/ui/external_link.svg", - "foreground/images/files/ui/filetype_placeholder_audio.png", - "foreground/images/files/ui/2x/filetype_placeholder_audio.png", - "foreground/images/files/ui/filetype_placeholder_generic.png", - "foreground/images/files/ui/2x/filetype_placeholder_generic.png", "foreground/images/files/ui/filetype_placeholder_generic.svg", - "foreground/images/files/ui/filetype_placeholder_image.png", - "foreground/images/files/ui/2x/filetype_placeholder_image.png", - "foreground/images/files/ui/filetype_placeholder_video.png", - "foreground/images/files/ui/2x/filetype_placeholder_video.png", "foreground/images/files/ui/holding_space_welcome_image.svg", "foreground/images/files/ui/info.svg", "foreground/images/files/ui/list_check.svg", "foreground/images/files/ui/menu_ng.svg", "foreground/images/files/ui/offline.svg", - "foreground/images/files/ui/person_add.png", - "foreground/images/files/ui/quick_view/filetype_audio.png", - "foreground/images/files/ui/quick_view/2x/filetype_audio.png", - "foreground/images/files/ui/quick_view/filetype_folder.png", - "foreground/images/files/ui/quick_view/2x/filetype_folder.png", - "foreground/images/files/ui/quick_view/filetype_generic.png", - "foreground/images/files/ui/quick_view/2x/filetype_generic.png", - "foreground/images/files/ui/quick_view/filetype_image.png", - "foreground/images/files/ui/quick_view/2x/filetype_image.png", - "foreground/images/files/ui/quick_view/filetype_video.png", - "foreground/images/files/ui/quick_view/2x/filetype_video.png", "foreground/images/files/ui/refresh.svg", "foreground/images/files/ui/restore.svg", - "foreground/images/files/ui/search.png", "foreground/images/files/ui/search.svg", "foreground/images/files/ui/search_clear_filled.svg", - "foreground/images/files/ui/service_drive.png", "foreground/images/files/ui/share_ng.svg", "foreground/images/files/ui/sort_desc.svg", "foreground/images/files/ui/sorting_ng.svg",
diff --git a/ui/file_manager/file_manager/common/js/api.js b/ui/file_manager/file_manager/common/js/api.js index 80e2313..fd1f950 100644 --- a/ui/file_manager/file_manager/common/js/api.js +++ b/ui/file_manager/file_manager/common/js/api.js
@@ -57,3 +57,76 @@ export async function getPreferences() { return promisify(chrome.fileManagerPrivate.getPreferences); } + +/** + * @param {!DirectoryEntry} parentEntry + * @param {string} name + * @return {!Promise<boolean>} True if valid, else throws. + */ +export async function validatePathNameLength(parentEntry, name) { + return promisify( + chrome.fileManagerPrivate.validatePathNameLength, parentEntry, name); +} + + +/* + * FileSystemEntry helpers + */ + +/** + * @param {!Entry} entry + * @return {!Promise<!DirectoryEntry>} + */ +export async function getParentEntry(entry) { + return new Promise((resolve, reject) => { + entry.getParent(resolve, reject); + }); +} + +/** + * @param {!Entry} entry + * @param {!DirectoryEntry} parent + * @param {string} newName + * @return {!Promise<!Entry>} + */ +export async function moveEntryTo(entry, parent, newName) { + return new Promise((resolve, reject) => { + entry.moveTo(parent, newName, resolve, reject); + }); +} + +/** + * @param {!DirectoryEntry} directory + * @param {string} filename + * @param {!Object=} options + * @return {!Promise<!FileEntry>} + */ +export async function getFile(directory, filename, options) { + return new Promise((resolve, reject) => { + directory.getFile(filename, options, resolve, reject); + }); +} + +/** + * @param {!DirectoryEntry} directory + * @param {string} filename + * @param {!Object=} options + * @return {!Promise<!DirectoryEntry>} + */ +export async function getDirectory(directory, filename, options) { + return new Promise((resolve, reject) => { + directory.getDirectory(filename, options, resolve, reject); + }); +} + +/** + * @param {!DirectoryEntry} directory + * @param {string} filename + * @param {boolean} isFile Whether to retrieve a file or a directory. + * @param {!Object=} options + * @return {!Promise<!Entry>} + */ +export async function getEntry(directory, filename, isFile, options) { + const getEntry = isFile ? getFile : getDirectory; + return getEntry(directory, filename, options); +}
diff --git a/ui/file_manager/file_manager/foreground/css/common.css b/ui/file_manager/file_manager/foreground/css/common.css index e7f33b6..699858cd 100644 --- a/ui/file_manager/file_manager/foreground/css/common.css +++ b/ui/file_manager/file_manager/foreground/css/common.css
@@ -114,10 +114,19 @@ display: none; } -cr-menu.chrome-menu > cr-menu-item[checked] { - background-image: -webkit-image-set( - url(../images/common/check_no_box.png) 1x, - url(../images/common/2x/check_no_box.png) 2x); +cr-menu.chrome-menu > cr-menu-item[checked]::after { + -webkit-mask-image: url(../images/common/ic_selected.svg); + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + background-color: var(--cros-icon-color-prominent); + content: ''; + float: right; + height: 32px; + width: 20px; +} + +html[dir='rtl'] cr-menu.chrome-menu > cr-menu-item[checked]::after { + float: left; } cr-menu.chrome-menu > [checked]::before { @@ -178,9 +187,7 @@ } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok:hover { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(rgba(0 0 0 / 8%), rgba(0 0 0 / 8%)), - var(--cros-button-background-color-primary); + background: var(--cros-button-background-color-primary-hover-preblended); } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok:active {
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 033df762..8c7693a 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -533,10 +533,7 @@ } .dialog-header.files-ng button[menu-shown] { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } .dialog-header.files-ng button:not([menu-shown]):not(:active):hover { @@ -549,10 +546,7 @@ } .dialog-header.files-ng button:active { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } html.focus-outline-visible .dialog-header.files-ng cr-button:not(:active):focus, @@ -1192,9 +1186,7 @@ } .dialog-footer .primary:hover { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(rgba(0 0 0 / 8%), rgba(0 0 0 / 8%)), - var(--cros-button-background-color-primary); + background: var(--cros-button-background-color-primary-hover-preblended); } .dialog-footer .primary paper-ripple { @@ -1796,16 +1788,12 @@ } .copied .badge { - background-image: -webkit-image-set( - url(../images/files/ui/cloud_import_syncing.png) 1x, - url(../images/files/ui/2x/cloud_import_syncing.png) 2x); + background-image: url(../images/files/ui/cloud_import_syncing.svg); display: block; } .imported .badge { - background-image: -webkit-image-set( - url(../images/files/ui/service_drive.png) 1x, - url(../images/files/ui/2x/service_drive.png) 2x); + background-image: url(../images/volumes/service_drive.svg); display: block; } @@ -2433,10 +2421,7 @@ } .table-header-label .sort-icon:active { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } html:not(.pointer-active) .table-header-label .sort-icon:hover, @@ -2519,10 +2504,7 @@ } .table-header-splitter .splitter-icon:active { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } html:not(.pointer-active) .table-header-splitter .splitter-icon:hover { @@ -2683,9 +2665,10 @@ } list.autocomplete-suggestions > li > div[search-icon] { - background: -webkit-image-set( - url(../images/files/ui/search.png) 1x, - url(../images/files/ui/2x/search.png) 2x) center no-repeat; + -webkit-mask-image: url(../images/files/ui/search.svg); + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + background-color: var(--cros-menu-icon-color); } list.autocomplete-suggestions > [selected],
diff --git a/ui/file_manager/file_manager/foreground/css/file_status.css b/ui/file_manager/file_manager/foreground/css/file_status.css index 0684c74..55561398 100644 --- a/ui/file_manager/file_manager/foreground/css/file_status.css +++ b/ui/file_manager/file_manager/foreground/css/file_status.css
@@ -4,24 +4,22 @@ /* Small icons for file statuses, used in lists and menus. */ [file-status-icon] { - background-image: none; - background-position: right center; - background-repeat: no-repeat; - background-size: 16px 16px; + -webkit-mask-image: none; + -webkit-mask-position: right center; + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: 16px 16px; } html[dir='rtl'] [file-status-icon] { - background-position: left center; + -webkit-mask-position: left center; } [file-status-icon='copied'] { - background-image: -webkit-image-set( - url(../images/files/ui/cloud_import_syncing.png) 1x, - url(../images/files/ui/2x/cloud_import_syncing.png) 2x); + -webkit-mask-image: url(../images/files/ui/cloud_import_syncing.svg); + background-color: currentColor; } [file-status-icon='imported'] { - background-image: -webkit-image-set( - url(../images/files/ui/service_drive.png) 1x, - url(../images/files/ui/2x/service_drive.png) 2x); + -webkit-mask-image: url(../images/volumes/service_drive.svg); + background-color: currentColor; }
diff --git a/ui/file_manager/file_manager/foreground/css/file_types.css b/ui/file_manager/file_manager/foreground/css/file_types.css index 33efdd4..6236b4f 100644 --- a/ui/file_manager/file_manager/foreground/css/file_types.css +++ b/ui/file_manager/file_manager/foreground/css/file_types.css
@@ -138,52 +138,27 @@ } /* Large generic thumbnails, used when a file does not have a thumbnail. */ -[generic-thumbnail] { - background-image: -webkit-image-set( - url(../images/files/ui/filetype_placeholder_generic.png) 1x, - url(../images/files/ui/2x/filetype_placeholder_generic.png) 2x); - background-position: center 50px; - background-repeat: no-repeat; -} - -body.files-ng .no-thumbnail[generic-thumbnail] { +.no-thumbnail[generic-thumbnail] { -webkit-mask-position: center; -webkit-mask-repeat: no-repeat; -webkit-mask-size: 48px; background-color: transparent; background-image: url(../images/files/ui/filetype_placeholder_generic.svg); background-position: center; + background-repeat: no-repeat; background-size: 48px; } -[generic-thumbnail='audio'] { - background-image: -webkit-image-set( - url(../images/files/ui/filetype_placeholder_audio.png) 1x, - url(../images/files/ui/2x/filetype_placeholder_audio.png) 2x); -} - -body.files-ng .no-thumbnail[generic-thumbnail='audio'] { +.no-thumbnail[generic-thumbnail='audio'] { background-image: url(../images/filetype/filetype_audio.svg); } -[generic-thumbnail='image'] { - background-image: -webkit-image-set( - url(../images/files/ui/filetype_placeholder_image.png) 1x, - url(../images/files/ui/2x/filetype_placeholder_image.png) 2x); -} - -body.files-ng .no-thumbnail[generic-thumbnail='image'], -body.files-ng .no-thumbnail[generic-thumbnail='raw'] { +.no-thumbnail[generic-thumbnail='image'], +.no-thumbnail[generic-thumbnail='raw'] { background-image: url(../images/filetype/filetype_image.svg); } -[generic-thumbnail='video'] { - background-image: -webkit-image-set( - url(../images/files/ui/filetype_placeholder_video.png) 1x, - url(../images/files/ui/2x/filetype_placeholder_video.png) 2x); -} - -body.files-ng .no-thumbnail[generic-thumbnail='video'] { +.no-thumbnail[generic-thumbnail='video'] { background-image: url(../images/filetype/filetype_video.svg); } @@ -417,5 +392,3 @@ .tree-row > .file-row > [volume-type-icon='trash'] { -webkit-mask-image: url(../images/files/ui/delete_ng.svg); } - -
diff --git a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js index 3de56cd..2fd49663 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js +++ b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js
@@ -60,14 +60,14 @@ }, /** @private */ - format_: async function() { + format_: function() { try { - await validateExternalDriveName( + validateExternalDriveName( this.label_, /** @type {!VolumeManagerCommon.FileSystemType} */ (this.formatType_)); - } catch (errorMessage) { - this.$.label.setAttribute('error-message', errorMessage); + } catch (error) { + this.$.label.setAttribute('error-message', error.message); this.$.label.invalid = true; return; }
diff --git a/ui/file_manager/file_manager/foreground/elements/files_password_dialog.html b/ui/file_manager/file_manager/foreground/elements/files_password_dialog.html index cf72984..b8b12df0 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_password_dialog.html +++ b/ui/file_manager/file_manager/foreground/elements/files_password_dialog.html
@@ -53,9 +53,7 @@ --disabled-border-color: var(--cros-button-stroke-color-secondary-disabled); --disabled-text-color: var(--cros-button-label-color-secondary-disabled); - /* TODO(crbug.com/1275388): use blend() instead */ - --hover-bg-action: linear-gradient(rgba(0 0 0 / 8%), rgba(0 0 0 / 8%)), - var(--cros-button-background-color-primary); + --hover-bg-action: var(--cros-button-background-color-primary-hover-preblended); --hover-bg-color: var(--cros-button-background-color-secondary-hover); --hover-border-color: var(--cros-button-stroke-color-secondary-hover); --ink-color: var(--cros-button-ripple-color-secondary);
diff --git a/ui/file_manager/file_manager/foreground/elements/files_quick_view.css b/ui/file_manager/file_manager/foreground/elements/files_quick_view.css index a15f647..ce67accc 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_quick_view.css +++ b/ui/file_manager/file_manager/foreground/elements/files_quick_view.css
@@ -267,36 +267,37 @@ /* Large generic thumbnails, used when a file does not have a thumbnail. */ [generic-thumbnail] { - background: -webkit-image-set( - url(../images/files/ui/quick_view/filetype_generic.png) 1x, - url(../images/files/ui/quick_view/2x/filetype_generic.png) 2x) - center - no-repeat; + -webkit-mask-image: url(../images/filetype/filetype_generic.svg); + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: auto 88px; + background-color: currentColor; + background-position: center; + background-repeat: no-repeat; + background-size: auto 88px; height: 88px; } [generic-thumbnail='.folder'] { - background-image: -webkit-image-set( - url(../images/files/ui/quick_view/filetype_folder.png) 1x, - url(../images/files/ui/quick_view/2x/filetype_folder.png) 2x); - height: 72px; + -webkit-mask-image: url(../images/filetype/filetype_folder.svg); + -webkit-mask-size: auto 72px; } [generic-thumbnail='audio'] { - background-image: -webkit-image-set( - url(../images/files/ui/quick_view/filetype_audio.png) 1x, - url(../images/files/ui/quick_view/2x/filetype_audio.png) 2x); + -webkit-mask-image: none; + background-color: transparent; + background-image: url(../images/filetype/filetype_audio.svg); } [generic-thumbnail='image'] { - background-image: -webkit-image-set( - url(../images/files/ui/quick_view/filetype_image.png) 1x, - url(../images/files/ui/quick_view/2x/filetype_image.png) 2x); + -webkit-mask-image: none; + background-color: transparent; + background-image: url(../images/filetype/filetype_image.svg); } [generic-thumbnail='video'] { - background-image: -webkit-image-set( - url(../images/files/ui/quick_view/filetype_video.png) 1x, - url(../images/files/ui/quick_view/2x/filetype_video.png) 2x); - height: 72px; + -webkit-mask-image: none; + background-color: transparent; + background-image: url(../images/filetype/filetype_video.svg); + background-size: auto 72px; }
diff --git a/ui/file_manager/file_manager/foreground/elements/xf_button.html b/ui/file_manager/file_manager/foreground/elements/xf_button.html index 975951d..b0faa56c 100644 --- a/ui/file_manager/file_manager/foreground/elements/xf_button.html +++ b/ui/file_manager/file_manager/foreground/elements/xf_button.html
@@ -20,10 +20,7 @@ } cr-icon-button { - /* TODO(crbug.com/1275388): use blend() instead */ - --cr-active-bg-color: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + --cr-active-bg-color: var(--cros-icon-button-pressed-color); --cr-focus-outline-color: var(--cros-focus-ring-color); --cr-hover-background-color: var(--cros-ripple-color); --cr-icon-button-fill-color: var(--cros-icon-color-primary);
diff --git a/ui/file_manager/file_manager/foreground/images/common/2x/check_no_box.png b/ui/file_manager/file_manager/foreground/images/common/2x/check_no_box.png deleted file mode 100644 index 284d93d..0000000 --- a/ui/file_manager/file_manager/foreground/images/common/2x/check_no_box.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/common/check_no_box.png b/ui/file_manager/file_manager/foreground/images/common/check_no_box.png deleted file mode 100644 index ab43376..0000000 --- a/ui/file_manager/file_manager/foreground/images/common/check_no_box.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/cloud_import_syncing.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/cloud_import_syncing.png deleted file mode 100644 index 136bedf2..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/cloud_import_syncing.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_audio.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_audio.png deleted file mode 100644 index df491a9..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_generic.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_generic.png deleted file mode 100644 index c24bb37..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_image.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_image.png deleted file mode 100644 index a2c3d953..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_video.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_video.png deleted file mode 100644 index 03af2fe9..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/filetype_placeholder_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/person_add.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/person_add.png deleted file mode 100644 index 428b660..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/person_add.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/search.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/search.png deleted file mode 100644 index 71b947803..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/search.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/service_drive.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/service_drive.png deleted file mode 100644 index 99a2cdb..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/2x/service_drive.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/cloud_import_syncing.png b/ui/file_manager/file_manager/foreground/images/files/ui/cloud_import_syncing.png deleted file mode 100644 index a48c94e..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/cloud_import_syncing.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_audio.png b/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_audio.png deleted file mode 100644 index d3986cb..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_generic.png b/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_generic.png deleted file mode 100644 index 54997bbe..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_image.png b/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_image.png deleted file mode 100644 index 62f6c8b..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_video.png b/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_video.png deleted file mode 100644 index fadda62..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/filetype_placeholder_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/person_add.png b/ui/file_manager/file_manager/foreground/images/files/ui/person_add.png deleted file mode 100644 index 623e20f..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/person_add.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_audio.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_audio.png deleted file mode 100644 index 07144bbc..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_folder.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_folder.png deleted file mode 100644 index f51f09b0..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_generic.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_generic.png deleted file mode 100644 index 95816db7..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_image.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_image.png deleted file mode 100644 index a7babfa..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_video.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_video.png deleted file mode 100644 index 4801f96..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/2x/filetype_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_audio.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_audio.png deleted file mode 100644 index 0a7475a..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_folder.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_folder.png deleted file mode 100644 index 0bd363c2..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_generic.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_generic.png deleted file mode 100644 index 84af4545..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_image.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_image.png deleted file mode 100644 index 2872723..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_video.png b/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_video.png deleted file mode 100644 index b85d6d3..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/quick_view/filetype_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/search.png b/ui/file_manager/file_manager/foreground/images/files/ui/search.png deleted file mode 100644 index b38c40b9..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/search.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/service_drive.png b/ui/file_manager/file_manager/foreground/images/files/ui/service_drive.png deleted file mode 100644 index 88a5260..0000000 --- a/ui/file_manager/file_manager/foreground/images/files/ui/service_drive.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index 4682f3c2..3abeceaa 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -455,6 +455,7 @@ deps = [ ":directory_model", "ui:directory_tree", + "//ui/file_manager/file_manager/common/js:api", "//ui/file_manager/file_manager/common/js:util", "//ui/file_manager/file_manager/externs:volume_info", "//ui/file_manager/file_manager/foreground/js:file_rename", @@ -603,6 +604,7 @@ js_library("file_rename") { deps = [ + "//ui/file_manager/file_manager/common/js:api", "//ui/file_manager/file_manager/common/js:util", "//ui/file_manager/file_manager/common/js:volume_manager_types", ] @@ -1005,6 +1007,7 @@ ":directory_model", ":file_selection", "ui:list_container", + "//ui/file_manager/file_manager/common/js:api", "//ui/file_manager/file_manager/common/js:util", "//ui/file_manager/file_manager/foreground/js:file_rename", "//ui/webui/resources/js:assert.m",
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js index cfbd8516..ac19c24 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -107,7 +107,7 @@ /** * @private */ - processOKActionForSaveDialog_() { + async processOKActionForSaveDialog_() { const selection = this.fileSelectionHandler_.selection; // If OK action is clicked when a directory is selected, open the directory. @@ -125,21 +125,18 @@ throw new Error('Missing filename!'); } - this.namingController_.validateFileNameForSaving(filename) - .then(url => { - // TODO(mtomasz): Clean this up by avoiding constructing a URL - // via string concatenation. - this.selectFilesAndClose_({ - urls: [url], - multiple: false, - filterIndex: this.dialogFooter_.selectedFilterIndex - }); - }) - .catch(error => { - if (error instanceof Error) { - console.error(error.stack && error); - } - }); + try { + const url = + await this.namingController_.validateFileNameForSaving(filename); + + this.selectFilesAndClose_({ + urls: [url], + multiple: false, + filterIndex: this.dialogFooter_.selectedFilterIndex + }); + } catch (error) { + console.error(error); + } } /**
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js index 772a3da..f0a4c59f 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -967,52 +967,51 @@ * * @param {!Entry} oldEntry The old entry. * @param {!Entry} newEntry The new entry. - * @param {function()=} opt_callback Called on completion. + * @return {!Promise<void>} Resolves on completion. */ - onRenameEntry(oldEntry, newEntry, opt_callback) { - this.currentDirContents_.prefetchMetadata([newEntry], true, () => { - // If the current directory is the old entry, then quietly change to the - // new one. - if (util.isSameEntry(oldEntry, this.getCurrentDirEntry())) { - this.changeDirectoryEntry( - /** @type {!DirectoryEntry|!FilesAppDirEntry} */ (newEntry)); - } - - // Replace the old item with the new item. oldEntry instance itself may - // have been removed/replaced from the list during the async process, we - // find an entry which should be replaced by checking toURL(). - const list = this.getFileList(); - let oldEntryExist = false; - let newEntryExist = false; - const oldEntryUrl = oldEntry.toURL(); - const newEntryUrl = newEntry.toURL(); - - for (let i = 0; i < list.length; i++) { - const item = list.item(i); - const url = item.toURL(); - if (url === oldEntryUrl) { - list.replaceItem(item, newEntry); - oldEntryExist = true; - break; + onRenameEntry(oldEntry, newEntry) { + return new Promise(resolve => { + this.currentDirContents_.prefetchMetadata([newEntry], true, () => { + // If the current directory is the old entry, then quietly change to the + // new one. + if (util.isSameEntry(oldEntry, this.getCurrentDirEntry())) { + this.changeDirectoryEntry( + /** @type {!DirectoryEntry|!FilesAppDirEntry} */ (newEntry)); } - if (url === newEntryUrl) { - newEntryExist = true; + // Replace the old item with the new item. oldEntry instance itself may + // have been removed/replaced from the list during the async process, we + // find an entry which should be replaced by checking toURL(). + const list = this.getFileList(); + let oldEntryExist = false; + let newEntryExist = false; + const oldEntryUrl = oldEntry.toURL(); + const newEntryUrl = newEntry.toURL(); + + for (let i = 0; i < list.length; i++) { + const item = list.item(i); + const url = item.toURL(); + if (url === oldEntryUrl) { + list.replaceItem(item, newEntry); + oldEntryExist = true; + break; + } + + if (url === newEntryUrl) { + newEntryExist = true; + } } - } - // When both old and new entries don't exist, it may be in the middle of - // update process. In DirectoryContent.update deletion is executed at - // first and insertion is executed as a async call. There is a chance that - // this method is called in the middle of update process. - if (!oldEntryExist && !newEntryExist) { - list.push(newEntry); - } + // When both old and new entries don't exist, it may be in the middle of + // update process. In DirectoryContent.update deletion is executed at + // first and insertion is executed as a async call. There is a chance + // that this method is called in the middle of update process. + if (!oldEntryExist && !newEntryExist) { + list.push(newEntry); + } - // Run callback, finally. - if (opt_callback) { - opt_callback(); - } + resolve(); + }); }); }
diff --git a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js index 7b65434..5fe5a92 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js
@@ -4,6 +4,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {AlertDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; +import {getParentEntry} from '../../common/js/api.js'; import {util} from '../../common/js/util.js'; import {VolumeInfo} from '../../externs/volume_info.js'; @@ -37,7 +38,11 @@ /** @private {boolean} */ this.editing_ = false; - /** @private {boolean} */ + /** + * Whether the entry being renamed is a root of a removable + * partition/volume. + * @private {boolean} + */ this.isRemovableRoot_ = false; /** @private {?VolumeInfo} */ @@ -80,9 +85,9 @@ * Attaches naming controller to specified directory item and start rename. * @param {!DirectoryItem} directoryItem An html element of a node of the * target. - * @param {boolean} isRemovableRoot Indicates whether the target is removable - * node or not. - * @param {VolumeInfo} volumeInfo A volume information about the target node. + * @param {boolean} isRemovableRoot Indicates whether the target is a + * removable volume root or not. + * @param {VolumeInfo} volumeInfo A volume information about the target entry. * |volumeInfo| can be null if method is invoked on a folder that is in * the tree view and is not root of an external drive. */ @@ -119,7 +124,7 @@ * Commits rename. * @private */ - commitRename_() { + async commitRename_() { const contextMenu = this.inputElement_.contextMenu; if (!this.editing_ || (contextMenu && !contextMenu.hidden)) { return; @@ -135,32 +140,22 @@ return; } - if (this.isRemovableRoot_) { - // Validate new name. - validateExternalDriveName( - newName, - assert(this.volumeInfo_ && this.volumeInfo_.diskFileSystemType)) - .then( - this.performExternalDriveRename_.bind(this, entry, newName), - errorMessage => { - this.alertDialog_.show( - /** @type {string} */ (errorMessage), - this.detach_.bind(this)); - }); - } else { - // Validate new name. - new Promise(entry.getParent.bind(entry)) - .then(parentEntry => { - return validateFileName( - parentEntry, newName, - !this.directoryModel_.getFileFilter().isHiddenFilesVisible()); - }) - .then( - this.performRename_.bind(this, entry, newName), errorMessage => { - this.alertDialog_.show( - /** @type {string} */ (errorMessage), - this.detach_.bind(this)); - }); + try { + if (this.isRemovableRoot_) { + validateExternalDriveName( + newName, + assert(this.volumeInfo_ && this.volumeInfo_.diskFileSystemType)); + this.performExternalDriveRename_(entry, newName); + return; + } + const parentEntry = await getParentEntry(entry); + await validateFileName( + parentEntry, newName, + this.directoryModel_.getFileFilter().isHiddenFilesVisible()); + await this.performRename_(entry, newName); + } catch (error) { + this.alertDialog_.show( + /** @type {string} */ (error.message), this.detach_.bind(this)); } } @@ -170,7 +165,7 @@ * @param {string} newName Validated name. * @private */ - performRename_(entry, newName) { + async performRename_(entry, newName) { const renamingCurrentDirectory = util.isSameEntry(entry, this.directoryModel_.getCurrentDirEntry()); if (renamingCurrentDirectory) { @@ -180,36 +175,32 @@ // TODO(yawano): Rename might take time on some volumes. Optimistically show // new name in the UI before actual rename is completed. - new Promise(renameEntry.bind(null, entry, newName)) - .then( - newEntry => { - // Put the new name in the .label element before detaching the - // <input> to prevent showing the old name. - this.getLabelElement_().textContent = newName; + try { + const newEntry = await renameEntry(entry, newName); - this.currentDirectoryItem_.entry = newEntry; - this.currentDirectoryItem_.updateSubDirectories( - true /* recursive */); + // Put the new name in the .label element before detaching the + // <input> to prevent showing the old name. + this.getLabelElement_().textContent = newName; - this.detach_(); + this.currentDirectoryItem_.entry = newEntry; + this.currentDirectoryItem_.updateSubDirectories(/* recursive= */ true); - // If renamed directory was current directory, change it to new - // one. - if (renamingCurrentDirectory) { - this.directoryModel_.changeDirectoryEntry( - newEntry, - this.directoryModel_.setIgnoringCurrentDirectoryDeletion - .bind(this.directoryModel_, false /* not ignore */)); - } - }, - error => { - this.directoryModel_.setIgnoringCurrentDirectoryDeletion( - false /* not ignore */); - this.detach_(); + // If renamed directory was current directory, change it to new one. + if (renamingCurrentDirectory) { + this.directoryModel_.changeDirectoryEntry( + /** @type {!DirectoryEntry} */ (newEntry), + this.directoryModel_.setIgnoringCurrentDirectoryDeletion.bind( + this.directoryModel_, /* ignore= */ false)); + } + } catch (error) { + this.directoryModel_.setIgnoringCurrentDirectoryDeletion( + /* ignore= */ false); - this.alertDialog_.show(getRenameErrorMessage( - /** @type {DOMError} */ (error), entry, newName)); - }); + this.alertDialog_.show(getRenameErrorMessage( + /** @type {DOMError} */ (error), entry, newName)); + } + + this.detach_(); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 6545d89..7e45ce1f 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1531,20 +1531,18 @@ if (util.isNonModifiable(fileManager.volumeManager, entry)) { return; } + let isRemovableRoot = false; + let volumeInfo = null; + if (entry) { + volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); + // Checks whether the target is an external drive. + if (volumeInfo && + CommandUtil.isRootEntry(fileManager.volumeManager, entry)) { + isRemovableRoot = true; + } + } if (event.target instanceof DirectoryTree || event.target instanceof DirectoryItem) { - let isRemovableRoot = false; - let volumeInfo = null; - if (entry) { - volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); - // Checks whether the target is actually external drive or just a folder - // inside the drive. - if (volumeInfo && - CommandUtil.isRootEntry(fileManager.volumeManager, entry)) { - isRemovableRoot = true; - } - } - if (event.target instanceof DirectoryTree) { const directoryTree = event.target; assert(fileManager.directoryTreeNamingController) @@ -1557,7 +1555,7 @@ .attachAndStart(directoryItem, isRemovableRoot, volumeInfo); } } else { - fileManager.namingController.initiateRename(); + fileManager.namingController.initiateRename(isRemovableRoot, volumeInfo); } }
diff --git a/ui/file_manager/file_manager/foreground/js/file_rename.js b/ui/file_manager/file_manager/foreground/js/file_rename.js index 2fcc03a..a75abfe 100644 --- a/ui/file_manager/file_manager/foreground/js/file_rename.js +++ b/ui/file_manager/file_manager/foreground/js/file_rename.js
@@ -7,47 +7,39 @@ * by the files app frontend. */ +import {getEntry, getParentEntry, moveEntryTo, validatePathNameLength} from '../../common/js/api.js'; import {str, strf, util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; /** * Renames the entry to newName. - * @param {Entry} entry The entry to be renamed. + * @param {!Entry} entry The entry to be renamed. * @param {string} newName The new name. - * @param {function(Entry)} successCallback Callback invoked when the rename - * is successfully done. - * @param {function(DOMError)} errorCallback Callback invoked when an error - * is found. + * @return {Promise<!Entry>} The renamed entry. */ -export function renameEntry(entry, newName, successCallback, errorCallback) { - entry.getParent(parentEntry => { - const parent = /** @type {!DirectoryEntry} */ (parentEntry); +export async function renameEntry(entry, newName) { + // Before moving, we need to check if there is an existing entry at + // parent/newName, since moveTo will overwrite it. + // Note that this way has some timing issue. After existing check, + // a new entry may be created in the background. However, there is no way not + // to overwrite the existing file, unfortunately. The risk should be low, + // assuming the unsafe period is very short. - // Before moving, we need to check if there is an existing entry at - // parent/newName, since moveTo will overwrite it. - // Note that this way has some timing issue. After existing check, - // a new entry may be create on background. However, there is no way not to - // overwrite the existing file, unfortunately. The risk should be low, - // assuming the unsafe period is very short. - (entry.isFile ? parent.getFile : parent.getDirectory) - .call( - parent, newName, {create: false}, - entry => { - // The entry with the name already exists. - errorCallback( - util.createDOMError(util.FileError.PATH_EXISTS_ERR)); - }, - error => { - if (error.name != util.FileError.NOT_FOUND_ERR) { - // Unexpected error is found. - errorCallback(error); - return; - } + const parent = await getParentEntry(entry); - // No existing entry is found. - entry.moveTo(parent, newName, successCallback, errorCallback); - }); - }, errorCallback); + try { + await getEntry(parent, newName, entry.isFile, {create: false}); + } catch (error) { + if (error.name == util.FileError.NOT_FOUND_ERR) { + return moveEntryTo(entry, parent, newName); + } + + // Unexpected error found. + throw error; + } + + // The entry with the name already exists. + throw util.createDOMError(util.FileError.PATH_EXISTS_ERR); } /** @@ -93,35 +85,33 @@ * * @param {!DirectoryEntry} parentEntry The entry of the parent directory. * @param {string} name New file or folder name. - * @param {boolean} filterHiddenOn Whether to report the hidden file name error - * or not. - * @return {Promise} Promise fulfilled on success, or rejected with the error - * message. + * @param {boolean} areHiddenFilesVisible Whether to report the hidden file name + * error or not. + * @return {Promise} Fulfills on success, throws error message otherwise. */ -export function validateFileName(parentEntry, name, filterHiddenOn) { +export async function validateFileName( + parentEntry, name, areHiddenFilesVisible) { const testResult = /[\/\\\<\>\:\?\*\"\|]/.exec(name); if (testResult) { - return Promise.reject(strf('ERROR_INVALID_CHARACTER', testResult[0])); - } else if (/^\s*$/i.test(name)) { - return Promise.reject(str('ERROR_WHITESPACE_NAME')); - } else if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) { - return Promise.reject(str('ERROR_RESERVED_NAME')); - } else if (filterHiddenOn && /\.crdownload$/i.test(name)) { - return Promise.reject(str('ERROR_RESERVED_NAME')); - } else if (filterHiddenOn && name[0] == '.') { - return Promise.reject(str('ERROR_HIDDEN_NAME')); + throw Error(strf('ERROR_INVALID_CHARACTER', testResult[0])); + } + if (/^\s*$/i.test(name)) { + throw Error(str('ERROR_WHITESPACE_NAME')); + } + if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) { + throw Error(str('ERROR_RESERVED_NAME')); + } + if (!areHiddenFilesVisible && /\.crdownload$/i.test(name)) { + throw Error(str('ERROR_RESERVED_NAME')); + } + if (!areHiddenFilesVisible && name[0] == '.') { + throw Error(str('ERROR_HIDDEN_NAME')); } - return new Promise((fulfill, reject) => { - chrome.fileManagerPrivate.validatePathNameLength( - parentEntry, name, valid => { - if (valid) { - fulfill(null); - } else { - reject(str('ERROR_LONG_NAME')); - } - }); - }); + const isValid = await validatePathNameLength(parentEntry, name); + if (!isValid) { + throw Error(str('ERROR_LONG_NAME')); + } } /** @@ -131,10 +121,10 @@ * * It also verifies that name length is in the limits of the filesystem. * + * This function throws if the new label is invalid, else it completes. + * * @param {string} name New external drive name. * @param {!VolumeManagerCommon.FileSystemType} fileSystem - * @return {Promise} Promise fulfilled on success, or rejected with the error - * message. */ export function validateExternalDriveName(name, fileSystem) { // Verify if entered name for external drive respects restrictions provided by @@ -146,20 +136,17 @@ // Verify length for the target file system type if (lengthLimit.hasOwnProperty(fileSystem) && nameLength > lengthLimit[fileSystem]) { - return Promise.reject( + throw Error( strf('ERROR_EXTERNAL_DRIVE_LONG_NAME', lengthLimit[fileSystem])); } - // Checks if the name contains only alphanumeric characters or allowed special - // characters. This needs to stay in sync with cros-disks/filesystem_label.cc - // on the ChromeOS side. + // Checks if the name contains only alphanumeric characters or allowed + // special characters. This needs to stay in sync with + // cros-disks/filesystem_label.cc on the ChromeOS side. const validCharRegex = /[a-zA-Z0-9 \!\#\$\%\&\(\)\-\@\^\_\`\{\}\~]/; for (let i = 0; i < nameLength; i++) { if (!validCharRegex.test(name[i])) { - return Promise.reject( - strf('ERROR_EXTERNAL_DRIVE_INVALID_CHARACTER', name[i])); + throw Error(strf('ERROR_EXTERNAL_DRIVE_INVALID_CHARACTER', name[i])); } } - - return Promise.resolve(); }
diff --git a/ui/file_manager/file_manager/foreground/js/naming_controller.js b/ui/file_manager/file_manager/foreground/js/naming_controller.js index 80e624eaf..1058d0d 100644 --- a/ui/file_manager/file_manager/foreground/js/naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/naming_controller.js
@@ -4,12 +4,14 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {AlertDialog, ConfirmDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; +import {getFile} from '../../common/js/api.js'; import {strf, util} from '../../common/js/util.js'; +import {VolumeInfo} from '../../externs/volume_info.js'; import {FileFilter} from './directory_contents.js'; import {DirectoryModel} from './directory_model.js'; -import {getRenameErrorMessage, renameEntry, validateFileName} from './file_rename.js'; +import {getRenameErrorMessage, renameEntry, validateExternalDriveName, validateFileName} from './file_rename.js'; import {FileSelectionHandler} from './file_selection.js'; import {ListContainer} from './ui/list_container.js'; @@ -46,6 +48,16 @@ /** @private @const {!FileSelectionHandler} */ this.selectionHandler_ = selectionHandler; + /** + * Whether the entry being renamed is a root of a removable + * partition/volume. + * @private {boolean} + */ + this.isRemovableRoot_ = false; + + /** @private {?VolumeInfo} */ + this.volumeInfo_ = null; + // Register events. this.listContainer_.renameInput.addEventListener( 'keydown', this.onRenameInputKeyDown_.bind(this)); @@ -56,83 +68,74 @@ /** * Verifies the user entered name for file or folder to be created or * renamed to. See also validateFileName. + * Returns true immediately if the name is valid, else returns false + * after the user has dismissed the error dialog. * * @param {!DirectoryEntry} parentEntry The URL of the parent directory entry. * @param {string} name New file or folder name. - * @param {function(boolean)} onDone Function to invoke when user closes the - * warning box or immediately if file name is correct. If the name was - * valid it is passed true, and false otherwise. + * @return {!Promise<boolean>} True if valid. + * @private */ - validateFileName(parentEntry, name, onDone) { - const fileNameErrorPromise = validateFileName( - parentEntry, name, !this.fileFilter_.isHiddenFilesVisible()); - fileNameErrorPromise - .then( - onDone.bind(null, true), - message => { - this.alertDialog_.show( - /** @type {string} */ (message), onDone.bind(null, false)); - }) - .catch(error => { - console.error(error.stack || error); - }); + async validateFileName(parentEntry, name) { + try { + await validateFileName( + parentEntry, name, this.fileFilter_.isHiddenFilesVisible()); + } catch (error) { + await new Promise( + (resolve) => this.alertDialog_.show( + /** @type {string} */ (error), resolve)); + return false; + } + return true; } /** * @param {string} filename * @return {Promise<string>} */ - validateFileNameForSaving(filename) { + async validateFileNameForSaving(filename) { const directory = /** @type {DirectoryEntry} */ ( this.directoryModel_.getCurrentDirEntry()); const currentDirUrl = directory.toURL().replace(/\/?$/, '/'); const fileUrl = currentDirUrl + encodeURIComponent(filename); - return new Promise(this.validateFileName.bind(this, directory, filename)) - .then(isValid => { - if (!isValid) { - return Promise.reject('Invalid filename.'); - } + try { + const isValid = await this.validateFileName(directory, filename); + if (!isValid) { + throw 'Invalid filename.'; + } - if (directory && util.isFakeEntry(directory)) { - // Can't save a file into a fake directory. - return Promise.reject('Cannot save into fake entry.'); - } + if (directory && util.isFakeEntry(directory)) { + // Can't save a file into a fake directory. + throw 'Cannot save into fake entry.'; + } - return new Promise( - directory.getFile.bind(directory, filename, {create: false})); - }) - .then( - () => { - // An existing file is found. Show confirmation dialog to - // overwrite it. If the user select "OK" on the dialog, save it. - return new Promise((fulfill, reject) => { - this.confirmDialog_.show( - strf('CONFIRM_OVERWRITE_FILE', filename), - fulfill.bind(null, fileUrl), reject.bind(null, 'Cancelled'), - () => {}); - }); - }, - error => { - if (error.name == util.FileError.NOT_FOUND_ERR) { - // The file does not exist, so it should be ok to create a - // new file. - return fileUrl; - } + await getFile(directory, filename, {create: false}); + } catch (error) { + if (error.name == util.FileError.NOT_FOUND_ERR) { + // The file does not exist, so it should be ok to create a new file. + return fileUrl; + } - if (error.name == util.FileError.TYPE_MISMATCH_ERR) { - // An directory is found. - // Do not allow to overwrite directory. - this.alertDialog_.show( - strf('DIRECTORY_ALREADY_EXISTS', filename)); - return Promise.reject(error); - } + if (error.name == util.FileError.TYPE_MISMATCH_ERR) { + // A directory is found. Do not allow to overwrite directory. + this.alertDialog_.show(strf('DIRECTORY_ALREADY_EXISTS', filename)); + throw error; + } - // Unexpected error. - console.error('File save failed: ' + error.code); - return Promise.reject(error); - }); + // Unexpected error. + console.error('File save failed: ' + error.code); + throw error; + } + + // An existing file is found. Show confirmation dialog to overwrite it. + // If the user selects "OK", save it. + return new Promise((fulfill, reject) => { + this.confirmDialog_.show( + strf('CONFIRM_OVERWRITE_FILE', filename), fulfill.bind(null, fileUrl), + reject.bind(null, 'Cancelled')); + }); } /** @@ -142,7 +145,17 @@ return !!this.listContainer_.renameInput.currentEntry; } - initiateRename() { + /** + * @param {boolean} isRemovableRoot Indicates whether the target is a + * removable volume root or not. + * @param {VolumeInfo} volumeInfo A volume information about the target entry. + * |volumeInfo| can be null if method is invoked on a folder that is in + * the tree view and is not root of an external drive. + */ + initiateRename(isRemovableRoot = false, volumeInfo = null) { + this.isRemovableRoot_ = isRemovableRoot; + this.volumeInfo_ = this.isRemovableRoot_ ? assert(volumeInfo) : null; + const selectedIndex = this.listContainer_.selectionModel.selectedIndex; const item = this.listContainer_.currentList.getListItemByIndex(selectedIndex); @@ -251,8 +264,10 @@ /** * @private + * @return {!Promise} Resolves when done renaming - both when renaming is + * successful and when it fails. */ - commitRename_() { + async commitRename_() { const input = this.listContainer_.renameInput; const entry = input.currentEntry; const newName = input.value; @@ -265,66 +280,86 @@ return; } + const volumeInfo = this.volumeInfo_; + const isRemovableRoot = this.isRemovableRoot_; + let isValid = false; input.validation_ = true; - const validationDone = valid => { - input.validation_ = false; - if (!valid) { - // Cancel rename if it fails to restore focus from alert dialog. - // Otherwise, just cancel the commitment and continue to rename. - if (document.activeElement != input) { - this.cancelRename_(); - } - return; + if (isRemovableRoot) { + try { + const diskFileSystemType = + assert(volumeInfo && volumeInfo.diskFileSystemType); + validateExternalDriveName(newName, diskFileSystemType); + isValid = true; + } catch (error) { + isValid = false; + await new Promise( + (resolve) => this.alertDialog_.show( + /** @type {string} */ (error.message), resolve)); + } + } else { + // TODO(mtomasz): this.getCurrentDirectoryEntry() might not return the + // actual parent if the directory content is a search result. Fix it to do + // proper validation. + isValid = await this.validateFileName( + /** @type {!DirectoryEntry} */ ( + this.directoryModel_.getCurrentDirEntry()), + newName); + } + + input.validation_ = false; + + if (!isValid) { + // Cancel rename if it fails to restore focus from alert dialog. + // Otherwise, just cancel the commitment and continue to rename. + if (document.activeElement != input) { + this.cancelRename_(); + } + return; + } + + // Validation succeeded. Do renaming. + this.listContainer_.renameInput.currentEntry = null; + if (this.listContainer_.renameInput.parentNode) { + this.listContainer_.renameInput.parentNode.removeChild( + this.listContainer_.renameInput); + } + + // Optimistically apply new name immediately to avoid flickering in + // case of success. + nameNode.textContent = newName; + + try { + let newEntry; + if (isRemovableRoot) { + newEntry = entry; + chrome.fileManagerPrivate.renameVolume(volumeInfo.volumeId, newName); + } else { + newEntry = await renameEntry(entry, newName); + await this.directoryModel_.onRenameEntry(entry, assert(newEntry)); } - // Validation succeeded. Do renaming. - this.listContainer_.renameInput.currentEntry = null; - if (this.listContainer_.renameInput.parentNode) { - this.listContainer_.renameInput.parentNode.removeChild( - this.listContainer_.renameInput); - } + // Select new entry. + this.listContainer_.currentList.selectionModel.selectedIndex = + this.directoryModel_.getFileList().indexOf(newEntry); + // Force to update selection immediately. + this.selectionHandler_.onFileSelectionChanged(); - // Optimistically apply new name immediately to avoid flickering in - // case of success. - nameNode.textContent = newName; + renamedItemElement.removeAttribute('renaming'); + this.listContainer_.endBatchUpdates(); - renameEntry( - entry, newName, - newEntry => { - this.directoryModel_.onRenameEntry(entry, assert(newEntry), () => { - // Select new entry. - this.listContainer_.currentList.selectionModel.selectedIndex = - this.directoryModel_.getFileList().indexOf(newEntry); - // Force to update selection immediately. - this.selectionHandler_.onFileSelectionChanged(); + // Focus may go out of the list. Back it to the list. + this.listContainer_.currentList.focus(); + } catch (error) { + // Write back to the old name. + nameNode.textContent = entry.name; + renamedItemElement.removeAttribute('renaming'); + this.listContainer_.endBatchUpdates(); - renamedItemElement.removeAttribute('renaming'); - this.listContainer_.endBatchUpdates(); - - // Focus may go out of the list. Back it to the list. - this.listContainer_.currentList.focus(); - }); - }, - error => { - // Write back to the old name. - nameNode.textContent = entry.name; - renamedItemElement.removeAttribute('renaming'); - this.listContainer_.endBatchUpdates(); - - // Show error dialog. - const message = getRenameErrorMessage(error, entry, newName); - this.alertDialog_.show(message); - }); - }; - - // TODO(mtomasz): this.getCurrentDirectoryEntry() might not return the - // actual parent if the directory content is a search result. Fix it to do - // proper validation. - this.validateFileName( - /** @type {!DirectoryEntry} */ ( - this.directoryModel_.getCurrentDirEntry()), - newName, validationDone.bind(this)); + // Show error dialog. + const message = getRenameErrorMessage(error, entry, newName); + this.alertDialog_.show(message); + } } /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/breadcrumb.html b/ui/file_manager/file_manager/foreground/js/ui/breadcrumb.html index b84d4ca..6785715 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/breadcrumb.html +++ b/ui/file_manager/file_manager/foreground/js/ui/breadcrumb.html
@@ -126,17 +126,11 @@ } :host([checked]) button[elider] { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } button:active { - /* TODO(crbug.com/1275388): use blend() instead */ - background: linear-gradient(var(--cros-ripple-color), - var(--cros-ripple-color)), - var(--cros-ripple-color); + background: var(--cros-icon-button-pressed-color); } #elider-menu button {
diff --git a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js index 5eb7c3c..fcbc49d 100644 --- a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js +++ b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
@@ -5,7 +5,7 @@ import {ENTRIES, getCaller, pending, repeatUntil, RootPath, sendTestMessage, TestEntryInfo} from '../test_util.js'; import {testcase} from '../testcase.js'; -import {expandTreeItem, remoteCall, setupAndWaitUntilReady} from './background.js'; +import {expandTreeItem, IGNORE_APP_ERRORS, remoteCall, setupAndWaitUntilReady} from './background.js'; import {TREEITEM_DOWNLOADS, TREEITEM_DRIVE} from './create_new_folder.js'; /** @@ -326,6 +326,70 @@ }; /** + * Tests renaming partitions with the keyboard on the file list. + */ +testcase.renameRemovableWithKeyboardOnFileList = async () => { + // Open Files app on local downloads. + const appId = + await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.world]); + + // Mount removable device with partitions. + await sendTestMessage({name: 'mountUsbWithMultiplePartitionTypes'}); + + // Wait and select the removable group by clicking the label. + const removableGroup = '#directory-tree [root-type-icon="removable"]'; + await remoteCall.waitAndClickElement(appId, removableGroup); + + // Focus on the file list. + await remoteCall.callRemoteTestUtil('focus', appId, ['#file-list']); + + // Wait for partitions to show up. + const expectedRows = [ + ['partition-1', '--', 'ntfs', ''], ['partition-2', '--', 'ext4', ''], + ['partition-3', '--', 'vfat', ''] + ]; + await remoteCall.waitForFiles( + appId, expectedRows, {ignoreLastModifiedTime: true}); + + // Attempt to rename partition with a label longer than permitted for fat32. + const partitionToRename = 'partition-3'; // fat32 + await renameFile(appId, partitionToRename, 'very-long-partition-name'); + + // Verify that an error was triggered. + const errorTextElement = + await remoteCall.waitForElement(appId, '.cr-dialog-text'); + chrome.test.assertEq( + `Use a name that's 11 characters or less`, errorTextElement.text); + + // Dismiss the error dialog. + await remoteCall.waitAndClickElement(appId, '.cr-dialog-ok'); + + // Enter ctrl+A to select the old text so we can replace it. + const textInput = '#file-list > li input'; + await remoteCall.callRemoteTestUtil( + 'fakeKeyDown', appId, [textInput, 'A', true, false, false]); + + // Enter a valid name this time. + const smallerPartitionName = 'smaller'; + const enterKey = [textInput, 'Enter', false, false, false]; + await remoteCall.inputText(appId, textInput, smallerPartitionName); + await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, enterKey); + + // Wait for the renaming input element to disappear. + await remoteCall.waitForElementLost(appId, textInput); + + // verify the partition was successfully renamed. + expectedRows[2][0] = smallerPartitionName; + await remoteCall.waitForFiles( + appId, expectedRows, {ignoreLastModifiedTime: true}); + + // Even though the Files app rename flow worked, the background.js page + // console errors about not being able to 'mount' the older volume name + // due to a disk_mount_manager.cc error: user/fake-usb not found. + return IGNORE_APP_ERRORS; +}; + +/** * Tests that the root html element .focus-outline-visible class appears for * keyboard interaction and is removed on mouse interaction. */
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index f53b0b7f..ea633fd6 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -772,7 +772,7 @@ "geometry/point3_f_unittest.cc", "geometry/point_f_unittest.cc", "geometry/point_unittest.cc", - "geometry/quad_unittest.cc", + "geometry/quad_f_unittest.cc", "geometry/quaternion_unittest.cc", "geometry/rect_conversions_unittest.cc", "geometry/rect_f_unittest.cc", @@ -786,7 +786,7 @@ "geometry/triangle_unittest.cc", "geometry/vector2d_f_unittest.cc", "geometry/vector2d_unittest.cc", - "geometry/vector3d_unittest.cc", + "geometry/vector3d_f_unittest.cc", "half_float_unittest.cc", "icc_profile_unittest.cc", "image/image_skia_operations_unittest.cc",
diff --git a/ui/gfx/geometry/insets.cc b/ui/gfx/geometry/insets.cc index 7c30bcd..ac08be8d 100644 --- a/ui/gfx/geometry/insets.cc +++ b/ui/gfx/geometry/insets.cc
@@ -16,11 +16,10 @@ return base::StringPrintf("%d,%d,%d,%d", top(), left(), bottom(), right()); } -Insets Insets::Offset(const gfx::Vector2d& vector) const { - return gfx::Insets(base::ClampAdd(top(), vector.y()), - base::ClampAdd(left(), vector.x()), - base::ClampSub(bottom(), vector.y()), - base::ClampSub(right(), vector.x())); +void Insets::Offset(const gfx::Vector2d& vector) { + Set(base::ClampAdd(top(), vector.y()), base::ClampAdd(left(), vector.x()), + base::ClampSub(bottom(), vector.y()), + base::ClampSub(right(), vector.x())); } void Insets::SetToMax(const gfx::Insets& other) {
diff --git a/ui/gfx/geometry/insets.h b/ui/gfx/geometry/insets.h index 946a2ce..23a85918 100644 --- a/ui/gfx/geometry/insets.h +++ b/ui/gfx/geometry/insets.h
@@ -115,8 +115,8 @@ // Adjusts the vertical and horizontal dimensions by the values described in // |vector|. Offsetting insets before applying to a rectangle would be - // equivalent to offseting the rectangle then applying the insets. - Insets Offset(const gfx::Vector2d& vector) const; + // equivalent to offsetting the rectangle then applying the insets. + void Offset(const gfx::Vector2d& vector); operator InsetsF() const { return InsetsF(static_cast<float>(top()), static_cast<float>(left()), @@ -184,6 +184,11 @@ return lhs; } +inline Insets operator+(Insets insets, const gfx::Vector2d& offset) { + insets.Offset(offset); + return insets; +} + // Helper methods to scale a gfx::Insets to a new gfx::Insets. GEOMETRY_EXPORT Insets ScaleToCeiledInsets(const Insets& insets, float x_scale,
diff --git a/ui/gfx/geometry/insets_f.h b/ui/gfx/geometry/insets_f.h index d56012eb..e853fc86 100644 --- a/ui/gfx/geometry/insets_f.h +++ b/ui/gfx/geometry/insets_f.h
@@ -79,10 +79,13 @@ return InsetsF(-top_, -left_, -bottom_, -right_); } - InsetsF Scale(float scale) const { - return InsetsF(scale * top(), scale * left(), scale * bottom(), - scale * right()); + void Scale(float x_scale, float y_scale) { + top_ *= y_scale; + left_ *= x_scale; + bottom_ *= y_scale; + right_ *= x_scale; } + void Scale(float scale) { Scale(scale, scale); } // Returns a string representation of the insets. std::string ToString() const; @@ -99,14 +102,13 @@ // test. This should not be used in production code - call ToString() instead. void PrintTo(const InsetsF& point, ::std::ostream* os); -inline InsetsF ScaleInsets(const InsetsF& i, float scale) { - return InsetsF(i.top() * scale, i.left() * scale, i.bottom() * scale, - i.right() * scale); +inline InsetsF ScaleInsets(InsetsF i, float x_scale, float y_scale) { + i.Scale(x_scale, y_scale); + return i; } -inline InsetsF ScaleInsets(const InsetsF& i, float x_scale, float y_scale) { - return InsetsF(i.top() * y_scale, i.left() * x_scale, i.bottom() * y_scale, - i.right() * x_scale); +inline InsetsF ScaleInsets(const InsetsF& i, float scale) { + return ScaleInsets(i, scale, scale); } inline InsetsF operator+(InsetsF lhs, const InsetsF& rhs) {
diff --git a/ui/gfx/geometry/insets_f_unittest.cc b/ui/gfx/geometry/insets_f_unittest.cc index b3f8906..3328914d 100644 --- a/ui/gfx/geometry/insets_f_unittest.cc +++ b/ui/gfx/geometry/insets_f_unittest.cc
@@ -99,6 +99,11 @@ EXPECT_EQ(InsetsF(24.5f, 12.5f, 10.5f, 2.5f), testf); testf = ScaleInsets(in, 2.5f); EXPECT_EQ(InsetsF(17.5f, 12.5f, 7.5f, 2.5f), testf); + + in.Scale(2.5f, 3.5f); + EXPECT_EQ(InsetsF(24.5f, 12.5f, 10.5f, 2.5f), in); + in.Scale(-2.5f); + EXPECT_EQ(InsetsF(-61.25f, -31.25f, -26.25f, -6.25f), in); } TEST(InsetsFTest, ScaleNegative) { @@ -108,6 +113,11 @@ EXPECT_EQ(InsetsF(-24.5f, -12.5f, -10.5f, -2.5f), testf); testf = ScaleInsets(in, 2.5f); EXPECT_EQ(InsetsF(-17.5f, -12.5f, -7.5f, -2.5f), testf); + + in.Scale(2.5f, 3.5f); + EXPECT_EQ(InsetsF(-24.5f, -12.5f, -10.5f, -2.5f), in); + in.Scale(-2.5f); + EXPECT_EQ(InsetsF(61.25f, 31.25f, 26.25f, 6.25f), in); } TEST(InsetsFTest, SetToMax) {
diff --git a/ui/gfx/geometry/insets_unittest.cc b/ui/gfx/geometry/insets_unittest.cc index aec3467..1333a3f 100644 --- a/ui/gfx/geometry/insets_unittest.cc +++ b/ui/gfx/geometry/insets_unittest.cc
@@ -143,8 +143,13 @@ offset_first.Offset(vector); offset_first.Inset(insets); + Insets insets_with_offset = insets; + insets_with_offset.Offset(vector); + EXPECT_EQ(Insets(11, 11, -7, -5), insets_with_offset); + EXPECT_EQ(insets_with_offset, insets + vector); + Rect inset_by_offset = rect; - inset_by_offset.Inset(insets.Offset(vector)); + inset_by_offset.Inset(insets_with_offset); EXPECT_EQ(inset_first, offset_first); EXPECT_EQ(inset_by_offset, inset_first); @@ -292,8 +297,8 @@ const Vector2d max_vector(int_max, int_max); Insets insets(1, 2, 3, 4); - Insets offset_test = insets.Offset(max_vector); - EXPECT_EQ(Insets(int_max, int_max, 3 - int_max, 4 - int_max), offset_test); + insets.Offset(max_vector); + EXPECT_EQ(Insets(int_max, int_max, 3 - int_max, 4 - int_max), insets); } TEST(InsetsTest, IntegerUnderflowOffset) { @@ -301,9 +306,8 @@ const Vector2d min_vector(int_min, int_min); Insets insets(-10); - Insets offset_test = insets.Offset(min_vector); - EXPECT_EQ(Insets(int_min, int_min, -10 - int_min, -10 - int_min), - offset_test); + insets.Offset(min_vector); + EXPECT_EQ(Insets(int_min, int_min, -10 - int_min, -10 - int_min), insets); } TEST(InsetsTest, Size) {
diff --git a/ui/gfx/geometry/point3_f.cc b/ui/gfx/geometry/point3_f.cc index 465376e..3906a60 100644 --- a/ui/gfx/geometry/point3_f.cc +++ b/ui/gfx/geometry/point3_f.cc
@@ -9,7 +9,7 @@ namespace gfx { std::string Point3F::ToString() const { - return base::StringPrintf("%f,%f,%f", x_, y_, z_); + return base::StringPrintf("%g,%g,%g", x_, y_, z_); } Point3F operator+(const Point3F& lhs, const Vector3dF& rhs) {
diff --git a/ui/gfx/geometry/point3_f_unittest.cc b/ui/gfx/geometry/point3_f_unittest.cc index aa80582..ea3cc66 100644 --- a/ui/gfx/geometry/point3_f_unittest.cc +++ b/ui/gfx/geometry/point3_f_unittest.cc
@@ -84,4 +84,8 @@ Point3F(1.25f, 2.5f, -3.75f).OffsetFromOrigin()); } +TEST(Point3FTest, ToString) { + EXPECT_EQ("1.03125,2.5,-3", Point3F(1.03125, 2.5, -3).ToString()); +} + } // namespace gfx
diff --git a/ui/gfx/geometry/quad_f.cc b/ui/gfx/geometry/quad_f.cc index 80ef28f..e2e2ff7 100644 --- a/ui/gfx/geometry/quad_f.cc +++ b/ui/gfx/geometry/quad_f.cc
@@ -11,6 +11,63 @@ namespace gfx { +namespace { + +PointF RightMostCornerToVector(const RectF& rect, const Vector2dF& vector) { + // Return the corner of the rectangle that if it is to the left of the vector + // would mean all of the rectangle is to the left of the vector. + // The vector here represents the side between two points in a clockwise + // convex polygon. + // + // Q XXX + // QQQ XXX If the lower left corner of X is left of the vector that goes + // QQQ from the top corner of Q to the right corner of Q, then all of X + // Q is left of the vector, and intersection impossible. + // + PointF point; + if (vector.x() >= 0) + point.set_y(rect.bottom()); + else + point.set_y(rect.y()); + if (vector.y() >= 0) + point.set_x(rect.x()); + else + point.set_x(rect.right()); + return point; +} + +// Tests whether the line is contained by or intersected with the circle. +bool LineIntersectsCircle(const PointF& center, + float radius, + const PointF& p0, + const PointF& p1) { + float x0 = p0.x() - center.x(), y0 = p0.y() - center.y(); + float x1 = p1.x() - center.x(), y1 = p1.y() - center.y(); + float radius2 = radius * radius; + if ((x0 * x0 + y0 * y0) <= radius2 || (x1 * x1 + y1 * y1) <= radius2) + return true; + if (p0 == p1) + return false; + + float a = y0 - y1; + float b = x1 - x0; + float c = x0 * y1 - x1 * y0; + float distance2 = c * c / (a * a + b * b); + // If distance between the center point and the line > the radius, + // the line doesn't cross (or is contained by) the ellipse. + if (distance2 > radius2) + return false; + + // The nearest point on the line is between p0 and p1? + float x = -a * c / (a * a + b * b); + float y = -b * c / (a * a + b * b); + + return (((x0 <= x && x <= x1) || (x0 >= x && x >= x1)) && + ((y0 <= y && y <= y1) || (y1 <= y && y <= y0))); +} + +} // anonymous namespace + void QuadF::operator=(const RectF& rect) { p1_ = PointF(rect.x(), rect.y()); p2_ = PointF(rect.right(), rect.y()); @@ -64,8 +121,13 @@ } bool QuadF::Contains(const PointF& point) const { - return PointIsInTriangle(point, p1_, p2_, p3_) - || PointIsInTriangle(point, p1_, p3_, p4_); + return PointIsInTriangle(point, p1_, p2_, p3_) || + PointIsInTriangle(point, p1_, p3_, p4_); +} + +bool QuadF::ContainsQuad(const QuadF& other) const { + return Contains(other.p1()) && Contains(other.p2()) && Contains(other.p3()) && + Contains(other.p4()); } void QuadF::Scale(float x_scale, float y_scale) { @@ -101,4 +163,64 @@ return result; } +bool QuadF::IntersectsRect(const RectF& rect) const { + // For each side of the quad clockwise we check if the rectangle is to the + // left of it since only content on the right can overlap with the quad. + // This only works if the quad is convex. + Vector2dF v1, v2, v3, v4; + + // Ensure we use clockwise vectors. + if (IsCounterClockwise()) { + v1 = p4_ - p1_; + v2 = p1_ - p2_; + v3 = p2_ - p3_; + v4 = p3_ - p4_; + } else { + v1 = p2_ - p1_; + v2 = p3_ - p2_; + v3 = p4_ - p3_; + v4 = p1_ - p4_; + } + + PointF p = RightMostCornerToVector(rect, v1); + if (CrossProduct(v1, p - p1_) < 0) + return false; + + p = RightMostCornerToVector(rect, v2); + if (CrossProduct(v2, p - p2_) < 0) + return false; + + p = RightMostCornerToVector(rect, v3); + if (CrossProduct(v3, p - p3_) < 0) + return false; + + p = RightMostCornerToVector(rect, v4); + if (CrossProduct(v4, p - p4_) < 0) + return false; + + // If not all of the rectangle is outside one of the quad's four sides, then + // that means at least a part of the rectangle is overlapping the quad. + return true; +} + +bool QuadF::IntersectsCircle(const PointF& center, float radius) const { + return Contains(center) || LineIntersectsCircle(center, radius, p1_, p2_) || + LineIntersectsCircle(center, radius, p2_, p3_) || + LineIntersectsCircle(center, radius, p3_, p4_) || + LineIntersectsCircle(center, radius, p4_, p1_); +} + +bool QuadF::IntersectsEllipse(const PointF& center, const SizeF& radii) const { + // Transform the ellipse to an origin-centered circle whose radius is the + // product of major radius and minor radius. Here we apply the same + // transformation to the quad. + QuadF transformed_quad = *this; + transformed_quad -= center.OffsetFromOrigin(); + transformed_quad.Scale(radii.height(), radii.width()); + + PointF origin_point; + return transformed_quad.IntersectsCircle(origin_point, + radii.height() * radii.width()); +} + } // namespace gfx
diff --git a/ui/gfx/geometry/quad_f.h b/ui/gfx/geometry/quad_f.h index 3fe8cf1..b5fcb432 100644 --- a/ui/gfx/geometry/quad_f.h +++ b/ui/gfx/geometry/quad_f.h
@@ -57,7 +57,12 @@ // Returns true if the |point| is contained within the quad, or lies on on // edge of the quad. This assumes that the quad is convex. - bool Contains(const gfx::PointF& point) const; + bool Contains(const PointF& point) const; + + // Returns true if the |quad| parameter is contained within |this| quad. + // This method assumes |this| quad is convex. The |quad| parameter has no + // restrictions. + bool ContainsQuad(const QuadF& quad) const; // Returns a rectangle that bounds the four points of the quad. The points of // the quad may lie on the right/bottom edge of the resulting rectangle, @@ -94,6 +99,26 @@ // Scale each point in the quad by the scale factors along each axis. void Scale(float x_scale, float y_scale); + // Tests whether any part of the rectangle intersects with this quad. + // This only works for convex quads. + // This intersection is edge-inclusive and will return true even if the + // intersecting area is empty (i.e., the intersection is a line or a point). + bool IntersectsRect(const RectF&) const; + + // Test whether any part of the circle/ellipse intersects with this quad. + // Note that these two functions only work for convex quads. + // These intersections are edge-inclusive and will return true even if the + // intersecting area is empty (i.e., the intersection is a line or a point). + bool IntersectsCircle(const PointF& center, float radius) const; + bool IntersectsEllipse(const PointF& center, const SizeF& radii) const; + + // The center of the quad. If the quad is the result of a affine-transformed + // rectangle this is the same as the original center transformed. + PointF CenterPoint() const { + return PointF((p1_.x() + p2_.x() + p3_.x() + p4_.x()) / 4.0, + (p1_.y() + p2_.y() + p3_.y() + p4_.y()) / 4.0); + } + // Returns a string representation of quad. std::string ToString() const;
diff --git a/ui/gfx/geometry/quad_f_unittest.cc b/ui/gfx/geometry/quad_f_unittest.cc new file mode 100644 index 0000000..1603985 --- /dev/null +++ b/ui/gfx/geometry/quad_f_unittest.cc
@@ -0,0 +1,676 @@ +// Copyright 2022 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 <stddef.h> + +#include "base/cxx17_backports.h" +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_f.h" + +namespace gfx { + +TEST(QuadFTest, Construction) { + // Verify constructors. + PointF a(1, 1); + PointF b(2, 1); + PointF c(2, 2); + PointF d(1, 2); + PointF e; + QuadF q1; + QuadF q2(e, e, e, e); + QuadF q3(a, b, c, d); + QuadF q4(BoundingRect(a, c)); + EXPECT_EQ(q1, q2); + EXPECT_EQ(q3, q4); + + // Verify getters. + EXPECT_EQ(q3.p1(), a); + EXPECT_EQ(q3.p2(), b); + EXPECT_EQ(q3.p3(), c); + EXPECT_EQ(q3.p4(), d); + + // Verify setters. + q3.set_p1(b); + q3.set_p2(c); + q3.set_p3(d); + q3.set_p4(a); + EXPECT_EQ(q3.p1(), b); + EXPECT_EQ(q3.p2(), c); + EXPECT_EQ(q3.p3(), d); + EXPECT_EQ(q3.p4(), a); + + // Verify operator=(Rect) + EXPECT_NE(q1, q4); + q1 = BoundingRect(a, c); + EXPECT_EQ(q1, q4); + + // Verify operator=(Quad) + EXPECT_NE(q1, q3); + q1 = q3; + EXPECT_EQ(q1, q3); +} + +TEST(QuadFTest, AddingVectors) { + PointF a(1, 1); + PointF b(2, 1); + PointF c(2, 2); + PointF d(1, 2); + Vector2dF v(3.5f, -2.5f); + + QuadF q1(a, b, c, d); + QuadF added = q1 + v; + q1 += v; + QuadF expected1(PointF(4.5f, -1.5f), PointF(5.5f, -1.5f), PointF(5.5f, -0.5f), + PointF(4.5f, -0.5f)); + EXPECT_EQ(expected1, added); + EXPECT_EQ(expected1, q1); + + QuadF q2(a, b, c, d); + QuadF subtracted = q2 - v; + q2 -= v; + QuadF expected2(PointF(-2.5f, 3.5f), PointF(-1.5f, 3.5f), PointF(-1.5f, 4.5f), + PointF(-2.5f, 4.5f)); + EXPECT_EQ(expected2, subtracted); + EXPECT_EQ(expected2, q2); + + QuadF q3(a, b, c, d); + q3 += v; + q3 -= v; + EXPECT_EQ(QuadF(a, b, c, d), q3); + EXPECT_EQ(q3, (q3 + v - v)); +} + +TEST(QuadFTest, IsRectilinear) { + PointF a(1, 1); + PointF b(2, 1); + PointF c(2, 2); + PointF d(1, 2); + Vector2dF v(3.5f, -2.5f); + + EXPECT_TRUE(QuadF().IsRectilinear()); + EXPECT_TRUE(QuadF(a, b, c, d).IsRectilinear()); + EXPECT_TRUE((QuadF(a, b, c, d) + v).IsRectilinear()); + + float epsilon = std::numeric_limits<float>::epsilon(); + PointF a2(1 + epsilon / 2, 1 + epsilon / 2); + PointF b2(2 + epsilon / 2, 1 + epsilon / 2); + PointF c2(2 + epsilon / 2, 2 + epsilon / 2); + PointF d2(1 + epsilon / 2, 2 + epsilon / 2); + EXPECT_TRUE(QuadF(a2, b, c, d).IsRectilinear()); + EXPECT_TRUE((QuadF(a2, b, c, d) + v).IsRectilinear()); + EXPECT_TRUE(QuadF(a, b2, c, d).IsRectilinear()); + EXPECT_TRUE((QuadF(a, b2, c, d) + v).IsRectilinear()); + EXPECT_TRUE(QuadF(a, b, c2, d).IsRectilinear()); + EXPECT_TRUE((QuadF(a, b, c2, d) + v).IsRectilinear()); + EXPECT_TRUE(QuadF(a, b, c, d2).IsRectilinear()); + EXPECT_TRUE((QuadF(a, b, c, d2) + v).IsRectilinear()); + + struct { + PointF a_off, b_off, c_off, d_off; + } tests[] = {{PointF(1, 1.00001f), PointF(2, 1.00001f), PointF(2, 2.00001f), + PointF(1, 2.00001f)}, + {PointF(1.00001f, 1), PointF(2.00001f, 1), PointF(2.00001f, 2), + PointF(1.00001f, 2)}, + {PointF(1.00001f, 1.00001f), PointF(2.00001f, 1.00001f), + PointF(2.00001f, 2.00001f), PointF(1.00001f, 2.00001f)}, + {PointF(1, 0.99999f), PointF(2, 0.99999f), PointF(2, 1.99999f), + PointF(1, 1.99999f)}, + {PointF(0.99999f, 1), PointF(1.99999f, 1), PointF(1.99999f, 2), + PointF(0.99999f, 2)}, + {PointF(0.99999f, 0.99999f), PointF(1.99999f, 0.99999f), + PointF(1.99999f, 1.99999f), PointF(0.99999f, 1.99999f)}}; + + for (const auto& test : tests) { + PointF a_off = test.a_off; + PointF b_off = test.b_off; + PointF c_off = test.c_off; + PointF d_off = test.d_off; + + EXPECT_FALSE(QuadF(a_off, b, c, d).IsRectilinear()); + EXPECT_FALSE((QuadF(a_off, b, c, d) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a, b_off, c, d).IsRectilinear()); + EXPECT_FALSE((QuadF(a, b_off, c, d) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a, b, c_off, d).IsRectilinear()); + EXPECT_FALSE((QuadF(a, b, c_off, d) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a, b, c, d_off).IsRectilinear()); + EXPECT_FALSE((QuadF(a, b, c, d_off) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a_off, b, c_off, d).IsRectilinear()); + EXPECT_FALSE((QuadF(a_off, b, c_off, d) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a, b_off, c, d_off).IsRectilinear()); + EXPECT_FALSE((QuadF(a, b_off, c, d_off) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a, b_off, c_off, d_off).IsRectilinear()); + EXPECT_FALSE((QuadF(a, b_off, c_off, d_off) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a_off, b, c_off, d_off).IsRectilinear()); + EXPECT_FALSE((QuadF(a_off, b, c_off, d_off) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a_off, b_off, c, d_off).IsRectilinear()); + EXPECT_FALSE((QuadF(a_off, b_off, c, d_off) + v).IsRectilinear()); + EXPECT_FALSE(QuadF(a_off, b_off, c_off, d).IsRectilinear()); + EXPECT_FALSE((QuadF(a_off, b_off, c_off, d) + v).IsRectilinear()); + EXPECT_TRUE(QuadF(a_off, b_off, c_off, d_off).IsRectilinear()); + EXPECT_TRUE((QuadF(a_off, b_off, c_off, d_off) + v).IsRectilinear()); + } +} + +TEST(QuadFTest, IsCounterClockwise) { + PointF a1(1, 1); + PointF b1(2, 1); + PointF c1(2, 2); + PointF d1(1, 2); + EXPECT_FALSE(QuadF(a1, b1, c1, d1).IsCounterClockwise()); + EXPECT_FALSE(QuadF(b1, c1, d1, a1).IsCounterClockwise()); + EXPECT_TRUE(QuadF(a1, d1, c1, b1).IsCounterClockwise()); + EXPECT_TRUE(QuadF(c1, b1, a1, d1).IsCounterClockwise()); + + // Slightly more complicated quads should work just as easily. + PointF a2(1.3f, 1.4f); + PointF b2(-0.7f, 4.9f); + PointF c2(1.8f, 6.2f); + PointF d2(2.1f, 1.6f); + EXPECT_TRUE(QuadF(a2, b2, c2, d2).IsCounterClockwise()); + EXPECT_TRUE(QuadF(b2, c2, d2, a2).IsCounterClockwise()); + EXPECT_FALSE(QuadF(a2, d2, c2, b2).IsCounterClockwise()); + EXPECT_FALSE(QuadF(c2, b2, a2, d2).IsCounterClockwise()); + + // Quads with 3 collinear points should work correctly, too. + PointF a3(0, 0); + PointF b3(1, 0); + PointF c3(2, 0); + PointF d3(1, 1); + EXPECT_FALSE(QuadF(a3, b3, c3, d3).IsCounterClockwise()); + EXPECT_FALSE(QuadF(b3, c3, d3, a3).IsCounterClockwise()); + EXPECT_TRUE(QuadF(a3, d3, c3, b3).IsCounterClockwise()); + // The next expectation in particular would fail for an implementation + // that incorrectly uses only a cross product of the first 3 vertices. + EXPECT_TRUE(QuadF(c3, b3, a3, d3).IsCounterClockwise()); + + // Non-convex quads should work correctly, too. + PointF a4(0, 0); + PointF b4(1, 1); + PointF c4(2, 0); + PointF d4(1, 3); + EXPECT_FALSE(QuadF(a4, b4, c4, d4).IsCounterClockwise()); + EXPECT_FALSE(QuadF(b4, c4, d4, a4).IsCounterClockwise()); + EXPECT_TRUE(QuadF(a4, d4, c4, b4).IsCounterClockwise()); + EXPECT_TRUE(QuadF(c4, b4, a4, d4).IsCounterClockwise()); + + // A quad with huge coordinates should not fail this check due to + // single-precision overflow. + PointF a5(1e30f, 1e30f); + PointF b5(1e35f, 1e30f); + PointF c5(1e35f, 1e35f); + PointF d5(1e30f, 1e35f); + EXPECT_FALSE(QuadF(a5, b5, c5, d5).IsCounterClockwise()); + EXPECT_FALSE(QuadF(b5, c5, d5, a5).IsCounterClockwise()); + EXPECT_TRUE(QuadF(a5, d5, c5, b5).IsCounterClockwise()); + EXPECT_TRUE(QuadF(c5, b5, a5, d5).IsCounterClockwise()); +} + +TEST(QuadFTest, BoundingBox) { + RectF r(3.2f, 5.4f, 7.007f, 12.01f); + EXPECT_EQ(r, QuadF(r).BoundingBox()); + + PointF a(1.3f, 1.4f); + PointF b(-0.7f, 4.9f); + PointF c(1.8f, 6.2f); + PointF d(2.1f, 1.6f); + float left = -0.7f; + float top = 1.4f; + float right = 2.1f; + float bottom = 6.2f; + EXPECT_EQ(RectF(left, top, right - left, bottom - top), + QuadF(a, b, c, d).BoundingBox()); +} + +TEST(QuadFTest, ContainsPoint) { + PointF a(1.3f, 1.4f); + PointF b(-0.8f, 4.4f); + PointF c(1.8f, 6.1f); + PointF d(2.1f, 1.6f); + + Vector2dF epsilon_x(2 * std::numeric_limits<float>::epsilon(), 0); + Vector2dF epsilon_y(0, 2 * std::numeric_limits<float>::epsilon()); + + Vector2dF ac_center = c - a; + ac_center.Scale(0.5f); + Vector2dF bd_center = d - b; + bd_center.Scale(0.5f); + + EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + ac_center)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + bd_center)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - ac_center)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - bd_center)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - ac_center)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - bd_center)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + ac_center)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + bd_center)); + + EXPECT_TRUE(QuadF(a, b, c, d).Contains(a)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_y)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(a + epsilon_x)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + epsilon_y)); + + EXPECT_TRUE(QuadF(a, b, c, d).Contains(b)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_y)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(b + epsilon_y)); + + EXPECT_TRUE(QuadF(a, b, c, d).Contains(c)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(c - epsilon_x)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - epsilon_y)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_y)); + + EXPECT_TRUE(QuadF(a, b, c, d).Contains(d)); + EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(d - epsilon_y)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_x)); + EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_y)); + + // Test a simple square. + PointF s1(-1, -1); + PointF s2(1, -1); + PointF s3(1, 1); + PointF s4(-1, 1); + // Top edge. + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, -1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, -1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, -1.0f))); + // Bottom edge. + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, 1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 1.0f))); + // Left edge. + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.1f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 0.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.1f))); + // Right edge. + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.1f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 0.0f))); + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.1f))); + // Centered inside. + EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 0))); + // Centered outside. + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 0))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 0))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, -1.1f))); + EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 1.1f))); +} + +TEST(QuadFTest, ContainsQuad) { + QuadF quad(PointF(10, 0), PointF(20, 10), PointF(10, 20), PointF(0, 10)); + EXPECT_TRUE(quad.ContainsQuad(quad)); + EXPECT_TRUE(QuadF(quad.BoundingBox()).ContainsQuad(quad)); + EXPECT_FALSE(quad.ContainsQuad(QuadF(quad.BoundingBox()))); + + EXPECT_FALSE(quad.ContainsQuad(QuadF(RectF(4.9, 4.9, 9.8, 9.8)))); + EXPECT_TRUE(quad.ContainsQuad(QuadF(RectF(5.1, 5.1, 9.8, 9.8)))); + EXPECT_FALSE(quad.ContainsQuad(QuadF(RectF(5.1, 5.1, 11, 9.8)))); + EXPECT_FALSE(quad.ContainsQuad(QuadF(RectF(5.1, 5.1, 9.8, 11)))); + + EXPECT_FALSE(quad.ContainsQuad(quad + gfx::Vector2dF(0.1, 0))); + EXPECT_FALSE(quad.ContainsQuad(quad + gfx::Vector2dF(0, 0.1))); + EXPECT_FALSE(quad.ContainsQuad(quad - gfx::Vector2dF(0.1, 0))); + EXPECT_FALSE(quad.ContainsQuad(quad - gfx::Vector2dF(0, 0.1))); +} + +TEST(QuadFTest, Scale) { + PointF a(1.3f, 1.4f); + PointF b(-0.8f, 4.4f); + PointF c(1.8f, 6.1f); + PointF d(2.1f, 1.6f); + QuadF q1(a, b, c, d); + q1.Scale(1.5f); + + PointF a_scaled = ScalePoint(a, 1.5f); + PointF b_scaled = ScalePoint(b, 1.5f); + PointF c_scaled = ScalePoint(c, 1.5f); + PointF d_scaled = ScalePoint(d, 1.5f); + EXPECT_EQ(q1, QuadF(a_scaled, b_scaled, c_scaled, d_scaled)); + + QuadF q2; + q2.Scale(1.5f); + EXPECT_EQ(q2, q2); +} + +TEST(QuadFTest, IntersectsRectClockwise) { + QuadF quad(PointF(10, 0), PointF(20, 10), PointF(10, 20), PointF(0, 10)); + + // Top-left. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 4.9, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 4.9, 6))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 5.1, 5.1))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 6, 4.9))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 2, 6))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 6, 2))); + + // Top. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, -30, 20, 2))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, -5, 20, 2))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, -5, 20, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, -5, 20, 5.1))); + + // Top-right. + EXPECT_FALSE(quad.IntersectsRect(RectF(15.1, 0, 10, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(15.1, 0, 10, 6))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14.9, 0, 10, 5.1))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14, 0, 10, 4.9))); + EXPECT_FALSE(quad.IntersectsRect(RectF(18, 0, 10, 6))); + EXPECT_FALSE(quad.IntersectsRect(RectF(14, 0, 10, 2))); + + // Right. + EXPECT_FALSE(quad.IntersectsRect(RectF(50, 0, 2, 20))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(22, 0, 2, 20))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(20.1, 0, 2, 20))); + EXPECT_TRUE(quad.IntersectsRect(RectF(19.9, 0, 2, 20))); + + // Bottom-right. + EXPECT_FALSE(quad.IntersectsRect(RectF(15.1, 15.1, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(15.1, 14, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14.9, 14.9, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14, 15.1, 10, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(18, 14, 10, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(14, 18, 10, 10))); + + // Bottom. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 50, 20, 2))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, 22, 20, 2))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, 20.1, 20, 2))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 19.9, 20, 2))); + + // Bottom-left. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 15.1, 4.9, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 15.1, 6, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 14.9, 5.1, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 14, 4.9, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 18, 6, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 14, 2, 10))); + + // Left. + EXPECT_FALSE(quad.IntersectsRect(RectF(-30, 0, 2, 20))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(-5, 0, 2, 20))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(-5, 0, 4.9, 20))); + EXPECT_TRUE(quad.IntersectsRect(RectF(-5, 0, 5.1, 20))); + + // Cover. + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 20, 20))); +} + +TEST(QuadFTest, IntersectsRectCounterClockwise) { + QuadF quad(PointF(10, 0), PointF(0, 10), PointF(10, 20), PointF(20, 10)); + + // Top-left. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 4.9, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 4.9, 6))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 5.1, 5.1))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 6, 4.9))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 2, 6))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 0, 6, 2))); + + // Top. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, -30, 20, 2))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, -5, 20, 2))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, -5, 20, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, -5, 20, 5.1))); + + // Top-right. + EXPECT_FALSE(quad.IntersectsRect(RectF(15.1, 0, 10, 4.9))); + EXPECT_TRUE(quad.IntersectsRect(RectF(15.1, 0, 10, 6))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14.9, 0, 10, 5.1))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14, 0, 10, 4.9))); + EXPECT_FALSE(quad.IntersectsRect(RectF(18, 0, 10, 6))); + EXPECT_FALSE(quad.IntersectsRect(RectF(14, 0, 10, 2))); + + // Right. + EXPECT_FALSE(quad.IntersectsRect(RectF(50, 0, 2, 20))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(22, 0, 2, 20))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(20.1, 0, 2, 20))); + EXPECT_TRUE(quad.IntersectsRect(RectF(19.9, 0, 2, 20))); + + // Bottom-right. + EXPECT_FALSE(quad.IntersectsRect(RectF(15.1, 15.1, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(15.1, 14, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14.9, 14.9, 10, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(14, 15.1, 10, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(18, 14, 10, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(14, 18, 10, 10))); + + // Bottom. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 50, 20, 2))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, 22, 20, 2))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(0, 20.1, 20, 2))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 19.9, 20, 2))); + + // Bottom-left. + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 15.1, 4.9, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 15.1, 6, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 14.9, 5.1, 10))); + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 14, 4.9, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 18, 6, 10))); + EXPECT_FALSE(quad.IntersectsRect(RectF(0, 14, 2, 10))); + + // Left. + EXPECT_FALSE(quad.IntersectsRect(RectF(-30, 0, 2, 20))); + // TODO(crbug.com/1283709): For now the result is true. + // EXPECT_FALSE(quad.IntersectsRect(RectF(-5, 0, 2, 20))); + // EXPECT_FALSE(quad.IntersectsRect(RectF(-5, 0, 4.9, 20))); + EXPECT_TRUE(quad.IntersectsRect(RectF(-5, 0, 5.1, 20))); + + // Cover. + EXPECT_TRUE(quad.IntersectsRect(RectF(0, 0, 20, 20))); +} + +TEST(QuadFTest, RectIntersectionIsInclusive) { + // A rectilinear quad at (10, 10) with dimensions 10x10. + QuadF quad(RectF(10, 10, 10, 10)); + + // A rect fully contained in the quad should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(11, 11, 8, 8))); + + // A point fully contained in the quad should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(11, 11, 0, 0))); + + // A rect that touches the quad only at the point (10, 10) should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(9, 9, 1, 1))); + + // A rect that touches the quad only on the left edge should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(9, 11, 1, 1))); + + // A rect that touches the quad only on the top edge should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(11, 9, 1, 1))); + + // A rect that touches the quad only on the right edge should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(20, 11, 1, 1))); + + // A rect that touches the quad only on the bottom edge should intersect. + EXPECT_TRUE(quad.IntersectsRect(RectF(11, 20, 1, 1))); + + // A rect that is fully outside the quad should not intersect. + EXPECT_FALSE(quad.IntersectsRect(RectF(8, 8, 1, 1))); + + // A point that is fully outside the quad should not intersect. + EXPECT_FALSE(quad.IntersectsRect(RectF(9, 9, 0, 0))); +} + +TEST(QuadFTest, IntersectsEllipseClockWise) { + QuadF quad(PointF(10, 0), PointF(20, 10), PointF(10, 20), PointF(0, 10)); + + // Top-left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(8, 2))); + + // Top. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 2))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 4.9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 5.1))); + + // Top-right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(8, 2))); + + // Right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(25, 10), SizeF(2, 20))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(25, 10), SizeF(4.9, 20))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(25, 10), SizeF(5.1, 20))); + + // Bottom-right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(8, 2))); + + // Bottom. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 2))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 4.9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 5.1))); + + // Bottom-left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(8, 2))); + + // Left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(2, 20))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(4.9, 20))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(5.1, 20))); +} + +TEST(QuadFTest, IntersectsEllipseCounterClockwise) { + QuadF quad(PointF(10, 0), PointF(0, 10), PointF(10, 20), PointF(20, 10)); + + // Top-left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 0), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 0), SizeF(8, 2))); + + // Top. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 2))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 4.9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(10, -5), SizeF(20, 5.1))); + + // Top-right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 0), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 0), SizeF(8, 2))); + + // Right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(25, 10), SizeF(2, 20))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(25, 10), SizeF(4.9, 20))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(25, 10), SizeF(5.1, 20))); + + // Bottom-right. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(20, 20), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(20, 20), SizeF(8, 2))); + + // Bottom. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 2))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 4.9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(10, 25), SizeF(20, 5.1))); + + // Bottom-left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(7, 7))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(6, 9))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(7.1, 7.1))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(0, 20), SizeF(9, 6))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(2, 8))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(0, 20), SizeF(8, 2))); + + // Left. + EXPECT_FALSE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(2, 20))); + EXPECT_FALSE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(4.9, 20))); + EXPECT_TRUE(quad.IntersectsEllipse(PointF(-5, 10), SizeF(5.1, 20))); +} + +TEST(QuadFTest, CircleIntersectionIsInclusive) { + // A rectilinear quad at (10, 10) with dimensions 10x10. + QuadF quad(RectF(10, 10, 10, 10)); + + // A circle fully contained in the top-left of the quad should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(12, 12), 1)); + + // A point fully contained in the top-left of the quad should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(12, 12), 0)); + + // A circle that touches the left edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(9, 11), 1)); + + // A circle that touches the top edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(11, 9), 1)); + + // A circle that touches the right edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(21, 11), 1)); + + // A circle that touches the bottom edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(11, 21), 1)); + + // A point that touches the left edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(10, 11), 0)); + + // A point that touches the top edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(11, 10), 0)); + + // A point that touches the right edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(20, 11), 0)); + + // A point that touches the bottom edge should intersect. + EXPECT_TRUE(quad.IntersectsCircle(PointF(11, 20), 0)); + + // A circle that is fully outside the quad should not intersect. + EXPECT_FALSE(quad.IntersectsCircle(PointF(9, 9), 1)); + + // A point that is fully outside the quad should not intersect. + EXPECT_FALSE(quad.IntersectsCircle(PointF(9, 9), 0)); +} + +TEST(QuadFTest, CenterPoint) { + EXPECT_EQ(PointF(), QuadF().CenterPoint()); + EXPECT_EQ(PointF(25.75f, 40.75f), + QuadF(RectF(10.5f, 20.5f, 30.5f, 40.5f)).CenterPoint()); + EXPECT_EQ(PointF(10, 10), + QuadF(PointF(10, 0), PointF(20, 10), PointF(10, 20), PointF(0, 10)) + .CenterPoint()); +} + +} // namespace gfx
diff --git a/ui/gfx/geometry/quad_unittest.cc b/ui/gfx/geometry/quad_unittest.cc deleted file mode 100644 index 87849b0c..0000000 --- a/ui/gfx/geometry/quad_unittest.cc +++ /dev/null
@@ -1,361 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include "base/cxx17_backports.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/quad_f.h" -#include "ui/gfx/geometry/rect_f.h" - -namespace gfx { - -TEST(QuadTest, Construction) { - // Verify constructors. - PointF a(1, 1); - PointF b(2, 1); - PointF c(2, 2); - PointF d(1, 2); - PointF e; - QuadF q1; - QuadF q2(e, e, e, e); - QuadF q3(a, b, c, d); - QuadF q4(BoundingRect(a, c)); - EXPECT_EQ(q1, q2); - EXPECT_EQ(q3, q4); - - // Verify getters. - EXPECT_EQ(q3.p1(), a); - EXPECT_EQ(q3.p2(), b); - EXPECT_EQ(q3.p3(), c); - EXPECT_EQ(q3.p4(), d); - - // Verify setters. - q3.set_p1(b); - q3.set_p2(c); - q3.set_p3(d); - q3.set_p4(a); - EXPECT_EQ(q3.p1(), b); - EXPECT_EQ(q3.p2(), c); - EXPECT_EQ(q3.p3(), d); - EXPECT_EQ(q3.p4(), a); - - // Verify operator=(Rect) - EXPECT_NE(q1, q4); - q1 = BoundingRect(a, c); - EXPECT_EQ(q1, q4); - - // Verify operator=(Quad) - EXPECT_NE(q1, q3); - q1 = q3; - EXPECT_EQ(q1, q3); -} - -TEST(QuadTest, AddingVectors) { - PointF a(1, 1); - PointF b(2, 1); - PointF c(2, 2); - PointF d(1, 2); - Vector2dF v(3.5f, -2.5f); - - QuadF q1(a, b, c, d); - QuadF added = q1 + v; - q1 += v; - QuadF expected1(PointF(4.5f, -1.5f), - PointF(5.5f, -1.5f), - PointF(5.5f, -0.5f), - PointF(4.5f, -0.5f)); - EXPECT_EQ(expected1, added); - EXPECT_EQ(expected1, q1); - - QuadF q2(a, b, c, d); - QuadF subtracted = q2 - v; - q2 -= v; - QuadF expected2(PointF(-2.5f, 3.5f), - PointF(-1.5f, 3.5f), - PointF(-1.5f, 4.5f), - PointF(-2.5f, 4.5f)); - EXPECT_EQ(expected2, subtracted); - EXPECT_EQ(expected2, q2); - - QuadF q3(a, b, c, d); - q3 += v; - q3 -= v; - EXPECT_EQ(QuadF(a, b, c, d), q3); - EXPECT_EQ(q3, (q3 + v - v)); -} - -TEST(QuadTest, IsRectilinear) { - PointF a(1, 1); - PointF b(2, 1); - PointF c(2, 2); - PointF d(1, 2); - Vector2dF v(3.5f, -2.5f); - - EXPECT_TRUE(QuadF().IsRectilinear()); - EXPECT_TRUE(QuadF(a, b, c, d).IsRectilinear()); - EXPECT_TRUE((QuadF(a, b, c, d) + v).IsRectilinear()); - - float epsilon = std::numeric_limits<float>::epsilon(); - PointF a2(1 + epsilon / 2, 1 + epsilon / 2); - PointF b2(2 + epsilon / 2, 1 + epsilon / 2); - PointF c2(2 + epsilon / 2, 2 + epsilon / 2); - PointF d2(1 + epsilon / 2, 2 + epsilon / 2); - EXPECT_TRUE(QuadF(a2, b, c, d).IsRectilinear()); - EXPECT_TRUE((QuadF(a2, b, c, d) + v).IsRectilinear()); - EXPECT_TRUE(QuadF(a, b2, c, d).IsRectilinear()); - EXPECT_TRUE((QuadF(a, b2, c, d) + v).IsRectilinear()); - EXPECT_TRUE(QuadF(a, b, c2, d).IsRectilinear()); - EXPECT_TRUE((QuadF(a, b, c2, d) + v).IsRectilinear()); - EXPECT_TRUE(QuadF(a, b, c, d2).IsRectilinear()); - EXPECT_TRUE((QuadF(a, b, c, d2) + v).IsRectilinear()); - - struct { - PointF a_off, b_off, c_off, d_off; - } tests[] = { - { - PointF(1, 1.00001f), - PointF(2, 1.00001f), - PointF(2, 2.00001f), - PointF(1, 2.00001f) - }, - { - PointF(1.00001f, 1), - PointF(2.00001f, 1), - PointF(2.00001f, 2), - PointF(1.00001f, 2) - }, - { - PointF(1.00001f, 1.00001f), - PointF(2.00001f, 1.00001f), - PointF(2.00001f, 2.00001f), - PointF(1.00001f, 2.00001f) - }, - { - PointF(1, 0.99999f), - PointF(2, 0.99999f), - PointF(2, 1.99999f), - PointF(1, 1.99999f) - }, - { - PointF(0.99999f, 1), - PointF(1.99999f, 1), - PointF(1.99999f, 2), - PointF(0.99999f, 2) - }, - { - PointF(0.99999f, 0.99999f), - PointF(1.99999f, 0.99999f), - PointF(1.99999f, 1.99999f), - PointF(0.99999f, 1.99999f) - } - }; - - for (size_t i = 0; i < base::size(tests); ++i) { - PointF a_off = tests[i].a_off; - PointF b_off = tests[i].b_off; - PointF c_off = tests[i].c_off; - PointF d_off = tests[i].d_off; - - EXPECT_FALSE(QuadF(a_off, b, c, d).IsRectilinear()); - EXPECT_FALSE((QuadF(a_off, b, c, d) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a, b_off, c, d).IsRectilinear()); - EXPECT_FALSE((QuadF(a, b_off, c, d) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a, b, c_off, d).IsRectilinear()); - EXPECT_FALSE((QuadF(a, b, c_off, d) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a, b, c, d_off).IsRectilinear()); - EXPECT_FALSE((QuadF(a, b, c, d_off) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a_off, b, c_off, d).IsRectilinear()); - EXPECT_FALSE((QuadF(a_off, b, c_off, d) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a, b_off, c, d_off).IsRectilinear()); - EXPECT_FALSE((QuadF(a, b_off, c, d_off) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a, b_off, c_off, d_off).IsRectilinear()); - EXPECT_FALSE((QuadF(a, b_off, c_off, d_off) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a_off, b, c_off, d_off).IsRectilinear()); - EXPECT_FALSE((QuadF(a_off, b, c_off, d_off) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a_off, b_off, c, d_off).IsRectilinear()); - EXPECT_FALSE((QuadF(a_off, b_off, c, d_off) + v).IsRectilinear()); - EXPECT_FALSE(QuadF(a_off, b_off, c_off, d).IsRectilinear()); - EXPECT_FALSE((QuadF(a_off, b_off, c_off, d) + v).IsRectilinear()); - EXPECT_TRUE(QuadF(a_off, b_off, c_off, d_off).IsRectilinear()); - EXPECT_TRUE((QuadF(a_off, b_off, c_off, d_off) + v).IsRectilinear()); - } -} - -TEST(QuadTest, IsCounterClockwise) { - PointF a1(1, 1); - PointF b1(2, 1); - PointF c1(2, 2); - PointF d1(1, 2); - EXPECT_FALSE(QuadF(a1, b1, c1, d1).IsCounterClockwise()); - EXPECT_FALSE(QuadF(b1, c1, d1, a1).IsCounterClockwise()); - EXPECT_TRUE(QuadF(a1, d1, c1, b1).IsCounterClockwise()); - EXPECT_TRUE(QuadF(c1, b1, a1, d1).IsCounterClockwise()); - - // Slightly more complicated quads should work just as easily. - PointF a2(1.3f, 1.4f); - PointF b2(-0.7f, 4.9f); - PointF c2(1.8f, 6.2f); - PointF d2(2.1f, 1.6f); - EXPECT_TRUE(QuadF(a2, b2, c2, d2).IsCounterClockwise()); - EXPECT_TRUE(QuadF(b2, c2, d2, a2).IsCounterClockwise()); - EXPECT_FALSE(QuadF(a2, d2, c2, b2).IsCounterClockwise()); - EXPECT_FALSE(QuadF(c2, b2, a2, d2).IsCounterClockwise()); - - // Quads with 3 collinear points should work correctly, too. - PointF a3(0, 0); - PointF b3(1, 0); - PointF c3(2, 0); - PointF d3(1, 1); - EXPECT_FALSE(QuadF(a3, b3, c3, d3).IsCounterClockwise()); - EXPECT_FALSE(QuadF(b3, c3, d3, a3).IsCounterClockwise()); - EXPECT_TRUE(QuadF(a3, d3, c3, b3).IsCounterClockwise()); - // The next expectation in particular would fail for an implementation - // that incorrectly uses only a cross product of the first 3 vertices. - EXPECT_TRUE(QuadF(c3, b3, a3, d3).IsCounterClockwise()); - - // Non-convex quads should work correctly, too. - PointF a4(0, 0); - PointF b4(1, 1); - PointF c4(2, 0); - PointF d4(1, 3); - EXPECT_FALSE(QuadF(a4, b4, c4, d4).IsCounterClockwise()); - EXPECT_FALSE(QuadF(b4, c4, d4, a4).IsCounterClockwise()); - EXPECT_TRUE(QuadF(a4, d4, c4, b4).IsCounterClockwise()); - EXPECT_TRUE(QuadF(c4, b4, a4, d4).IsCounterClockwise()); - - // A quad with huge coordinates should not fail this check due to - // single-precision overflow. - PointF a5(1e30f, 1e30f); - PointF b5(1e35f, 1e30f); - PointF c5(1e35f, 1e35f); - PointF d5(1e30f, 1e35f); - EXPECT_FALSE(QuadF(a5, b5, c5, d5).IsCounterClockwise()); - EXPECT_FALSE(QuadF(b5, c5, d5, a5).IsCounterClockwise()); - EXPECT_TRUE(QuadF(a5, d5, c5, b5).IsCounterClockwise()); - EXPECT_TRUE(QuadF(c5, b5, a5, d5).IsCounterClockwise()); -} - -TEST(QuadTest, BoundingBox) { - RectF r(3.2f, 5.4f, 7.007f, 12.01f); - EXPECT_EQ(r, QuadF(r).BoundingBox()); - - PointF a(1.3f, 1.4f); - PointF b(-0.7f, 4.9f); - PointF c(1.8f, 6.2f); - PointF d(2.1f, 1.6f); - float left = -0.7f; - float top = 1.4f; - float right = 2.1f; - float bottom = 6.2f; - EXPECT_EQ(RectF(left, top, right - left, bottom - top), - QuadF(a, b, c, d).BoundingBox()); -} - -TEST(QuadTest, ContainsPoint) { - PointF a(1.3f, 1.4f); - PointF b(-0.8f, 4.4f); - PointF c(1.8f, 6.1f); - PointF d(2.1f, 1.6f); - - Vector2dF epsilon_x(2 * std::numeric_limits<float>::epsilon(), 0); - Vector2dF epsilon_y(0, 2 * std::numeric_limits<float>::epsilon()); - - Vector2dF ac_center = c - a; - ac_center.Scale(0.5f); - Vector2dF bd_center = d - b; - bd_center.Scale(0.5f); - - EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + ac_center)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + bd_center)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - ac_center)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - bd_center)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - ac_center)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - bd_center)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + ac_center)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + bd_center)); - - EXPECT_TRUE(QuadF(a, b, c, d).Contains(a)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_y)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(a + epsilon_x)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + epsilon_y)); - - EXPECT_TRUE(QuadF(a, b, c, d).Contains(b)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_y)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(b + epsilon_y)); - - EXPECT_TRUE(QuadF(a, b, c, d).Contains(c)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(c - epsilon_x)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - epsilon_y)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_y)); - - EXPECT_TRUE(QuadF(a, b, c, d).Contains(d)); - EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(d - epsilon_y)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_x)); - EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_y)); - - // Test a simple square. - PointF s1(-1, -1); - PointF s2(1, -1); - PointF s3(1, 1); - PointF s4(-1, 1); - // Top edge. - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, -1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, -1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, -1.0f))); - // Bottom edge. - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, 1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 1.0f))); - // Left edge. - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.1f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 0.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.1f))); - // Right edge. - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.1f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 0.0f))); - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.1f))); - // Centered inside. - EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 0))); - // Centered outside. - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 0))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 0))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, -1.1f))); - EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 1.1f))); -} - -TEST(QuadTest, Scale) { - PointF a(1.3f, 1.4f); - PointF b(-0.8f, 4.4f); - PointF c(1.8f, 6.1f); - PointF d(2.1f, 1.6f); - QuadF q1(a, b, c, d); - q1.Scale(1.5f); - - PointF a_scaled = ScalePoint(a, 1.5f); - PointF b_scaled = ScalePoint(b, 1.5f); - PointF c_scaled = ScalePoint(c, 1.5f); - PointF d_scaled = ScalePoint(d, 1.5f); - EXPECT_EQ(q1, QuadF(a_scaled, b_scaled, c_scaled, d_scaled)); - - QuadF q2; - q2.Scale(1.5f); - EXPECT_EQ(q2, q2); -} - -} // namespace gfx
diff --git a/ui/gfx/geometry/vector3d_f.cc b/ui/gfx/geometry/vector3d_f.cc index d538a57..e1e3009ea 100644 --- a/ui/gfx/geometry/vector3d_f.cc +++ b/ui/gfx/geometry/vector3d_f.cc
@@ -16,7 +16,7 @@ namespace gfx { std::string Vector3dF::ToString() const { - return base::StringPrintf("[%f %f %f]", x_, y_, z_); + return base::StringPrintf("[%g %g %g]", x_, y_, z_); } bool Vector3dF::IsZero() const {
diff --git a/ui/gfx/geometry/vector3d_unittest.cc b/ui/gfx/geometry/vector3d_f_unittest.cc similarity index 96% rename from ui/gfx/geometry/vector3d_unittest.cc rename to ui/gfx/geometry/vector3d_f_unittest.cc index 1eab6a6..27224bd 100644 --- a/ui/gfx/geometry/vector3d_unittest.cc +++ b/ui/gfx/geometry/vector3d_f_unittest.cc
@@ -14,7 +14,7 @@ namespace gfx { -TEST(Vector3dTest, IsZero) { +TEST(Vector3dFTest, IsZero) { gfx::Vector3dF float_zero(0, 0, 0); gfx::Vector3dF float_nonzero(0.1f, -0.1f, 0.1f); @@ -22,7 +22,7 @@ EXPECT_FALSE(float_nonzero.IsZero()); } -TEST(Vector3dTest, Add) { +TEST(Vector3dFTest, Add) { gfx::Vector3dF f1(3.1f, 5.1f, 2.7f); gfx::Vector3dF f2(4.3f, -1.3f, 8.1f); @@ -40,7 +40,7 @@ float_tests[i].actual.ToString()); } -TEST(Vector3dTest, Negative) { +TEST(Vector3dFTest, Negative) { const struct { gfx::Vector3dF expected; gfx::Vector3dF actual; @@ -58,7 +58,7 @@ float_tests[i].actual.ToString()); } -TEST(Vector3dTest, Scale) { +TEST(Vector3dFTest, Scale) { float triple_values[][6] = { { 4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f }, { 4.5f, -1.2f, -1.8f, 3.3f, 5.6f, 4.2f }, @@ -142,7 +142,7 @@ } } -TEST(Vector3dTest, Length) { +TEST(Vector3dFTest, Length) { float float_values[][3] = { { 0, 0, 0 }, { 10.5f, 20.5f, 8.5f }, @@ -179,7 +179,7 @@ } } -TEST(Vector3dTest, DotProduct) { +TEST(Vector3dFTest, DotProduct) { const struct { float expected; gfx::Vector3dF input1; @@ -204,7 +204,7 @@ } } -TEST(Vector3dTest, CrossProduct) { +TEST(Vector3dFTest, CrossProduct) { const struct { gfx::Vector3dF expected; gfx::Vector3dF input1; @@ -265,7 +265,7 @@ EXPECT_EQ(Vector3dF(3.5f, 5.5f, 7.5f).ToString(), a.ToString()); } -TEST(Vector3dTest, AngleBetweenVectorsInDegress) { +TEST(Vector3dFTest, AngleBetweenVectorsInDegress) { const struct { float expected; gfx::Vector3dF input1; @@ -291,7 +291,7 @@ } } -TEST(Vector3dTest, ClockwiseAngleBetweenVectorsInDegress) { +TEST(Vector3dFTest, ClockwiseAngleBetweenVectorsInDegress) { const struct { float expected; gfx::Vector3dF input1; @@ -320,7 +320,7 @@ } } -TEST(Vector3dTest, GetNormalized) { +TEST(Vector3dFTest, GetNormalized) { const struct { bool expected; gfx::Vector3dF v; @@ -346,4 +346,8 @@ } } +TEST(Vector3dFTest, ToString) { + EXPECT_EQ("[1.03125 2.5 -3]", Vector3dF(1.03125, 2.5, -3).ToString()); +} + } // namespace gfx
diff --git a/ui/gfx/image/mojom/BUILD.gn b/ui/gfx/image/mojom/BUILD.gn index dd07e3cbc..1df60a1 100644 --- a/ui/gfx/image/mojom/BUILD.gn +++ b/ui/gfx/image/mojom/BUILD.gn
@@ -7,6 +7,8 @@ mojom("mojom") { sources = [ "image.mojom" ] + webui_module_path = "chrome://resources/mojo/ui/gfx/image/mojom" + public_deps = [ "//skia/public/mojom" ] cpp_typemaps = [
diff --git a/ui/gfx/mojom/BUILD.gn b/ui/gfx/mojom/BUILD.gn index 48e07a7..7d991327 100644 --- a/ui/gfx/mojom/BUILD.gn +++ b/ui/gfx/mojom/BUILD.gn
@@ -38,6 +38,7 @@ "//skia/public/mojom", "//ui/gfx/geometry/mojom", ] + webui_module_path = "chrome://resources/mojo/ui/gfx/mojom" enabled_features = [] if (ozone_platform_x11) { @@ -335,6 +336,7 @@ } public_deps = [ "//mojo/public/mojom/base" ] generate_java = true + webui_module_path = "chrome://resources/mojo/ui/gfx/mojom" shared_cpp_typemap = { types = [
diff --git a/ui/gfx/native_pixmap.h b/ui/gfx/native_pixmap.h index 7ce49ea..a880df80 100644 --- a/ui/gfx/native_pixmap.h +++ b/ui/gfx/native_pixmap.h
@@ -5,7 +5,6 @@ #ifndef UI_GFX_NATIVE_PIXMAP_H_ #define UI_GFX_NATIVE_PIXMAP_H_ -#include "base/bind.h" #include "base/memory/ref_counted.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/size.h"
diff --git a/ui/gfx/platform_font_skia.cc b/ui/gfx/platform_font_skia.cc index fe80a2c..6216dc2 100644 --- a/ui/gfx/platform_font_skia.cc +++ b/ui/gfx/platform_font_skia.cc
@@ -95,7 +95,7 @@ // PlatformFontSkia, public: PlatformFontSkia::PlatformFontSkia() { - CHECK(InitDefaultFont()) << "Could not find the default font"; + EnsuresDefaultFontIsInitialized(); InitFromPlatformFont(g_default_font.Get().get()); } @@ -142,11 +142,10 @@ // PlatformFontSkia, PlatformFont implementation: // static -bool PlatformFontSkia::InitDefaultFont() { +void PlatformFontSkia::EnsuresDefaultFontIsInitialized() { if (g_default_font.Get()) - return true; + return; - bool success = false; std::string family = kFallbackFontFamilyName; int size_pixels = PlatformFont::kDefaultBaseFontSize; int style = Font::NORMAL; @@ -191,13 +190,13 @@ params = gfx::GetFontRenderParams(FontRenderParamsQuery(), nullptr); } + bool success = false; sk_sp<SkTypeface> typeface = CreateSkTypeface(style & Font::ITALIC, weight, &family, &success); - if (!success) - return false; + CHECK(success); + g_default_font.Get() = new PlatformFontSkia( std::move(typeface), family, size_pixels, style, weight, params); - return true; } // static @@ -341,9 +340,7 @@ &font_family_, &success); if (!success) { - LOG(ERROR) << "Could not find any font: " << font_family << ", " - << kFallbackFontFamilyName << ". Falling back to the default"; - + EnsuresDefaultFontIsInitialized(); InitFromPlatformFont(g_default_font.Get().get()); return; }
diff --git a/ui/gfx/platform_font_skia.h b/ui/gfx/platform_font_skia.h index e9a878f3..0cea0409 100644 --- a/ui/gfx/platform_font_skia.h +++ b/ui/gfx/platform_font_skia.h
@@ -31,10 +31,8 @@ PlatformFontSkia(const PlatformFontSkia&) = delete; PlatformFontSkia& operator=(const PlatformFontSkia&) = delete; - // Initials the default PlatformFont. Returns true if this is successful, or - // false if fonts resources are not available. If this returns false, the - // calling service should shut down. - static bool InitDefaultFont(); + // Initializes the default PlatformFont. + static void EnsuresDefaultFontIsInitialized(); // Resets and reloads the cached system font used by the default constructor. // This function is useful when the system font has changed, for example, when
diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc index 9d2c0c8..4dca245 100644 --- a/ui/gl/gl_image.cc +++ b/ui/gl/gl_image.cc
@@ -4,6 +4,7 @@ #include "ui/gl/gl_image.h" +#include "base/notreached.h" #include "ui/gl/gl_bindings.h" #if defined(OS_ANDROID)
diff --git a/ui/gl/gl_image_stub.cc b/ui/gl/gl_image_stub.cc index 56782e1..1267d83 100644 --- a/ui/gl/gl_image_stub.cc +++ b/ui/gl/gl_image_stub.cc
@@ -6,6 +6,7 @@ #include <GL/gl.h> +#include "base/notreached.h" #include "ui/gfx/gpu_fence.h" namespace gl {
diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h index c5c4f84..9fa86c5b 100644 --- a/ui/latency/latency_info.h +++ b/ui/latency/latency_info.h
@@ -94,14 +94,13 @@ LAST = OTHER, }; -// TODO(crbug.com/1101000): Some of the data in `LatencyInfo` is only used for +// TODO(crbug.com/1101000): Some of the data in `LatencyInfo` were only used for // calculating AverageLag metrics, namely: // - `INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT_COMPONENT` component; // - `scroll_update_delta_`; and // - `predicted_scroll_update_delta_`. -// Equivalent data is added to `cc::EventMetrics` to be used instead. Remove -// data from `LatencyInfo` when AverageLag metrics switch to use -// `cc::EventMetrics`. +// Equivalent data is now added to `cc::EventMetrics` and used in calculating +// AverageLag metrics. Remove unused data from `LatencyInfo`. class LatencyInfo { public: enum : size_t { kMaxInputCoordinates = 2 };
diff --git a/ui/ozone/platform/drm/host/host_cursor_proxy.cc b/ui/ozone/platform/drm/host/host_cursor_proxy.cc index 28c65ed..cbe49db 100644 --- a/ui/ozone/platform/drm/host/host_cursor_proxy.cc +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "ui/ozone/public/gpu_platform_support_host.h"
diff --git a/ui/ozone/platform/flatland/flatland_surface_factory.cc b/ui/ozone/platform/flatland/flatland_surface_factory.cc index cd2625d4..ba138f6 100644 --- a/ui/ozone/platform/flatland/flatland_surface_factory.cc +++ b/ui/ozone/platform/flatland/flatland_surface_factory.cc
@@ -234,6 +234,20 @@ CreateNativePixmap(widget, vk_device, size, format, usage)); } +scoped_refptr<gfx::NativePixmap> +FlatlandSurfaceFactory::CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) { + auto collection = flatland_sysmem_buffer_manager_.GetCollectionById( + handle.buffer_collection_id.value()); + if (!collection) + return nullptr; + + return collection->CreateNativePixmap(handle.buffer_index); +} + #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> FlatlandSurfaceFactory::CreateVulkanImplementation(
diff --git a/ui/ozone/platform/flatland/flatland_surface_factory.h b/ui/ozone/platform/flatland/flatland_surface_factory.h index c9fcf17..ae6a3752 100644 --- a/ui/ozone/platform/flatland/flatland_surface_factory.h +++ b/ui/ozone/platform/flatland/flatland_surface_factory.h
@@ -60,6 +60,11 @@ gfx::BufferFormat format, gfx::BufferUsage usage, NativePixmapCallback callback) override; + scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) override; #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation( bool use_swiftshader,
diff --git a/ui/ozone/platform/scenic/scenic_surface_factory.cc b/ui/ozone/platform/scenic/scenic_surface_factory.cc index e53d805..6b20a49 100644 --- a/ui/ozone/platform/scenic/scenic_surface_factory.cc +++ b/ui/ozone/platform/scenic/scenic_surface_factory.cc
@@ -253,6 +253,20 @@ CreateNativePixmap(widget, vk_device, size, format, usage)); } +scoped_refptr<gfx::NativePixmap> +ScenicSurfaceFactory::CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) { + auto collection = sysmem_buffer_manager_.GetCollectionById( + handle.buffer_collection_id.value()); + if (!collection) + return nullptr; + + return collection->CreateNativePixmap(handle.buffer_index); +} + #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> ScenicSurfaceFactory::CreateVulkanImplementation(bool use_swiftshader,
diff --git a/ui/ozone/platform/scenic/scenic_surface_factory.h b/ui/ozone/platform/scenic/scenic_surface_factory.h index 2a3d5b9..a4164fa8 100644 --- a/ui/ozone/platform/scenic/scenic_surface_factory.h +++ b/ui/ozone/platform/scenic/scenic_surface_factory.h
@@ -64,6 +64,11 @@ gfx::BufferFormat format, gfx::BufferUsage usage, NativePixmapCallback callback) override; + scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + gfx::BufferFormat format, + gfx::NativePixmapHandle handle) override; #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation( bool use_swiftshader,
diff --git a/ui/ozone/platform/wayland/OWNERS b/ui/ozone/platform/wayland/OWNERS index 9469bd25..72721318 100644 --- a/ui/ozone/platform/wayland/OWNERS +++ b/ui/ozone/platform/wayland/OWNERS
@@ -2,3 +2,4 @@ nickdiego@igalia.com tonikitoo@igalia.com adunaev@igalia.com +fangzhoug@chromium.org
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index 276bee4..5c29233 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -102,10 +102,6 @@ event_watcher_->StartProcessingEvents(); } -void WaylandEventSource::StopProcessingEvents() { - event_watcher_->StopProcessingEvents(); -} - void WaylandEventSource::OnKeyboardFocusChanged(WaylandWindow* window, bool focused) { DCHECK(window); @@ -473,6 +469,10 @@ StartProcessingEvents(); } +void WaylandEventSource::StopProcessingEventsForTesting() { + event_watcher_->StopProcessingEvents(); +} + void WaylandEventSource::OnWindowRemoved(WaylandWindow* window) { if (connection_->IsDragInProgress()) { auto* target_window = window_manager_->GetCurrentTouchFocusedWindow();
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index 32e85251..6768bf2 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -75,8 +75,6 @@ // This method assumes connection is already estabilished and input objects // are already bound and properly initialized. void StartProcessingEvents(); - // Stops polling for events from input devices. - void StopProcessingEvents(); // Allow to explicitly reset pointer flags. Required in cases where the // pointer state is modified by a button pressed event, but the respective @@ -157,6 +155,7 @@ // PlatformEventSource: void OnDispatcherListChanged() override; + void StopProcessingEventsForTesting() override; // WaylandWindowObserver: void OnWindowRemoved(WaylandWindow* window) override;
diff --git a/ui/ozone/platform/wayland/host/wayland_event_watcher.cc b/ui/ozone/platform/wayland/host/wayland_event_watcher.cc index db41e1db..535018ec 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_watcher.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_watcher.cc
@@ -27,19 +27,6 @@ namespace { -// Signals |event| after dispatching the pending tasks. -void DispatchPending(wl_display* display, - wl_event_queue* event_queue, - base::WaitableEvent* event) { - // wl_display_dispatch_queue_pending may block if dispatching events results - // in a tab dragging that spins a run loop, which doesn't return until it's - // over. Thus, signal before this function is called. - if (event) - event->Signal(); - - wl_display_dispatch_queue_pending(display, event_queue); -} - void wayland_log(const char* fmt, va_list argp) { LOG(WARNING) << "libwayland: " << base::StringPrintV(fmt, argp); } @@ -98,13 +85,14 @@ void WaylandEventWatcher::StartProcessingEvents() { if (!ui_thread_task_runner_) ui_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + weak_this_ = weak_factory_.GetWeakPtr(); if (use_dedicated_polling_thread_ && !thread_) { // FD watching will happen on a different thread. DETACH_FROM_THREAD(thread_checker_); thread_ = std::make_unique<WaylandEventWatcherThread>( base::BindOnce(&WaylandEventWatcher::StartProcessingEventsInternal, - weak_factory_.GetWeakPtr())); + base::Unretained(this))); base::Thread::Options thread_options; thread_options.message_pump_type = base::MessagePumpType::UI; @@ -123,14 +111,18 @@ } void WaylandEventWatcher::StopProcessingEvents() { + shutting_down_ = true; if (!watching_) return; if (use_dedicated_polling_thread_) { + // This object is constructed and destroyed on the main thread. As such, it + // doesn't makes sense to pass a WeakPtr bound to the main thread for + // dereferencing on the watching thread. This code has never worked. watching_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandEventWatcher::StopProcessingEventsInternal, - weak_factory_.GetWeakPtr())); + base::Unretained(this))); } else { StopProcessingEventsInternal(); } @@ -238,13 +230,18 @@ } void WaylandEventWatcher::DispatchPendingQueue() { + // Once the class is shutting down, never dispatch any more events. + if (shutting_down_) + return; + if (ui_thread_task_runner_->BelongsToCurrentThread()) { DCHECK(!use_dedicated_polling_thread_); - DispatchPending(display_, event_queue_, nullptr); + DispatchPendingMainThread(nullptr); } else { DCHECK(use_dedicated_polling_thread_); base::WaitableEvent event; - auto cb = base::BindOnce(&DispatchPending, display_, event_queue_, &event); + auto cb = base::BindOnce(&WaylandEventWatcher::DispatchPendingMainThread, + weak_this_, &event); ui_thread_task_runner_->PostTask(FROM_HERE, std::move(cb)); // The point of the dedicated polling thread is to let the main thread know @@ -256,6 +253,19 @@ } } +void WaylandEventWatcher::DispatchPendingMainThread( + base::WaitableEvent* event) { + // wl_display_dispatch_queue_pending may block if dispatching events results + // in a tab dragging that spins a run loop, which doesn't return until it's + // over. Thus, signal before this function is called. + if (event) + event->Signal(); + + if (!shutting_down_) { + wl_display_dispatch_queue_pending(display_, event_queue_); + } +} + bool WaylandEventWatcher::CheckForErrors() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Errors are fatal. If this function returns non-zero the display can no
diff --git a/ui/ozone/platform/wayland/host/wayland_event_watcher.h b/ui/ozone/platform/wayland/host/wayland_event_watcher.h index ee4749e3..9c760fe 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_watcher.h +++ b/ui/ozone/platform/wayland/host/wayland_event_watcher.h
@@ -17,6 +17,7 @@ namespace base { class Thread; class SingleThreadTaskRunner; +class WaitableEvent; } // namespace base namespace ui { @@ -58,6 +59,10 @@ void MaybePrepareReadQueue(); void DispatchPendingQueue(); + // Dispatches pending tasks. Must only be called on main thread. + // Signals |event| before dispatching the pending tasks. + void DispatchPendingMainThread(base::WaitableEvent* event); + // Checks if |display_| has any error set. If so, |shutdown_cb_| is executed // and false is returned. bool CheckForErrors(); @@ -66,6 +71,7 @@ wl_display* const display_; // Owned by WaylandConnection. wl_event_queue* const event_queue_; // Owned by WaylandConnection. + base::WeakPtr<WaylandEventWatcher> weak_this_; // Bound to the main thread. bool watching_ = false; bool prepared_ = false; @@ -81,6 +87,12 @@ // ozone_unittests run. bool use_dedicated_polling_thread_ = true; + // Set to true when the event watcher begins to shut down. Setting this to + // true has two effects: + // (1) the main thread will stop dispatching queued events + // (2) the polling thread will stop posting tasks to the main thread. + std::atomic<bool> shutting_down_{false}; + base::OnceCallback<void()> shutdown_cb_; // Used to verify watching the fd happens on a valid thread. @@ -97,6 +109,7 @@ // The thread's task runner where the wl_display's fd is being watched. scoped_refptr<base::SingleThreadTaskRunner> watching_thread_task_runner_; + // This weak factory must only be accessed on the main thread. base::WeakPtrFactory<WaylandEventWatcher> weak_factory_{this}; };
diff --git a/ui/ozone/platform/wayland/host/wayland_frame_manager.cc b/ui/ozone/platform/wayland/host/wayland_frame_manager.cc index 569526c7..b825eea 100644 --- a/ui/ozone/platform/wayland/host/wayland_frame_manager.cc +++ b/ui/ozone/platform/wayland/host/wayland_frame_manager.cc
@@ -104,6 +104,8 @@ subsurface_to_overlay.second->buffer_id); // Buffer is gone while this frame is pending, remove this config. if (!handle) { + frame->buffer_id = subsurface_to_overlay.second->buffer_id; + frame->buffer_lost = true; subsurface_to_overlay.second.reset(); } else if (!handle->wl_buffer() && !handle_pending_creation) { // Found the first not-ready buffer, let handle invoke @@ -116,6 +118,8 @@ auto* handle = connection_->buffer_manager_host()->EnsureBufferHandle( frame->root_surface, frame->root_config->buffer_id); if (!handle) { + frame->buffer_id = frame->root_config->buffer_id; + frame->buffer_lost = true; frame->root_config.reset(); } else if (!handle->wl_buffer() && !handle_pending_creation) { handle_pending_creation = handle; @@ -142,9 +146,26 @@ PlayBackFrame(std::move(playback)); pending_frames_.pop_front(); + + // wl_frame_callback drives the continuous playback of frames, if the frame we + // just played-back did not set up a wl_frame_callback, we should playback + // another frame. + if (!submitted_frames_.empty() && + !submitted_frames_.back()->wl_frame_callback) { + MaybeProcessPendingFrame(); + } } void WaylandFrameManager::PlayBackFrame(std::unique_ptr<WaylandFrame> frame) { + // Skip this frame if we can't playback this frame due to lost buffers. + if (frame->buffer_lost) { + frame->feedback = gfx::PresentationFeedback::Failure(); + submitted_frames_.push_back(std::move(frame)); + VerifyNumberOfSubmittedFrames(); + MaybeProcessSubmittedFrames(); + return; + } + auto* root_surface = frame->root_surface; auto& root_config = frame->root_config; bool empty_frame = !root_config || !root_config->buffer_id; @@ -379,7 +400,7 @@ // Investigate the issue with surface sync. frame->feedback = gfx::PresentationFeedback::Failure(); } - CHECK_NE(frame, submitted_frames_.back()); + CHECK_NE(frame.get(), submitted_frames_.back().get()); } MaybeProcessSubmittedFrames(); }
diff --git a/ui/ozone/platform/wayland/host/wayland_frame_manager.h b/ui/ozone/platform/wayland/host/wayland_frame_manager.h index 4d601a474..8f1a035 100644 --- a/ui/ozone/platform/wayland/host/wayland_frame_manager.h +++ b/ui/ozone/platform/wayland/host/wayland_frame_manager.h
@@ -60,6 +60,10 @@ // Used to invoke buffer_manager_host OnSubmission and OnPrensentation calls. uint32_t buffer_id; + // An indicator that there are buffers destrotyed before frame playback. This + // frame should be skipped. + bool buffer_lost = false; + // A Wayland callback, which is triggered once wl_buffer has been committed // and it is the right time to notify the GPU that it can start a new drawing // operation.
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index eb1d9b6..a23ec63 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -69,7 +69,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) shell_toplevel_->SetAppId(window_unique_id_); #else - shell_toplevel_->SetAppId(wm_class_class_); + shell_toplevel_->SetAppId(app_id_); #endif shell_toplevel_->SetTitle(window_title_); SetSizeConstraints(); @@ -239,7 +239,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) return window_unique_id_; #else - return wm_class_class_; + return app_id_; #endif } @@ -420,7 +420,7 @@ window_unique_id_ = std::string(crosapi::kLacrosAppIdPrefix) + token.ToString(); #else - wm_class_class_ = properties.wm_class_class; + app_id_ = properties.wayland_app_id; #endif SetWaylandExtension(this, static_cast<WaylandExtension*>(this)); SetWmMoveLoopHandler(this, static_cast<WmMoveLoopHandler*>(this));
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h index 909f33d..9e26791 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -205,10 +205,10 @@ std::string window_unique_id_; #else // Id of the chromium app passed through - // PlatformWindowInitProperties::wm_class_class. This is used by Wayland + // PlatformWindowInitProperties::wm_class_name. This is used by Wayland // compositor to identify the app, unite it's windows into the same stack of // windows and find *.desktop file to set various preferences including icons. - std::string wm_class_class_; + std::string app_id_; #endif // Title of the ShellToplevel.
diff --git a/ui/ozone/public/overlay_candidates_ozone.cc b/ui/ozone/public/overlay_candidates_ozone.cc index e6cc3c8..2973027 100644 --- a/ui/ozone/public/overlay_candidates_ozone.cc +++ b/ui/ozone/public/overlay_candidates_ozone.cc
@@ -4,7 +4,7 @@ #include "ui/ozone/public/overlay_candidates_ozone.h" -#include <stdlib.h> +#include "base/notreached.h" namespace ui {
diff --git a/ui/platform_window/platform_window_init_properties.h b/ui/platform_window/platform_window_init_properties.h index 796dee0..fbdfb84 100644 --- a/ui/platform_window/platform_window_init_properties.h +++ b/ui/platform_window/platform_window_init_properties.h
@@ -125,6 +125,10 @@ std::string wm_class_class; X11ExtensionDelegate* x11_extension_delegate = nullptr; + + // Wayland specific. Holds the application ID that is used by the window + // manager to match the desktop entry and group windows. + std::string wayland_app_id; #endif bool enable_compositing_based_throttling = false;
diff --git a/ui/platform_window/x11/x11_topmost_window_finder.cc b/ui/platform_window/x11/x11_topmost_window_finder.cc index 50e75e17..e20bf0ab 100644 --- a/ui/platform_window/x11/x11_topmost_window_finder.cc +++ b/ui/platform_window/x11/x11_topmost_window_finder.cc
@@ -44,15 +44,8 @@ for (iter = windows.rbegin(); iter != windows.rend(); iter++) { if (IsWindowNamed(*iter) && should_stop_iterating.Run(*iter)) return true; - } - - // If we're at this point, we didn't find the window we're looking for at the - // current level, so we need to recurse to the next level. We use a second - // loop because the recursion and call to XQueryTree are expensive and is only - // needed for a small number of cases. - if (++depth <= max_depth) { - for (iter = windows.rbegin(); iter != windows.rend(); iter++) { - if (EnumerateChildren(should_stop_iterating, *iter, max_depth, depth)) + if (depth < max_depth) { + if (EnumerateChildren(should_stop_iterating, *iter, max_depth, depth + 1)) return true; } } @@ -68,9 +61,9 @@ void EnumerateTopLevelWindows( ui::ShouldStopIteratingCallback should_stop_iterating) { - // Some WMs parent 'top-level' windows in unnamed actual top-level windows - // (ion WM), so extend the search depth to all children of top-level windows. - const int kMaxSearchDepth = 1; + // WMs may reparent toplevel windows inside their own containers, so extend + // the search to all grandchildren of all toplevel windows. + const int kMaxSearchDepth = 2; ui::EnumerateAllWindows(should_stop_iterating, kMaxSearchDepth); }
diff --git a/ui/views/.clang-tidy b/ui/views/.clang-tidy index 09fa855..d42851ef 100644 --- a/ui/views/.clang-tidy +++ b/ui/views/.clang-tidy
@@ -1,6 +1,7 @@ --- Checks: 'google-build-namespaces, google-readability-namespace-comments, + modernize-concat-nested-namespaces, modernize-replace-auto-ptr, modernize-use-using' HeaderFilterRegex: 'ui/views/*'
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc index b8dade0..b6783e98 100644 --- a/ui/views/controls/button/toggle_button.cc +++ b/ui/views/controls/button/toggle_button.cc
@@ -71,8 +71,8 @@ // Returns the extra space needed to draw the shadows around the thumb. Since // the extra space is around the thumb, the insets will be negative. static gfx::Insets GetShadowOutsets() { - return gfx::Insets(-kShadowBlur) - .Offset(gfx::Vector2d(kShadowOffsetX, kShadowOffsetY)); + return gfx::Insets(-kShadowBlur) + + gfx::Vector2d(kShadowOffsetX, kShadowOffsetY); } void SetThumbColor(bool is_on, const absl::optional<SkColor>& thumb_color) {
diff --git a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc index f0ea123..ec662bc8 100644 --- a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc +++ b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc
@@ -366,16 +366,20 @@ InitEditableCombobox(); ClickArrow(); EXPECT_TRUE(IsMenuOpen()); - parent_of_combobox_->RemoveChildView(combobox_); + auto combobox = parent_of_combobox_->RemoveChildViewT(combobox_); EXPECT_EQ(nullptr, combobox_->GetMenuRunnerForTest()); + combobox_ = nullptr; } TEST_F(EditableComboboxTest, RemovingParentOfControlWhileMenuOpenClosesMenu) { InitEditableCombobox(); ClickArrow(); EXPECT_TRUE(IsMenuOpen()); - widget_->GetContentsView()->RemoveChildView(parent_of_combobox_); + auto parent = + widget_->GetContentsView()->RemoveChildViewT(parent_of_combobox_); EXPECT_EQ(nullptr, combobox_->GetMenuRunnerForTest()); + combobox_ = nullptr; + parent_of_combobox_ = nullptr; } TEST_F(EditableComboboxTest, LeftOrRightKeysMoveInTextfield) {
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index 2339422..c47afc89 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc
@@ -302,6 +302,10 @@ SetHeaderImpl(nullptr); } +void ScrollView::SetPreferredViewportMargins(const gfx::Insets& margins) { + preferred_viewport_margins_ = margins; +} + void ScrollView::SetBackgroundColor(const absl::optional<SkColor>& color) { if (background_color_ == color && !background_color_id_) return; @@ -921,22 +925,26 @@ return; } + gfx::Rect contents_region = rect; + contents_region.Inset(-preferred_viewport_margins_); + // Figure out the maximums for this scroll view. const int contents_max_x = std::max(contents_viewport_->width(), contents_->width()); const int contents_max_y = std::max(contents_viewport_->height(), contents_->height()); - int x = base::clamp(rect.x(), 0, contents_max_x); - int y = base::clamp(rect.y(), 0, contents_max_y); + int x = base::clamp(contents_region.x(), 0, contents_max_x); + int y = base::clamp(contents_region.y(), 0, contents_max_y); // Figure out how far and down the rectangle will go taking width // and height into account. This will be "clipped" by the viewport. const int max_x = std::min( - contents_max_x, x + std::min(rect.width(), contents_viewport_->width())); - const int max_y = - std::min(contents_max_y, - y + std::min(rect.height(), contents_viewport_->height())); + contents_max_x, + x + std::min(contents_region.width(), contents_viewport_->width())); + const int max_y = std::min( + contents_max_y, + y + std::min(contents_region.height(), contents_viewport_->height())); // See if the rect is already visible. Note the width is (max_x - x) // and the height is (max_y - y) to take into account the clipping of
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h index c6ba19918..320e062c 100644 --- a/ui/views/controls/scroll_view.h +++ b/ui/views/controls/scroll_view.h
@@ -118,6 +118,10 @@ int GetMinHeight() const { return min_height_; } + // Sets the preferred margins within the scroll viewport - when scrolling + // rects to visible, these margins will be added to the visible rect. + void SetPreferredViewportMargins(const gfx::Insets& margins); + // The background color can be configured in two distinct ways: // . By way of SetBackgroundThemeColorId(). This is the default and when // called the background color comes from the theme (and changes if the @@ -380,6 +384,8 @@ // The layer type used for content view when scroll by layers is enabled. ui::LayerType layer_type_ = ui::LAYER_TEXTURED; + gfx::Insets preferred_viewport_margins_; + // Scrolling callbacks. ScrollViewCallbackList on_contents_scrolled_; ScrollViewCallbackList on_contents_scroll_ended_;
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index eb0058f9..e350876e 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -853,7 +853,7 @@ // Remove the virtual views that are no longer needed. auto& virtual_children = GetViewAccessibility().virtual_children(); - for (int i = start; i < start + length; i++) + for (int i = start; !virtual_children.empty() && i < start + length; i++) virtual_children[virtual_children.size() - 1]->RemoveFromParentView(); UpdateVirtualAccessibilityChildrenBounds(); @@ -1648,7 +1648,11 @@ // Update the bounds for the table's content rows. for (int row_index = 0; row_index < GetRowCount(); row_index++) { - auto& ax_row = virtual_children[header_ ? row_index + 1 : row_index]; + const size_t ax_row_index = header_ ? row_index + 1 : row_index; + if (ax_row_index >= virtual_children.size()) + break; + + auto& ax_row = virtual_children[ax_row_index]; ui::AXNodeData& row_data = ax_row->GetCustomData(); DCHECK_EQ(row_data.role, ax::mojom::Role::kRow); row_data.relative_bounds.bounds =
diff --git a/ui/views/controls/table/table_view_unittest.cc b/ui/views/controls/table/table_view_unittest.cc index e06a0dc..7e4281f 100644 --- a/ui/views/controls/table/table_view_unittest.cc +++ b/ui/views/controls/table/table_view_unittest.cc
@@ -804,6 +804,19 @@ EXPECT_EQ("rows=0 4 cols=0 2", helper_->GetPaintRegion(table_->bounds())); } +// Regression tests for https://crbug.com/1283805, and +// https://crbug.com/1283807. +TEST_P(TableViewTest, NoCrashesWithAllColumnsHidden) { + // Set both initially visible columns hidden. + table_->SetColumnVisibility(0, false); + table_->SetColumnVisibility(1, false); + EXPECT_EQ(0u, helper_->visible_col_count()); + + // Remove and add rows in this state, there should be no crashes. + model_->RemoveRow(0); + model_->AddRows(1, 2, /*value_multiplier=*/10); +} + // Verifies resizing a column using the mouse works. TEST_P(TableViewTest, Resize) { const int x = table_->GetVisibleColumn(0).width;
diff --git a/ui/views/controls/webview/webview_unittest.cc b/ui/views/controls/webview/webview_unittest.cc index e9f781f..60b4ee89 100644 --- a/ui/views/controls/webview/webview_unittest.cc +++ b/ui/views/controls/webview/webview_unittest.cc
@@ -271,7 +271,14 @@ web_view()->SetWebContents(web_contents1.get()); // Layout() is normally async, call it now to ensure visibility is updated. web_view()->Layout(); +#if defined(USE_AURA) EXPECT_EQ(1, observer1.shown_count()); +#else + // On Mac, setting the web contents adds a WebContentsViewCocoa + // to the view hierarchy. The window change (from nil to non-nil) + // generates one more web contents visibility update that Aura. + EXPECT_EQ(2, observer1.shown_count()); +#endif // Nothing else should change. EXPECT_EQ(1, observer1.hidden_count());
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc index 80d1019..a41611a 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
@@ -370,6 +370,8 @@ properties->wm_class_class = params.wm_class_class; properties->wm_role_name = params.wm_role_name; + properties->wayland_app_id = params.wayland_app_id; + DCHECK(!properties->x11_extension_delegate); properties->x11_extension_delegate = this; }
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 3d70ff878..5ca3597 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -1007,6 +1007,15 @@ delegate_->OnNativeWidgetEndUserBoundsChange(); } +void NativeWidgetAura::OnWindowAddedToRootWindow(aura::Window* window) { + delegate_->OnNativeWidgetAddedToCompositor(); +} + +void NativeWidgetAura::OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) { + delegate_->OnNativeWidgetRemovingFromCompositor(); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWidgetAura, ui::EventHandler implementation:
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index 50edf92..84248c99 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h
@@ -197,6 +197,9 @@ intptr_t old) override; void OnResizeLoopStarted(aura::Window* window) override; void OnResizeLoopEnded(aura::Window* window) override; + void OnWindowAddedToRootWindow(aura::Window* window) override; + void OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) override; // ui::EventHandler: void OnKeyEvent(ui::KeyEvent* event) override;
diff --git a/ui/views/widget/native_widget_delegate.h b/ui/views/widget/native_widget_delegate.h index f3239499f..effdec1b 100644 --- a/ui/views/widget/native_widget_delegate.h +++ b/ui/views/widget/native_widget_delegate.h
@@ -106,6 +106,12 @@ virtual void OnNativeWidgetBeginUserBoundsChange() = 0; virtual void OnNativeWidgetEndUserBoundsChange() = 0; + // Called when the NativeWidget is added and/or being removed from a + // Compositor. On some platforms the Compositor never changes, and these + // functions are never called. + virtual void OnNativeWidgetAddedToCompositor() = 0; + virtual void OnNativeWidgetRemovingFromCompositor() = 0; + // Returns true if the delegate has a FocusManager. virtual bool HasFocusManager() const = 0;
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index ef8434f6..e3dbf3a 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -1451,6 +1451,10 @@ widget_delegate_->OnWindowEndUserBoundsChange(); } +void Widget::OnNativeWidgetAddedToCompositor() {} + +void Widget::OnNativeWidgetRemovingFromCompositor() {} + bool Widget::HasFocusManager() const { return !!focus_manager_.get(); }
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 5225b04..0bcdee1 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -374,6 +374,9 @@ std::string wm_class_name; std::string wm_class_class; + // Only used by Wayland, for root level windows. + std::string wayland_app_id; + // If true then the widget uses software compositing. bool force_software_compositing = false; @@ -1019,6 +1022,8 @@ void OnNativeWidgetWindowShowStateChanged() override; void OnNativeWidgetBeginUserBoundsChange() override; void OnNativeWidgetEndUserBoundsChange() override; + void OnNativeWidgetAddedToCompositor() override; + void OnNativeWidgetRemovingFromCompositor() override; bool HasFocusManager() const override; void OnNativeWidgetPaint(const ui::PaintContext& context) override; int GetNonClientComponent(const gfx::Point& point) override;
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn index 7d22026..c1c6591 100644 --- a/ui/webui/resources/BUILD.gn +++ b/ui/webui/resources/BUILD.gn
@@ -49,6 +49,7 @@ if (include_polymer) { deps += [ "cr_components:build_grdp", + "cr_components/app_management:build_grdp", "cr_components/customize_themes:build_grdp", "cr_components/most_visited:build_grdp", "cr_elements:build_grdp", @@ -60,6 +61,7 @@ "$root_gen_dir/ui/webui/resources/cr_components/cr_components_resources.grdp", "$root_gen_dir/ui/webui/resources/cr_components/customize_themes/resources.grdp", "$root_gen_dir/ui/webui/resources/cr_components/most_visited/resources.grdp", + "$root_gen_dir/ui/webui/resources/cr_components/app_management/resources.grdp", "$root_gen_dir/ui/webui/resources/cr_elements/cr_elements_resources.grdp", "$root_gen_dir/ui/webui/resources/js/browser_command/resources.grdp", ]
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn index 24ff94a..9f7e1b3 100644 --- a/ui/webui/resources/cr_components/BUILD.gn +++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -12,7 +12,6 @@ "$root_gen_dir/ui/webui/resources/preprocessed/cr_components" preprocess_gen_manifest = "preprocessed_gen_manifest.json" preprocess_mojom_manifest = "preprocessed_mojom_manifest.json" -preprocess_external_mojo_manifest = "preprocessed_external_mojo_manifest.json" if (is_chromeos_ash) { preprocess_polymer2_manifest = "preprocessed_polymer2_manifest.json" } @@ -21,10 +20,7 @@ generate_grd("build_grdp") { grd_prefix = "cr_components" out_grd = "$target_gen_dir/${grd_prefix}_resources.grdp" - deps = [ - ":preprocess", - ":preprocess_external_mojo", - ] + deps = [ ":preprocess" ] if (is_chromeos_ash) { input_files_base_dir = rebase_path(".", "//") input_files = [ @@ -68,7 +64,6 @@ "$target_gen_dir/$preprocess_gen_manifest", "$target_gen_dir/$preprocess_mojom_manifest", "$target_gen_dir/$preprocess_src_manifest", - "$target_gen_dir/$preprocess_external_mojo_manifest", ] # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS. @@ -77,13 +72,6 @@ } resource_path_prefix = "cr_components" - - resource_path_rewrites = [ - "mojo/public/mojom/base/file_path.mojom-lite.js|app_management/file_path.mojom-lite.js", - "mojo/public/mojom/base/safe_base_name.mojom-lite.js|app_management/safe_base_name.mojom-lite.js", - "ui/gfx/image/mojom/image.mojom-lite.js|app_management/image.mojom-lite.js", - "components/services/app_service/public/mojom/types.mojom-lite.js|app_management/types.mojom-lite.js", - ] } group("preprocess") { @@ -113,12 +101,6 @@ "chromeos/smb_shares/smb_browser_proxy.js", "color_change_listener/browser_proxy.js", "color_change_listener/colors_css_updater.js", - "app_management/permission_constants.js", - "app_management/permission_util.js", - "app_management/browser_proxy.js", - "app_management/constants.js", - "app_management/types.js", - "app_management/util.js", ] } @@ -131,10 +113,7 @@ } preprocess_if_expr("preprocess_generated") { - deps = [ - ":polymer3_elements", - "//ui/webui/resources/cr_components/app_management:mojo_bindings_js__generator", - ] + deps = [ ":polymer3_elements" ] in_folder = target_gen_dir out_folder = preprocess_folder out_manifest = "$target_gen_dir/$preprocess_gen_manifest" @@ -142,11 +121,6 @@ "managed_dialog/managed_dialog.js", "managed_footnote/managed_footnote.js", "omnibox/cr_autocomplete_match_list.js", - "app_management/permission_item.js", - "app_management/shared_style.js", - "app_management/shared_vars.js", - "app_management/toggle_row.js", - "app_management/app_management.mojom-lite.js", ] if (is_chromeos_ash) { @@ -418,7 +392,6 @@ group("closure_compile") { deps = [ - "app_management:closure_compile", "color_change_listener:closure_compile", "managed_dialog:closure_compile", "managed_footnote:closure_compile", @@ -432,7 +405,6 @@ group("polymer3_elements") { public_deps = [ - "app_management:web_components", "customize_themes:web_components", "iph_bubble:web_components", "managed_dialog:web_components", @@ -445,25 +417,3 @@ public_deps += [ "chromeos:polymer3_elements" ] } } - -preprocess_if_expr("preprocess_external_mojo") { - deps = [ - "//components/services/app_service/public/mojom:mojom_js", - "//mojo/public/js:bindings_lite", - "//mojo/public/mojom/base", - "//ui/gfx/image/mojom:mojom_js", - ] - in_folder = "$root_gen_dir" - - # It does not matter which preprocess folder these files are pasted into, as - # they are not used for bundling; the purpose of this build rule is to - # include them in the generated grd file. - out_folder = "$preprocess_folder" - out_manifest = "$target_gen_dir/$preprocess_external_mojo_manifest" - in_files = [ - "mojo/public/mojom/base/file_path.mojom-lite.js", - "mojo/public/mojom/base/safe_base_name.mojom-lite.js", - "ui/gfx/image/mojom/image.mojom-lite.js", - "components/services/app_service/public/mojom/types.mojom-lite.js", - ] -}
diff --git a/ui/webui/resources/cr_components/app_management/BUILD.gn b/ui/webui/resources/cr_components/app_management/BUILD.gn index e6bd6b82..19eaa2d 100644 --- a/ui/webui/resources/cr_components/app_management/BUILD.gn +++ b/ui/webui/resources/cr_components/app_management/BUILD.gn
@@ -3,95 +3,99 @@ # found in the LICENSE file. import("//mojo/public/tools/bindings/mojom.gni") -import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/preprocess_if_expr.gni") import("//tools/polymer/html_to_js.gni") +import("//tools/typescript/ts_library.gni") +import("//ui/webui/resources/tools/generate_grd.gni") -js_type_check("closure_compile") { - is_polymer3 = true - deps = [ - ":browser_proxy", - ":constants", - ":permission_constants", - ":permission_item", - ":permission_util", - ":shared_style", - ":shared_vars", - ":toggle_row", - ":types", - ":util", - ] -} +preprocess_folder_tmp = "$root_gen_dir/ui/webui/resources/preprocessed/cr_components/app_management_tmp" +preprocess_folder = + "$root_gen_dir/ui/webui/resources/preprocessed/cr_components/app_management" -js_library("permission_item") { - deps = [ - ":browser_proxy", - ":permission_constants", - ":toggle_row", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} +web_component_files = [ + "icons.ts", + "permission_item.ts", + "shared_style.ts", + "shared_vars.ts", + "toggle_row.ts", +] -js_library("shared_style") { - deps = [] -} - -js_library("shared_vars") { - deps = [] -} - -js_library("permission_constants") { - deps = [ ":mojo_bindings_js_library_for_compile" ] -} - -js_library("permission_util") { - deps = [ - ":permission_constants", - "//ui/webui/resources/js:assert.m", - ] -} - -js_library("browser_proxy") { - deps = [ - ":mojo_bindings_js_library_for_compile", - "//ui/webui/resources/js:cr.m", - ] -} - -js_library("toggle_row") { - deps = [ - ":types", - "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle.m", - "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m", - ] -} - -js_library("constants") { - deps = [ ":mojo_bindings_js_library_for_compile" ] -} - -js_library("types") { - deps = [] -} - -js_library("util") { - deps = [ ":permission_constants" ] - externs_list = [ "//third_party/closure_compiler/externs/metrics_private.js" ] -} +non_web_component_files = [ + "constants.ts", + "permission_constants.ts", + "permission_util.ts", + "browser_proxy.ts", + "util.ts", +] html_to_js("web_components") { - js_files = [ - "permission_item.js", - "shared_style.js", - "shared_vars.js", - "toggle_row.js", - ] + js_files = web_component_files } mojom("mojo_bindings") { sources = [ "app_management.mojom" ] + webui_module_path = "/" public_deps = [ "//components/services/app_service/public/mojom", "//mojo/public/mojom/base", ] } + +preprocess_if_expr("preprocess_src") { + visibility = [ ":build_ts" ] + in_folder = "." + out_folder = preprocess_folder_tmp + in_files = non_web_component_files +} + +preprocess_if_expr("preprocess_generated") { + visibility = [ ":build_ts" ] + deps = [ ":web_components" ] + in_folder = target_gen_dir + out_folder = preprocess_folder_tmp + in_files = web_component_files +} + +copy("copy_mojo") { + deps = [ + ":mojo_bindings_webui_js", + "//components/services/app_service/public/mojom:types_js__generator", + ] + sources = [ + "$root_gen_dir/mojom-webui/components/services/app_service/public/mojom/types.mojom-webui.js", + "$root_gen_dir/mojom-webui/ui/webui/resources/cr_components/app_management/app_management.mojom-webui.js", + ] + outputs = [ "$preprocess_folder_tmp/{{source_file_part}}" ] +} + +ts_library("build_ts") { + root_dir = preprocess_folder_tmp + out_dir = preprocess_folder + composite = true + tsconfig_base = "tsconfig_base.json" + in_files = web_component_files + non_web_component_files + [ + "app_management.mojom-webui.js", + "types.mojom-webui.js", + ] + + definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] + + deps = [ + "//third_party/polymer/v3_0:library", + "//ui/webui/resources:library", + ] + extra_deps = [ + ":copy_mojo", + ":preprocess_generated", + ":preprocess_src", + ] +} + +generate_grd("build_grdp") { + grd_prefix = "cr_components_app_management" + out_grd = "$target_gen_dir/resources.grdp" + deps = [ ":build_ts" ] + manifest_files = [ "$target_gen_dir/tsconfig.manifest" ] + resource_path_prefix = "cr_components/app_management" +}
diff --git a/ui/webui/resources/cr_components/app_management/browser_proxy.js b/ui/webui/resources/cr_components/app_management/browser_proxy.js deleted file mode 100644 index 983f19a..0000000 --- a/ui/webui/resources/cr_components/app_management/browser_proxy.js +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; -import 'chrome://resources/mojo/skia/public/mojom/image_info.mojom-lite.js'; -import 'chrome://resources/mojo/skia/public/mojom/bitmap.mojom-lite.js'; -import 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'; -import './file_path.mojom-lite.js'; -import './image.mojom-lite.js'; -import './types.mojom-lite.js'; -import './app_management.mojom-lite.js'; - -import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; - -export class BrowserProxy { - constructor() { - /** @type {appManagement.mojom.PageCallbackRouter} */ - this.callbackRouter = new appManagement.mojom.PageCallbackRouter(); - - /** @type {appManagement.mojom.PageHandlerRemote} */ - this.handler = new appManagement.mojom.PageHandlerRemote(); - const factory = appManagement.mojom.PageHandlerFactory.getRemote(); - factory.createPageHandler( - this.callbackRouter.$.bindNewPipeAndPassRemote(), - this.handler.$.bindNewPipeAndPassReceiver()); - } -} - -addSingletonGetter(BrowserProxy);
diff --git a/ui/webui/resources/cr_components/app_management/browser_proxy.ts b/ui/webui/resources/cr_components/app_management/browser_proxy.ts new file mode 100644 index 0000000..5843343 --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/browser_proxy.ts
@@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {PageCallbackRouter, PageHandlerFactory, PageHandlerInterface, PageHandlerRemote} from './app_management.mojom-webui.js'; + +export class BrowserProxy { + callbackRouter: PageCallbackRouter; + handler: PageHandlerInterface; + + constructor() { + this.callbackRouter = new PageCallbackRouter(); + + this.handler = new PageHandlerRemote(); + + const factory = PageHandlerFactory.getRemote(); + factory.createPageHandler( + this.callbackRouter.$.bindNewPipeAndPassRemote(), + (this.handler as PageHandlerRemote).$.bindNewPipeAndPassReceiver()); + } + + static getInstance(): BrowserProxy { + return instance || (instance = new BrowserProxy()); + } + + static setInstance(obj: BrowserProxy) { + instance = obj; + } +} + +let instance: BrowserProxy|null = null;
diff --git a/ui/webui/resources/cr_components/app_management/constants.js b/ui/webui/resources/cr_components/app_management/constants.js deleted file mode 100644 index 6130d23..0000000 --- a/ui/webui/resources/cr_components/app_management/constants.js +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; - -import 'chrome://resources/mojo/skia/public/mojom/image_info.mojom-lite.js'; -import 'chrome://resources/mojo/skia/public/mojom/bitmap.mojom-lite.js'; -import 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'; -import './file_path.mojom-lite.js'; -import './image.mojom-lite.js'; -import './safe_base_name.mojom-lite.js'; -import './types.mojom-lite.js'; -import './app_management.mojom-lite.js'; - -/** - * The number of apps displayed in app list in the main view before expanding. - * @const {number} - */ -export const NUMBER_OF_APPS_DISPLAYED_DEFAULT = 4; - -/** - * Enumeration of the different subpage types within the app management page. - * @enum {number} - * @const - */ -export const PageType = { - MAIN: 0, - DETAIL: 1, -}; - -export const AppType = apps.mojom.AppType; - -export const OptionalBool = apps.mojom.OptionalBool; - -export const InstallReason = apps.mojom.InstallReason; - -export const WindowMode = apps.mojom.WindowMode; - -// This histogram is also declared and used at chrome/browser/ui/webui/settings/ -// chromeos/app_management/app_management_uma.h. -export const AppManagementEntryPointsHistogramName = - 'AppManagement.EntryPoints'; - -/** - * These values are persisted to logs and should not be renumbered or re-used. - * See tools/metrics/histograms/enums.xml. - * @enum {number} - */ -export const AppManagementEntryPoint = { - AppListContextMenuAppInfoArc: 0, - AppListContextMenuAppInfoChromeApp: 1, - AppListContextMenuAppInfoWebApp: 2, - ShelfContextMenuAppInfoArc: 3, - ShelfContextMenuAppInfoChromeApp: 4, - ShelfContextMenuAppInfoWebApp: 5, - MainViewArc: 6, - MainViewChromeApp: 7, - MainViewWebApp: 8, - OsSettingsMainPage: 9, - MainViewPluginVm: 10, - DBusServicePluginVm: 11, - MainViewBorealis: 12, -}; - -/** - * These values are persisted to logs and should not be renumbered or re-used. - * See tools/metrics/histograms/enums.xml. - * @enum {number} - */ -export const AppManagementUserAction = { - ViewOpened: 0, - NativeSettingsOpened: 1, - UninstallDialogLaunched: 2, - PinToShelfTurnedOn: 3, - PinToShelfTurnedOff: 4, - NotificationsTurnedOn: 5, - NotificationsTurnedOff: 6, - LocationTurnedOn: 7, - LocationTurnedOff: 8, - CameraTurnedOn: 9, - CameraTurnedOff: 10, - MicrophoneTurnedOn: 11, - MicrophoneTurnedOff: 12, - ContactsTurnedOn: 13, - ContactsTurnedOff: 14, - StorageTurnedOn: 15, - StorageTurnedOff: 16, - PrintingTurnedOn: 17, - PrintingTurnedOff: 18, - ResizeLockTurnedOn: 19, - ResizeLockTurnedOff: 20, - PreferredAppTurnedOn: 21, - PreferredAppTurnedOff: 22, - SupportedLinksListShown: 23, - OverlappingAppsDialogShown: 24, -};
diff --git a/ui/webui/resources/cr_components/app_management/constants.ts b/ui/webui/resources/cr_components/app_management/constants.ts new file mode 100644 index 0000000..b0f4c63 --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/constants.ts
@@ -0,0 +1,73 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export {AppType, InstallReason, OptionalBool, WindowMode} from './types.mojom-webui.js'; + +/** + * The number of apps displayed in app list in the main view before expanding. + */ +export const NUMBER_OF_APPS_DISPLAYED_DEFAULT = 4; + +// Enumeration of the different subpage types within the app management page. +export enum PageType { + MAIN = 0, + DETAIL = 1, +} + +// This histogram is also declared and used at chrome/browser/ui/webui/settings/ +// chromeos/app_management/app_management_uma.h. +export const AppManagementEntryPointsHistogramName = + 'AppManagement.EntryPoints'; + +/** + * These values are persisted to logs and should not be renumbered or re-used. + * See tools/metrics/histograms/enums.xml. + */ +export enum AppManagementEntryPoint { + AppListContextMenuAppInfoArc = 0, + AppListContextMenuAppInfoChromeApp = 1, + AppListContextMenuAppInfoWebApp = 2, + ShelfContextMenuAppInfoArc = 3, + ShelfContextMenuAppInfoChromeApp = 4, + ShelfContextMenuAppInfoWebApp = 5, + MainViewArc = 6, + MainViewChromeApp = 7, + MainViewWebApp = 8, + OsSettingsMainPage = 9, + MainViewPluginVm = 10, + DBusServicePluginVm = 11, + MainViewBorealis = 12, +} + +/** + * These values are persisted to logs and should not be renumbered or re-used. + * See tools/metrics/histograms/enums.xml. + */ +export enum AppManagementUserAction { + ViewOpened = 0, + NativeSettingsOpened = 1, + UninstallDialogLaunched = 2, + PinToShelfTurnedOn = 3, + PinToShelfTurnedOff = 4, + NotificationsTurnedOn = 5, + NotificationsTurnedOff = 6, + LocationTurnedOn = 7, + LocationTurnedOff = 8, + CameraTurnedOn = 9, + CameraTurnedOff = 10, + MicrophoneTurnedOn = 11, + MicrophoneTurnedOff = 12, + ContactsTurnedOn = 13, + ContactsTurnedOff = 14, + StorageTurnedOn = 15, + StorageTurnedOff = 16, + PrintingTurnedOn = 17, + PrintingTurnedOff = 18, + ResizeLockTurnedOn = 19, + ResizeLockTurnedOff = 20, + PreferredAppTurnedOn = 21, + PreferredAppTurnedOff = 22, + SupportedLinksListShown = 23, + OverlappingAppsDialogShown = 24, +}
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/icons.html b/ui/webui/resources/cr_components/app_management/icons.html similarity index 97% rename from chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/icons.html rename to ui/webui/resources/cr_components/app_management/icons.html index d7b7a19..e20b975 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/icons.html +++ b/ui/webui/resources/cr_components/app_management/icons.html
@@ -3,7 +3,6 @@ <!-- These icons are custom and kept in sorted order. See http://goo.gl/Y1OdAq for instructions on adding additional icons. - TODO: move these icons to a generic file when other pages need to use them. --> <defs> <g id="camera" viewBox="0 0 20 20"><rect width="20px" height="20px" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"></rect><path d="M2,5.99539757 C2,5.44565467 2.44851311,5 3.00247329,5 L12.9975267,5 C13.5511774,5 14,5.44910619 14,5.99539757 L14,14.0046024 C14,14.5543453 13.5514869,15 12.9975267,15 L3.00247329,15 C2.44882258,15 2,14.5508938 2,14.0046024 L2,5.99539757 Z M14,8.5 L18,5.5 L18,14.5 L14,12 L14,8.5 Z M4,7 L4,13 L12,13 L12,7 L4,7 Z" id="Combined-Shape"></path></g>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/icons.js b/ui/webui/resources/cr_components/app_management/icons.ts similarity index 100% rename from chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/icons.js rename to ui/webui/resources/cr_components/app_management/icons.ts
diff --git a/ui/webui/resources/cr_components/app_management/permission_constants.js b/ui/webui/resources/cr_components/app_management/permission_constants.js deleted file mode 100644 index 26d8bd84..0000000 --- a/ui/webui/resources/cr_components/app_management/permission_constants.js +++ /dev/null
@@ -1,17 +0,0 @@ -// 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 './file_path.mojom-lite.js'; -import './image.mojom-lite.js'; -import './safe_base_name.mojom-lite.js'; -import './types.mojom-lite.js'; - - -export const TriState = apps.mojom.TriState; - -export const PermissionType = apps.mojom.PermissionType; - -export const PermissionValue = apps.mojom.PermissionValue;
diff --git a/ui/webui/resources/cr_components/app_management/permission_constants.ts b/ui/webui/resources/cr_components/app_management/permission_constants.ts new file mode 100644 index 0000000..65d47c8 --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/permission_constants.ts
@@ -0,0 +1,9 @@ +// 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 {PermissionType} from './types.mojom-webui.js'; + +export {PermissionType, PermissionValue, TriState} from './types.mojom-webui.js'; + +export type PermissionTypeIndex = keyof typeof PermissionType;
diff --git a/ui/webui/resources/cr_components/app_management/permission_item.js b/ui/webui/resources/cr_components/app_management/permission_item.ts similarity index 61% rename from ui/webui/resources/cr_components/app_management/permission_item.js rename to ui/webui/resources/cr_components/app_management/permission_item.ts index 4bfade1..33440fa 100644 --- a/ui/webui/resources/cr_components/app_management/permission_item.js +++ b/ui/webui/resources/cr_components/app_management/permission_item.ts
@@ -5,85 +5,83 @@ import './toggle_row.js'; import {assert, assertNotReached} from '//resources/js/assert.m.js'; -import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {App} from './app_management.mojom-webui.js'; import {BrowserProxy} from './browser_proxy.js'; import {AppManagementUserAction} from './constants.js'; -import {PermissionType, PermissionValue, TriState} from './permission_constants.js'; +import {PermissionType, PermissionTypeIndex, TriState} from './permission_constants.js'; import {createBoolPermission, createTriStatePermission, getBoolPermissionValue, getTriStatePermissionValue, isBoolValue, isTriStateValue} from './permission_util.js'; -import {getPermission, getPermissionValueBool, getSelectedApp, recordAppManagementUserAction} from './util.js'; +import {AppManagementToggleRowElement} from './toggle_row.js'; +import {Permission} from './types.mojom-webui.js'; +import {getPermission, getPermissionValueBool, recordAppManagementUserAction} from './util.js'; -Polymer({ - _template: html`{__html_template__}`, - is: 'app-management-permission-item', +export class AppManamentPermissionItemElement extends PolymerElement { + static get is() { + return 'app-management-permission-item'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** + * The name of the permission, to be displayed to the user. + */ + permissionLabel: String, + + /** + * A string version of the permission type. Must be a value of the + * permission type enum in apps.mojom.PermissionType. + */ + permissionType: String, + + icon: String, + + /** + * If set to true, toggling the permission item will not set the + * permission in the backend. Call `syncPermission()` to set the + * permission to reflect the current UI state. + */ + syncPermissionManually: Boolean, + + app_: Object, + + /** + * True if the permission type is available for the app. + */ + available_: { + type: Boolean, + computed: 'isAvailable_(app_, permissionType)', + reflectToAttribute: true, + }, + + disabled_: { + type: Boolean, + computed: 'isManaged_(app_, permissionType)', + reflectToAttribute: true, + }, + }; + } + + private permissionLabel: string; + private permissionType: PermissionTypeIndex; + private icon: string; + private syncPermissionManually: boolean; + private app_: App; + private available_: boolean; + private disabled_: boolean; - properties: { - /** - * The name of the permission, to be displayed to the user. - * @type {string} - */ - permissionLabel: String, + ready() { + super.ready(); + this.addEventListener('click', this.onClick_); + this.addEventListener('change', this.togglePermission_); + } - /** - * A string version of the permission type. Must be a value of the - * permission type enum in apps.mojom.PermissionType. - * @type {string} - */ - permissionType: String, - - /** - * @type {string} - */ - icon: String, - - /** - * If set to true, toggling the permission item will not set the permission - * in the backend. Call `syncPermission()` to set the permission to reflect - * the current UI state. - * - * @type {boolean} - */ - syncPermissionManually: Boolean, - - /** - * @type {App} - */ - app_: Object, - - /** - * True if the permission type is available for the app. - * @type {boolean} - * @private - */ - available_: { - type: Boolean, - computed: 'isAvailable_(app_, permissionType)', - reflectToAttribute: true, - }, - - /** - * @type {boolean} - * @private - */ - disabled_: { - type: Boolean, - computed: 'isManaged_(app_, permissionType)', - reflectToAttribute: true, - }, - }, - - - listeners: {click: 'onClick_', change: 'togglePermission_'}, - - /** - * Returns true if the permission type is available for the app. - * - * @param {App} app - * @param {string} permissionType - * @private - */ - isAvailable_(app, permissionType) { + private isAvailable_(app: App, permissionType: PermissionTypeIndex): boolean { if (app === undefined || permissionType === undefined) { return false; } @@ -91,14 +89,9 @@ assert(app); return getPermission(app, permissionType) !== undefined; - }, + } - /** - * @param {App} app - * @param {string} permissionType - * @return {boolean} - */ - isManaged_(app, permissionType) { + private isManaged_(app: App, permissionType: PermissionTypeIndex): boolean { if (app === undefined || permissionType === undefined || !this.isAvailable_(app, permissionType)) { return false; @@ -109,42 +102,34 @@ assert(permission); return permission.isManaged; - }, + } - /** - * @param {App} app - * @param {string} permissionType - * @return {boolean} - */ - getValue_(app, permissionType) { + private getValue_(app: App, permissionType: PermissionTypeIndex): boolean { if (app === undefined || permissionType === undefined) { return false; } assert(app); return getPermissionValueBool(app, permissionType); - }, + } resetToggle() { const currentValue = this.getValue_(this.app_, this.permissionType); - this.$$('#toggle-row').setToggle(currentValue); - }, + this.shadowRoot! + .querySelector<AppManagementToggleRowElement>('#toggle-row')!.setToggle( + currentValue); + } - /** - * @private - */ - onClick_() { - this.$$('#toggle-row').click(); - }, + private onClick_() { + this.shadowRoot! + .querySelector<AppManagementToggleRowElement>('#toggle-row')!.click(); + } - /** - * @private - */ - togglePermission_() { + private togglePermission_() { if (!this.syncPermissionManually) { this.syncPermission(); } - }, + } /** * Set the permission to match the current UI state. This only needs to be @@ -153,8 +138,7 @@ syncPermission() { assert(this.app_); - /** @type {!Permission} */ - let newPermission; + let newPermission: Permission|undefined = undefined; let newBoolState = false; // to keep the closure compiler happy. const permissionValue = getPermission(this.app_, this.permissionType).value; @@ -173,23 +157,19 @@ } BrowserProxy.getInstance().handler.setPermission( - this.app_.id, newPermission); + this.app_.id, newPermission!); recordAppManagementUserAction( this.app_.type, this.getUserMetricActionForPermission_( newBoolState, this.permissionType)); - }, + } /** * Gets the permission boolean based on the toggle's UI state. - * - * @param {App} app - * @param {string} permissionType - * @return {!Permission} - * @private */ - getUIPermissionBoolean_(app, permissionType) { + private getUIPermissionBoolean_( + app: App, permissionType: PermissionTypeIndex): Permission { const currentPermission = getPermission(app, permissionType); assert(isBoolValue(currentPermission.value)); @@ -199,17 +179,13 @@ return createBoolPermission( PermissionType[permissionType], newPermissionValue, currentPermission.isManaged); - }, + } /** * Gets the permission tristate based on the toggle's UI state. - * - * @param {App} app - * @param {string} permissionType - * @return {!Permission} - * @private */ - getUIPermissionTriState_(app, permissionType) { + private getUIPermissionTriState_( + app: App, permissionType: PermissionTypeIndex): Permission { let newPermissionValue; const currentPermission = getPermission(app, permissionType); @@ -231,21 +207,18 @@ break; default: assertNotReached(); + newPermissionValue = TriState.kBlock; } assert(newPermissionValue !== undefined); return createTriStatePermission( PermissionType[permissionType], newPermissionValue, currentPermission.isManaged); - }, + } - /** - * @param {boolean} permissionValue - * @param {string} permissionType - * @return {AppManagementUserAction} - * @private - */ - getUserMetricActionForPermission_(permissionValue, permissionType) { + private getUserMetricActionForPermission_( + permissionValue: boolean, + permissionType: PermissionTypeIndex): AppManagementUserAction { switch (permissionType) { case 'kNotifications': return permissionValue ? AppManagementUserAction.NotificationsTurnedOn : @@ -277,6 +250,10 @@ default: assertNotReached(); + return AppManagementUserAction.NotificationsTurnedOn; } - }, -}); + } +} + +customElements.define( + AppManamentPermissionItemElement.is, AppManamentPermissionItemElement);
diff --git a/ui/webui/resources/cr_components/app_management/permission_util.js b/ui/webui/resources/cr_components/app_management/permission_util.js deleted file mode 100644 index 962b0ad..0000000 --- a/ui/webui/resources/cr_components/app_management/permission_util.js +++ /dev/null
@@ -1,109 +0,0 @@ -// 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 {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; - -import {PermissionType, PermissionValue, TriState} from './permission_constants.js'; - -/** - * @param {PermissionType} permissionType - * @param {PermissionValue} value - * @param {boolean} isManaged - * @return {!apps.mojom.Permission} - */ -export function createPermission(permissionType, value, isManaged) { - return { - permissionType, - value, - isManaged, - }; -} - -/** - * @param {TriState} value - * @returns {PermissionValue} - */ -export function createTriStatePermissionValue(value) { - return {tristateValue: value}; -} - -/** - * @param {PermissionValue} permissionValue - * @returns {TriState} - */ -export function getTriStatePermissionValue(permissionValue) { - assert(isTriStateValue(permissionValue)); - return permissionValue['tristateValue']; -} - -/** - * @param {boolean} value - * @returns {PermissionValue} - */ -export function createBoolPermissionValue(value) { - return {boolValue: value}; -} - -/** - * @param {PermissionValue} permissionValue - * @returns {boolean} - */ -export function getBoolPermissionValue(permissionValue) { - assert(isBoolValue(permissionValue)); - return permissionValue['boolValue']; -} - -/** - * @param {PermissionValue} permissionValue - * @returns {boolean} - */ -export function isTriStateValue(permissionValue) { - return permissionValue['tristateValue'] !== undefined && - permissionValue['boolValue'] === undefined; -} - -/** - * @param {PermissionValue} permissionValue - * @returns {boolean} - */ -export function isBoolValue(permissionValue) { - return permissionValue['boolValue'] !== undefined && - permissionValue['tristateValue'] === undefined; -} - -/** - * @param {PermissionType} permissionType - * @param {boolean} value - * @param {boolean} isManaged - * @return {!apps.mojom.Permission} - */ -export function createBoolPermission(permissionType, value, isManaged) { - return createPermission( - permissionType, createBoolPermissionValue(value), isManaged); -} - -/** - * @param {PermissionType} permissionType - * @param {TriState} value - * @param {boolean} isManaged - * @return {!apps.mojom.Permission} - */ -export function createTriStatePermission(permissionType, value, isManaged) { - return createPermission( - permissionType, createTriStatePermissionValue(value), isManaged); -} - -/** - * @param {PermissionValue} permissionValue - * @returns {boolean} - */ -export function isPermissionEnabled(permissionValue) { - if (isBoolValue(permissionValue)) { - return getBoolPermissionValue(permissionValue); - } else if (isTriStateValue(permissionValue)) { - return getTriStatePermissionValue(permissionValue) === TriState.kAllow; - } else { - assertNotReached(); - } -}
diff --git a/ui/webui/resources/cr_components/app_management/permission_util.ts b/ui/webui/resources/cr_components/app_management/permission_util.ts new file mode 100644 index 0000000..38d6b6a --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/permission_util.ts
@@ -0,0 +1,74 @@ +// 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 {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; + +import {PermissionType, PermissionValue, TriState} from './permission_constants.js'; +import {Permission} from './types.mojom-webui.js'; + +export function createPermission( + permissionType: PermissionType, value: PermissionValue, + isManaged: boolean): Permission { + return { + permissionType, + value, + isManaged, + }; +} + +export function createTriStatePermissionValue(value: TriState): + PermissionValue { + return {tristateValue: value} as PermissionValue; +} + +export function getTriStatePermissionValue(permissionValue: PermissionValue): + TriState { + assert(isTriStateValue(permissionValue)); + return permissionValue.tristateValue!; +} + +export function createBoolPermissionValue(value: boolean): PermissionValue { + return {boolValue: value} as PermissionValue; +} + +export function getBoolPermissionValue(permissionValue: PermissionValue): + boolean { + assert(isBoolValue(permissionValue)); + return permissionValue.boolValue!; +} + +export function isTriStateValue(permissionValue: PermissionValue): boolean { + return permissionValue['tristateValue'] !== undefined && + permissionValue['boolValue'] === undefined; +} + +export function isBoolValue(permissionValue: PermissionValue): boolean { + return permissionValue['boolValue'] !== undefined && + permissionValue['tristateValue'] === undefined; +} + +export function createBoolPermission( + permissionType: PermissionType, value: boolean, + isManaged: boolean): Permission { + return createPermission( + permissionType, createBoolPermissionValue(value), isManaged); +} + +export function createTriStatePermission( + permissionType: PermissionType, value: TriState, + isManaged: boolean): Permission { + return createPermission( + permissionType, createTriStatePermissionValue(value), isManaged); +} + +export function isPermissionEnabled(permissionValue: PermissionValue): boolean { + if (isBoolValue(permissionValue)) { + return getBoolPermissionValue(permissionValue)!; + } else if (isTriStateValue(permissionValue)) { + return getTriStatePermissionValue(permissionValue) === TriState.kAllow; + } else { + assertNotReached(); + return false; + } +}
diff --git a/ui/webui/resources/cr_components/app_management/shared_style.js b/ui/webui/resources/cr_components/app_management/shared_style.ts similarity index 100% rename from ui/webui/resources/cr_components/app_management/shared_style.js rename to ui/webui/resources/cr_components/app_management/shared_style.ts
diff --git a/ui/webui/resources/cr_components/app_management/shared_vars.js b/ui/webui/resources/cr_components/app_management/shared_vars.ts similarity index 100% rename from ui/webui/resources/cr_components/app_management/shared_vars.js rename to ui/webui/resources/cr_components/app_management/shared_vars.ts
diff --git a/ui/webui/resources/cr_components/app_management/toggle_row.js b/ui/webui/resources/cr_components/app_management/toggle_row.js deleted file mode 100644 index 6bc6fd00..0000000 --- a/ui/webui/resources/cr_components/app_management/toggle_row.js +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -import './shared_style.js'; -import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; -import '//resources/cr_elements/policy/cr_policy_indicator.m.js'; - -import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -Polymer({ - _template: html`{__html_template__}`, - is: 'app-management-toggle-row', - - properties: { - /** - * @type {string} - */ - icon: String, - /** - * @type {string} - */ - label: String, - /** - * @type {boolean} - */ - managed: {type: Boolean, value: false, reflectToAttribute: true}, - /** - * @type {boolean} - */ - value: {type: Boolean, value: false, reflectToAttribute: true}, - /** - * @type {string} - */ - description: String, - }, - - listeners: { - click: 'onClick_', - }, - - /** - * @returns {boolean} true if the toggle is checked. - */ - isChecked() { - return this.$.toggle.checked; - }, - - /** - * @param {boolean} value What to set the toggle to. - */ - setToggle(value) { - this.$.toggle.checked = value; - }, - - /** - * @param {MouseEvent} event - * @private - */ - onClick_(event) { - event.stopPropagation(); - this.$['toggle'].click(); - }, -});
diff --git a/ui/webui/resources/cr_components/app_management/toggle_row.ts b/ui/webui/resources/cr_components/app_management/toggle_row.ts new file mode 100644 index 0000000..6dd03aa8 --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/toggle_row.ts
@@ -0,0 +1,55 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +import './shared_style.js'; +import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; +import '//resources/cr_elements/policy/cr_policy_indicator.m.js'; +import '//resources/cr_elements/icons.m.js'; + +import {CrToggleElement} from '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +export interface AppManagementToggleRowElement { + $: {toggle: CrToggleElement} +} + +export class AppManagementToggleRowElement extends PolymerElement { + static get is() { + return 'app-management-toggle-row'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + icon: String, + label: String, + managed: {type: Boolean, value: false, reflectToAttribute: true}, + value: {type: Boolean, value: false, reflectToAttribute: true}, + description: String, + }; + } + + ready() { + super.ready(); + this.addEventListener('click', this.onClick_); + } + + isChecked(): boolean { + return this.$.toggle.checked; + } + + setToggle(value: boolean) { + this.$.toggle.checked = value; + } + + private onClick_(event: Event) { + event.stopPropagation(); + this.$.toggle.click(); + } +} + +customElements.define( + AppManagementToggleRowElement.is, AppManagementToggleRowElement);
diff --git a/ui/webui/resources/cr_components/app_management/tsconfig_base.json b/ui/webui/resources/cr_components/app_management/tsconfig_base.json new file mode 100644 index 0000000..3f69ccee --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/tsconfig_base.json
@@ -0,0 +1,9 @@ +{ + "extends": "../../../../../tools/typescript/tsconfig_base.json", + "compilerOptions": { + "allowJs": true, + "noUncheckedIndexedAccess": false, + "noUnusedLocals": false, + "strictPropertyInitialization": false + } +}
diff --git a/ui/webui/resources/cr_components/app_management/types.js b/ui/webui/resources/cr_components/app_management/types.js deleted file mode 100644 index c8874115..0000000 --- a/ui/webui/resources/cr_components/app_management/types.js +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Closure typedefs for App Management. - */ - -/** - * @typedef {appManagement.mojom.App} - */ -let App; - -/** - * @typedef {appManagement.mojom.ExtensionAppPermissionMessage} - */ -let ExtensionAppPermissionMessage; - -/** - * @typedef {apps.mojom.Permission} - */ -let Permission; - -/** - * Maps app ids to Apps. - * @typedef {!Object<string, App>} - */ -let AppMap; - -/** - * @typedef {{ - * apps: !AppMap, - * selectedAppId: ?string, - * }} - */ -let AppManagementPageState; - -/** - * @typedef {apps.mojom.WindowMode} - */ -let WindowMode;
diff --git a/ui/webui/resources/cr_components/app_management/util.js b/ui/webui/resources/cr_components/app_management/util.js deleted file mode 100644 index 2f23b5f..0000000 --- a/ui/webui/resources/cr_components/app_management/util.js +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assert} from 'chrome://resources/js/assert.m.js'; -import {assertNotReached} from 'chrome://resources/js/assert.m.js'; - -import {AppManagementUserAction, AppType, OptionalBool} from './constants.js'; -import {PermissionType} from './permission_constants.js'; -import {isPermissionEnabled} from './permission_util.js'; - - -/** - * @fileoverview Utility functions for the App Management page. - */ - -/** - * @return {!AppManagementPageState} - */ -export function createEmptyState() { - return { - apps: {}, - selectedAppId: null, - }; -} - -/** - * @param {!Array<App>} apps - * @return {!AppManagementPageState} - */ -export function createInitialState(apps) { - const initialState = createEmptyState(); - - for (const app of apps) { - initialState.apps[app.id] = app; - } - - return initialState; -} - -/** - * @param {App} app - * @return {string} - */ -export function getAppIcon(app) { - return `chrome://app-icon/${app.id}/64`; -} - -/** - * If the given value is not in the set, returns a new set with the value - * added, otherwise returns the old set. - * @template T - * @param {!Set<T>} set - * @param {T} value - * @return {!Set<T>} - */ -export function addIfNeeded(set, value) { - if (!set.has(value)) { - set = new Set(set); - set.add(value); - } - return set; -} - -/** - * If the given value is in the set, returns a new set without the value, - * otherwise returns the old set. - * @template T - * @param {!Set<T>} set - * @param {T} value - * @return {!Set<T>} - */ -export function removeIfNeeded(set, value) { - if (set.has(value)) { - set = new Set(set); - set.delete(value); - } - return set; -} - -/** - * @param {App} app - * @param {string} permissionType - * @return {boolean} - */ -export function getPermissionValueBool(app, permissionType) { - const permission = getPermission(app, permissionType); - assert(permission); - - return isPermissionEnabled(permission.value); -} - -/** - * Undefined is returned when the app does not request a permission. - * - * @param {App} app - * @param {string} permissionType - * @return {Permission|undefined} - */ -export function getPermission(app, permissionType) { - return app.permissions[PermissionType[permissionType]]; -} - -/** - * @param {AppManagementPageState} state - * @return {?App} - */ -export function getSelectedApp(state) { - const selectedAppId = state.selectedAppId; - return selectedAppId ? state.apps[selectedAppId] : null; -} - -/** - * A comparator function to sort strings alphabetically. - * - * @param {string} a - * @param {string} b - */ -export function alphabeticalSort(a, b) { - return a.localeCompare(b); -} - -/** - * Toggles an OptionalBool - * - * @param {OptionalBool} bool - * @return {OptionalBool} - */ -export function toggleOptionalBool(bool) { - switch (bool) { - case OptionalBool.kFalse: - return OptionalBool.kTrue; - case OptionalBool.kTrue: - return OptionalBool.kFalse; - default: - assertNotReached(); - } -} - -/** - * @param {OptionalBool} optionalBool - * @returns {boolean} - */ -export function convertOptionalBoolToBool(optionalBool) { - switch (optionalBool) { - case OptionalBool.kTrue: - return true; - case OptionalBool.kFalse: - return false; - default: - assertNotReached(); - } -} - -/** - * @param {AppType} appType - * @return {string} - * @private - */ -export function getUserActionHistogramNameForAppType_(appType) { - switch (appType) { - case AppType.kArc: - return 'AppManagement.AppDetailViews.ArcApp'; - case AppType.kChromeApp: - case AppType.kStandaloneBrowser: - case AppType.kStandaloneBrowserChromeApp: - // TODO(https://crbug.com/1225848): Figure out appropriate behavior for - // Lacros-hosted chrome-apps. - return 'AppManagement.AppDetailViews.ChromeApp'; - case AppType.kWeb: - return 'AppManagement.AppDetailViews.WebApp'; - case AppType.kPluginVm: - return 'AppManagement.AppDetailViews.PluginVmApp'; - case AppType.kBorealis: - return 'AppManagement.AppDetailViews.BorealisApp'; - default: - assertNotReached(); - } -} - -/** - * @param {AppType} appType - * @param {AppManagementUserAction} userAction - */ -export function recordAppManagementUserAction(appType, userAction) { - const histogram = getUserActionHistogramNameForAppType_(appType); - const enumLength = Object.keys(AppManagementUserAction).length; - chrome.metricsPrivate.recordEnumerationValue( - histogram, userAction, enumLength); -}
diff --git a/ui/webui/resources/cr_components/app_management/util.ts b/ui/webui/resources/cr_components/app_management/util.ts new file mode 100644 index 0000000..4f572466 --- /dev/null +++ b/ui/webui/resources/cr_components/app_management/util.ts
@@ -0,0 +1,125 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; + +import {App} from './app_management.mojom-webui.js'; +import {AppManagementUserAction, AppType, OptionalBool} from './constants.js'; +import {PermissionType, PermissionTypeIndex} from './permission_constants.js'; +import {isPermissionEnabled} from './permission_util.js'; + +/** + * @fileoverview Utility functions for the App Management page. + */ + +type AppManagementPageState = { + apps: Record<string, App>, + selectedAppId: string|null, +}; + +export function createEmptyState(): AppManagementPageState { + return { + apps: {}, + selectedAppId: null, + }; +} + +export function createInitialState(apps: Array<App>): AppManagementPageState { + const initialState = createEmptyState(); + + for (const app of apps) { + initialState.apps[app.id] = app; + } + + return initialState; +} + +export function getAppIcon(app: App): string { + return `chrome://app-icon/${app.id}/64`; +} + +export function getPermissionValueBool( + app: App, permissionType: PermissionTypeIndex): boolean { + const permission = getPermission(app, permissionType); + assert(permission); + + return isPermissionEnabled(permission.value); +} + +/** + * Undefined is returned when the app does not request a permission. + */ +export function getPermission(app: App, permissionType: PermissionTypeIndex) { + return app.permissions[PermissionType[permissionType]]; +} + +export function getSelectedApp(state: AppManagementPageState): App|null { + const selectedAppId = state.selectedAppId; + return selectedAppId ? state.apps[selectedAppId] : null; +} + +/** + * A comparator function to sort strings alphabetically. + */ +export function alphabeticalSort(a: string, b: string) { + return a.localeCompare(b); +} + +/** + * Toggles an OptionalBool + */ +export function toggleOptionalBool(bool: OptionalBool): OptionalBool { + switch (bool) { + case OptionalBool.kFalse: + return OptionalBool.kTrue; + case OptionalBool.kTrue: + return OptionalBool.kFalse; + default: + assertNotReached(); + return OptionalBool.kFalse; + } +} + +export function convertOptionalBoolToBool(optionalBool: OptionalBool): boolean { + switch (optionalBool) { + case OptionalBool.kTrue: + return true; + case OptionalBool.kFalse: + return false; + default: + assertNotReached(); + return false; + } +} + +export function getUserActionHistogramNameForAppType_(appType: AppType): + string { + switch (appType) { + case AppType.kArc: + return 'AppManagement.AppDetailViews.ArcApp'; + case AppType.kChromeApp: + case AppType.kStandaloneBrowser: + case AppType.kStandaloneBrowserChromeApp: + // TODO(https://crbug.com/1225848): Figure out appropriate behavior for + // Lacros-hosted chrome-apps. + return 'AppManagement.AppDetailViews.ChromeApp'; + case AppType.kWeb: + return 'AppManagement.AppDetailViews.WebApp'; + case AppType.kPluginVm: + return 'AppManagement.AppDetailViews.PluginVmApp'; + case AppType.kBorealis: + return 'AppManagement.AppDetailViews.BorealisApp'; + default: + assertNotReached(); + return ''; + } +} + +export function recordAppManagementUserAction( + appType: AppType, userAction: AppManagementUserAction) { + const histogram = getUserActionHistogramNameForAppType_(appType); + const enumLength = Object.keys(AppManagementUserAction).length; + chrome.metricsPrivate.recordEnumerationValue( + histogram, userAction, enumLength); +}
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 47c0073..28ce9da 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
@@ -83,9 +83,7 @@ --disabled-border-color: var(--cros-button-stroke-color-secondary-disabled); --disabled-text-color: var(--cros-button-label-color-secondary-disabled); - /* TODO(crbug.com/1275388): use blend() instead */ - --hover-bg-action: linear-gradient(rgba(0 0 0 / 8%), rgba(0 0 0 / 8%)), - var(--cros-button-background-color-primary); + --hover-bg-action: var(--cros-button-background-color-primary-hover-preblended); --hover-bg-color: var(--cros-button-background-color-secondary-hover); --hover-border-color: var(--cros-button-stroke-color-secondary-hover); --ink-color: var(--cros-button-ripple-color-secondary);
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts index fbaef41..9b9775ba9 100644 --- a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts +++ b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts
@@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {IronDropdownElement} from 'chrome://resources/polymer/v3_0/iron-dropdown/iron-dropdown.js'; import {LegacyElementMixin} from 'chrome://resources/polymer/v3_0/polymer/lib/legacy/legacy-element-mixin.js'; +import {CrInputElement} from '../cr_input/cr_input.m.js'; + interface CrSearchableDropDownElement extends LegacyElementMixin, HTMLElement { autofocus: boolean; readonly: boolean; @@ -17,6 +20,11 @@ label: string; updateValueOnInput: boolean; showLoading: boolean; + + $: { + search: CrInputElement, + dropdown: IronDropdownElement, + }; } export {CrSearchableDropDownElement};
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 143fda0..b06a29c 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
@@ -139,9 +139,9 @@ <iron-icon id="dropdown-icon" icon="cr:arrow-drop-down"></iron-icon> </div> <div id="dropdown-box"> - <iron-dropdown horizontal-align="left" vertical-align="top" - vertical-offset="0" no-cancel-on-outside-click - no-cancel-on-esc-key> + <iron-dropdown id="dropdown" horizontal-align="left" + vertical-align="top" vertical-offset="0" + no-cancel-on-outside-click no-cancel-on-esc-key> <div slot="dropdown-content"> <div id="loading-box" hidden="[[!showLoading]]"> <paper-spinner-lite active></paper-spinner-lite>
diff --git a/ui/webui/resources/cr_elements/find_shortcut_behavior.d.ts b/ui/webui/resources/cr_elements/find_shortcut_behavior.d.ts index 7166266..87f54123 100644 --- a/ui/webui/resources/cr_elements/find_shortcut_behavior.d.ts +++ b/ui/webui/resources/cr_elements/find_shortcut_behavior.d.ts
@@ -11,3 +11,7 @@ } declare const FindShortcutBehavior: object; + +export const FindShortcutManager: { + listeners: Array<FindShortcutBehavior>, +};
diff --git a/ui/webui/resources/mojo/BUILD.gn b/ui/webui/resources/mojo/BUILD.gn index 99bd219..49a25df 100644 --- a/ui/webui/resources/mojo/BUILD.gn +++ b/ui/webui/resources/mojo/BUILD.gn
@@ -21,7 +21,10 @@ "mojo/public/mojom/base/time.mojom-webui.js", "mojo/public/mojom/base/token.mojom-webui.js", "skia/public/mojom/skcolor.mojom-webui.js", + "skia/public/mojom/bitmap.mojom-webui.js", + "skia/public/mojom/image_info.mojom-webui.js", "ui/base/mojom/window_open_disposition.mojom-webui.js", + "ui/gfx/image/mojom/image.mojom-webui.js", "url/mojom/url.mojom-webui.js", ] @@ -32,6 +35,7 @@ "//mojo/public/mojom/base:base_js__generator", "//skia/public/mojom:mojom_js__generator", "//ui/base/mojom:mojom_js__generator", + "//ui/gfx/image/mojom:mojom_js__generator", "//url/mojom:url_mojom_gurl_js__generator", ]
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index 31e9d1e6..bd6ddd8 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -604,6 +604,8 @@ "browser/browser_controls_navigation_state_handler_delegate.h", "browser/browser_list_proxy.cc", "browser/browser_list_proxy.h", + "browser/component_updater/client_side_phishing_component_loader_policy.cc", + "browser/component_updater/client_side_phishing_component_loader_policy.h", "browser/component_updater/registration.cc", "browser/component_updater/registration.h", "browser/content_view_render_view.cc", @@ -709,6 +711,7 @@ "//components/browser_ui/sms/android", "//components/cdm/browser", "//components/component_updater/android:embedded_component_loader", + "//components/component_updater/installer_policies", "//components/content_capture/android", "//components/content_settings/android", "//components/crash/android:crash_android",
diff --git a/weblayer/browser/component_updater/DEPS b/weblayer/browser/component_updater/DEPS new file mode 100644 index 0000000..6ce3145 --- /dev/null +++ b/weblayer/browser/component_updater/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/component_updater/installer_policies", +] \ No newline at end of file
diff --git a/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.cc b/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.cc new file mode 100644 index 0000000..37fea30e --- /dev/null +++ b/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.cc
@@ -0,0 +1,101 @@ +// 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 "weblayer/browser/component_updater/client_side_phishing_component_loader_policy.h" + +#include <stdint.h> + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/check.h" +#include "base/containers/flat_map.h" +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/files/scoped_file.h" +#include "base/location.h" +#include "base/task/post_task.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "base/values.h" +#include "base/version.h" +#include "components/component_updater/android/component_loader_policy.h" +#include "components/component_updater/installer_policies/client_side_phishing_component_installer_policy.h" +#include "components/safe_browsing/content/browser/client_side_phishing_model.h" +#include "weblayer/common/features.h" + +namespace weblayer { + +namespace { +// Persisted to logs, should never change. +constexpr char kClientSidePhishingComponentMetricsSuffix[] = + "ClientSidePhishing"; + +void LoadFromDisk(base::ScopedFD pb_fd, base::ScopedFD visual_tflite_model_fd) { + std::string binary_pb; + base::ScopedFILE pb_file_stream( + base::FileToFILE(base::File(std::move(pb_fd)), "r")); + if (!base::ReadStreamToString(pb_file_stream.get(), &binary_pb)) + binary_pb.clear(); + + base::File visual_tflite_model(std::move(visual_tflite_model_fd), + base::File::FLAG_OPEN | base::File::FLAG_READ); + + // The ClientSidePhishingModel singleton will react appropriately if the + // |binary_pb| is empty or |visual_tflite_model| is invalid. + safe_browsing::ClientSidePhishingModel::GetInstance() + ->PopulateFromDynamicUpdate(binary_pb, std::move(visual_tflite_model)); +} + +} // namespace + +void ClientSidePhishingComponentLoaderPolicy::ComponentLoaded( + const base::Version& version, + base::flat_map<std::string, base::ScopedFD>& fd_map, + std::unique_ptr<base::DictionaryValue> manifest) { + DCHECK(version.IsValid()); + + auto pb_iterator = + fd_map.find(component_updater::kClientModelBinaryPbFileName); + if (pb_iterator == fd_map.end()) + return; + + auto visual_tflite_model_iterator = + fd_map.find(component_updater::kVisualTfLiteModelFileName); + + base::ThreadPool::PostTask( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&LoadFromDisk, std::move(pb_iterator->second), + visual_tflite_model_iterator == fd_map.end() + ? base::ScopedFD() + : std::move(visual_tflite_model_iterator->second))); +} + +void ClientSidePhishingComponentLoaderPolicy::ComponentLoadFailed( + component_updater::ComponentLoadResult /*error*/) {} + +void ClientSidePhishingComponentLoaderPolicy::GetHash( + std::vector<uint8_t>* hash) const { + component_updater::ClientSidePhishingComponentInstallerPolicy::GetPublicHash( + hash); +} + +std::string ClientSidePhishingComponentLoaderPolicy::GetMetricsSuffix() const { + return kClientSidePhishingComponentMetricsSuffix; +} + +void LoadClientSidePhishingComponent( + component_updater::ComponentLoaderPolicyVector& policies) { + if (!base::FeatureList::IsEnabled( + weblayer::features::kWebLayerClientSidePhishingDetection)) { + return; + } + + policies.push_back( + std::make_unique<ClientSidePhishingComponentLoaderPolicy>()); +} + +} // namespace weblayer
diff --git a/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.h b/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.h new file mode 100644 index 0000000..fadf3915 --- /dev/null +++ b/weblayer/browser/component_updater/client_side_phishing_component_loader_policy.h
@@ -0,0 +1,53 @@ +// 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 WEBLAYER_BROWSER_COMPONENT_UPDATER_CLIENT_SIDE_PHISHING_COMPONENT_LOADER_POLICY_H_ +#define WEBLAYER_BROWSER_COMPONENT_UPDATER_CLIENT_SIDE_PHISHING_COMPONENT_LOADER_POLICY_H_ + +#include <stdint.h> + +#include <memory> +#include <string> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/files/scoped_file.h" +#include "components/component_updater/android/component_loader_policy.h" + +namespace base { +class DictionaryValue; +class Version; +} // namespace base + +namespace weblayer { + +class ClientSidePhishingComponentLoaderPolicy + : public component_updater::ComponentLoaderPolicy { + public: + ClientSidePhishingComponentLoaderPolicy() = default; + ~ClientSidePhishingComponentLoaderPolicy() override = default; + + ClientSidePhishingComponentLoaderPolicy( + const ClientSidePhishingComponentLoaderPolicy&) = delete; + ClientSidePhishingComponentLoaderPolicy& operator=( + const ClientSidePhishingComponentLoaderPolicy&) = delete; + + private: + // The following methods override ComponentLoaderPolicy. + void ComponentLoaded( + const base::Version& version, + base::flat_map<std::string, base::ScopedFD>& fd_map, + std::unique_ptr<base::DictionaryValue> manifest) override; + void ComponentLoadFailed( + component_updater::ComponentLoadResult error) override; + void GetHash(std::vector<uint8_t>* hash) const override; + std::string GetMetricsSuffix() const override; +}; + +void LoadClientSidePhishingComponent( + component_updater::ComponentLoaderPolicyVector& policies); + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_COMPONENT_UPDATER_CLIENT_SIDE_PHISHING_COMPONENT_LOADER_POLICY_H_
diff --git a/weblayer/browser/component_updater/registration.cc b/weblayer/browser/component_updater/registration.cc index 321e1905..33ac090 100644 --- a/weblayer/browser/component_updater/registration.cc +++ b/weblayer/browser/component_updater/registration.cc
@@ -4,11 +4,17 @@ #include "weblayer/browser/component_updater/registration.h" +#include "weblayer/browser/component_updater/client_side_phishing_component_loader_policy.h" + namespace weblayer { component_updater::ComponentLoaderPolicyVector GetComponentLoaderPolicies() { + component_updater::ComponentLoaderPolicyVector policies; + + LoadClientSidePhishingComponent(policies); // TODO(crbug.com/1233490) register AutoFillRegex component loader policy. - return component_updater::ComponentLoaderPolicyVector(); + + return policies; } } // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc b/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc index 694f4fc..1e898b2f 100644 --- a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc +++ b/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc
@@ -13,6 +13,7 @@ #include "weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "weblayer/browser/safe_browsing/safe_browsing_service.h" +#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" namespace weblayer { @@ -48,6 +49,7 @@ display_options, should_trigger_reporting, // WebLayer doesn't integrate //components/history. /*history_service=*/nullptr, + base::BindRepeating(&GetUserPopulationForBrowserContext, browser_context), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( browser_context), SafeBrowsingMetricsCollectorFactory::GetForBrowserContext(